def make_routing_table(self, channels=(), conversations=(), routing=()): routing_table = { u'campaign_id': self.user_helper.account_key, u'channels': [], u'conversations': [], u'routers': [], u'routing_entries': [], } for channel in channels: routing_table[u'channels'].append( ChannelType.format_channel(channel)) for conv in conversations: routing_table[u'conversations'].append( ConversationType.format_conversation(conv)) # TODO: routers def mkconn(thing): if isinstance(thing, tuple): # It's a tuple, so assume it's a tag. return u'TRANSPORT_TAG:%s:%s' % thing else: # Assume it's a conversation. return u'CONVERSATION:%s:%s' % ( thing.conversation_type, thing.key) for src, dst in routing: routing_table[u'routing_entries'].append( RoutingEntryType.format_entry( (mkconn(src), 'default'), (mkconn(dst), 'default'))) return routing_table
def make_routing_table(self, channels=(), conversations=(), routing=()): routing_table = { u'campaign_id': self.user_helper.account_key, u'channels': [], u'conversations': [], u'routers': [], u'routing_entries': [], } for channel in channels: routing_table[u'channels'].append( ChannelType.format_channel(channel)) for conv in conversations: routing_table[u'conversations'].append( ConversationType.format_conversation(conv)) # TODO: routers def mkconn(thing): if isinstance(thing, tuple): # It's a tuple, so assume it's a tag. return u'TRANSPORT_TAG:%s:%s' % thing else: # Assume it's a conversation. return u'CONVERSATION:%s:%s' % (thing.conversation_type, thing.key) for src, dst in routing: routing_table[u'routing_entries'].append( RoutingEntryType.format_entry((mkconn(src), 'default'), (mkconn(dst), 'default'))) return routing_table
def format_channels(channels): return [ChannelType.format_channel(ch) for ch in channels]
def test_basic_checks(self): self.basic_checks(ChannelType())
class GoApiServer(JSONRPC, GoApiSubHandler): def __init__(self, user_account_key, vumi_api): JSONRPC.__init__(self) GoApiSubHandler.__init__(self, user_account_key, vumi_api) self.putSubHandler('conversation', ConversationSubhandler(user_account_key, vumi_api)) self.putSubHandler('router', RouterSubhandler(user_account_key, vumi_api)) def _conversations(self, user_api): def format_conversations(convs): return [ConversationType.format_conversation(c) for c in convs] d = user_api.active_conversations() d.addCallback(format_conversations) return d def _channels(self, user_api): def format_channels(channels): return [ChannelType.format_channel(ch) for ch in channels] d = user_api.active_channels() d.addCallback(format_channels) return d def _routers(self, user_api): def format_routers(routers): return [RouterType.format_router(rb) for rb in routers] d = user_api.active_routers() d.addCallback(format_routers) return d def _routing_entries(self, user_api): def format_routing_entries(routing_table): return [ RoutingEntryType.format_entry((src_conn, src_endp), (dst_conn, dst_endp)) for src_conn, src_endp, dst_conn, dst_endp in routing_table.entries() ] d = user_api.get_routing_table() d.addCallback(format_routing_entries) return d @signature(returns=List("List of campaigns.", item_type=CampaignType())) def jsonrpc_campaigns(self): """List the campaigns a user has access to.""" return [CampaignType.format_campaign({ 'key': self.user_account_key, 'name': u"Your Campaign", })] @signature(campaign_key=Unicode("Campaign key."), returns=List("List of conversations.", item_type=ConversationType())) def jsonrpc_conversations(self, campaign_key): """List the active conversations under a particular campaign. """ user_api = self.get_user_api(campaign_key) return self._conversations(user_api) @signature(campaign_key=Unicode("Campaign key."), returns=List("List of channels.", item_type=ChannelType())) def jsonrpc_channels(self, campaign_key): """List the active channels under a particular campaign. """ user_api = self.get_user_api(campaign_key) return self._channels(user_api) @signature(campaign_key=Unicode("Campaign key."), returns=List("List of routers.", item_type=RouterType())) def jsonrpc_routers(self, campaign_key): """List the active routers under a particular campaign. """ user_api = self.get_user_api(campaign_key) return self._routers(user_api) @signature(campaign_key=Unicode("Campaign key."), returns=List("List of routing table entries.", item_type=RoutingEntryType())) def jsonrpc_routing_entries(self, campaign_key): """List the routing entries from a particular campaign's routing table. """ user_api = self.get_user_api(campaign_key) return self._routing_entries(user_api) @signature(campaign_key=Unicode("Campaign key."), returns=RoutingType( "Complete description of the routing table.")) def jsonrpc_routing_table(self, campaign_key): """List the channels, conversations, routers and routing table entries that make up a campaign's routing. """ user_api = self.get_user_api(campaign_key) deferreds = [] deferreds.append(self._channels(user_api)) deferreds.append(self._routers(user_api)) deferreds.append(self._conversations(user_api)) deferreds.append(self._routing_entries(user_api)) def construct_json(results): for success, result in results: if not success: result.raiseException() results = [r[1] for r in results] channels, routers, conversations, routing_entries = results return RoutingType.format_routing( channels, routers, conversations, routing_entries) d = DeferredList(deferreds, consumeErrors=True) d.addCallback(construct_json) return d @signature(campaign_key=Unicode("Campaign key."), routing=RoutingType("Description of the new routing table.")) def jsonrpc_update_routing_table(self, campaign_key, routing): user_api = self.get_user_api(campaign_key) deferreds = [] deferreds.append(self._channels(user_api)) deferreds.append(self._routers(user_api)) deferreds.append(self._conversations(user_api)) def gather_endpoints(results): for success, result in results: if not success: result.raiseException() results = [r[1] for r in results] channels, routers, conversations = results recv_outbound_endpoints = set( endpoint['uuid'] for endpoint in itertools.chain( (e for c in channels for e in c['endpoints']), (e for r in routers for e in r['conversation_endpoints']), ) ) recv_inbound_endpoints = set( endpoint['uuid'] for endpoint in itertools.chain( (e for c in conversations for e in c['endpoints']), (e for r in routers for e in r['channel_endpoints']) ) ) return recv_outbound_endpoints, recv_inbound_endpoints def check_routing_table(endpoint_sets): """Check that endpoints link from known receives-outbound (right) endpoints to known receives-inbound (left) endpoints or vice versa. """ recv_outbound_endpoints, recv_inbound_endpoints = endpoint_sets routing_entries = routing['routing_entries'] for entry in routing_entries: source, target = entry['source'], entry['target'] src_uuid, dst_uuid = source['uuid'], target['uuid'] if src_uuid in recv_outbound_endpoints: if dst_uuid not in recv_inbound_endpoints: raise InvalidRoutingTable( "Source outbound-receiving endpoint %r should" " link to an inbound-receiving endpoint but links" " to %r" % (source, target)) elif src_uuid in recv_inbound_endpoints: if dst_uuid not in recv_outbound_endpoints: raise InvalidRoutingTable( "Source inbound-receiving endpoint %r should" " link to an outbound-receiving endpoint but links" " to %r" % (source, target)) else: raise InvalidRoutingTable("Unknown source endpoint %r" % (source,)) return routing_entries def populate_routing_table(routing_entries): routing_table = RoutingTable() for entry in routing_entries: source, target = entry['source'], entry['target'] src_conn, src_endp = EndpointType.parse_uuid( source['uuid']) dst_conn, dst_endp = EndpointType.parse_uuid( target['uuid']) routing_table.add_entry(src_conn, src_endp, dst_conn, dst_endp) d = user_api.get_user_account() d.addCallback(save_routing_table, routing_table) return d def save_routing_table(user_account, routing_table): user_account.routing_table = routing_table return user_account.save() def swallow_result(result): return None d = DeferredList(deferreds, consumeErrors=True) d.addCallback(gather_endpoints) d.addCallback(check_routing_table) d.addCallback(populate_routing_table) d.addCallback(swallow_result) return d