Example #1
0
 def __init__(self, *args, **kw):
     kw['required_fields'] = {
         'uuid': Unicode(),
         'tag': Tag(),
         'name': Unicode(),
         'description': Unicode(),
         'endpoints': List(item_type=EndpointType()),
     }
     super(ChannelType, self).__init__(*args, **kw)
Example #2
0
 def __init__(self, *args, **kw):
     kw['required_fields'] = {
         'uuid': Unicode(),
         'type': Unicode(),
         'name': Unicode(),
         'description': Unicode(),
         'channel_endpoints': List(item_type=EndpointType()),
         'conversation_endpoints': List(item_type=EndpointType()),
     }
     super(RouterType, self).__init__(*args, **kw)
Example #3
0
 def __init__(self, *args, **kw):
     uuid_dict = Dict(required_fields={'uuid': Unicode()})
     kw['required_fields'] = {
         'source': uuid_dict,
         'target': uuid_dict,
     }
     super(RoutingEntryType, self).__init__(*args, **kw)
Example #4
0
 def test_check_params(self):
     s = Signature(lambda slf, x, y: x, x=Int(), y=Unicode())
     s.check_params([None, 1, u"a"], {})
     self.assertRaises(RpcCheckError, s.check_params, [None, u"a", u"a"],
                       {})
     self.assertRaises(RpcCheckError, s.check_params, [None, 1, 2], {})
     self.assertRaises(RpcCheckError, s.check_params, [None, 1, u"a", 3],
                       {})
Example #5
0
class DummyApi(object):
    def __init__(self, result=None):
        self.result = result

    @signature(a=Unicode(), b=Int())
    def test(self, a, b):
        """Basic doc."""
        return self.result
Example #6
0
 def test_optional_fields(self):
     d = Dict(optional_fields={'foo': Int(null=True), 'bar': Unicode()})
     d.check("name", {'foo': None, 'bar': u'b'})
     d.check("name", {'foo': 1, 'bar': u'b'})
     d.check("name", {'foo': 1, 'bar': u'b', 'extra': 2})
     d.check("name", {"foo": 1})
     d.check("name", {"bar": u"b"})
     self.assertRaises(RpcCheckError, d.check, "name", {"foo": u'b'})
Example #7
0
 def test_fallback_to_item_type(self):
     d = Dict(required_fields={'foo': Int()},
              optional_fields={'bar': Int()},
              item_type=Unicode())
     d.check("name", {'foo': 1})
     d.check("name", {'foo': 1, 'bar': 2})
     d.check("name", {'foo': 1, 'bar': 2, 'extra': u'foo'})
     self.assertRaises(RpcCheckError, d.check, "name", {
         'foo': 1,
         'bar': 2,
         'extra': 3
     })
Example #8
0
    def __init__(self, *args, **kw):
        """Description of a conversation.

        The following fields are required:

        * uuid: The conversation key.
        * type: The conversation type, e.g. 'bulk-message'.
        * name: The conversation name, e.g. 'My Bulk Sender'.
        * description: The conversation description, e.g.
                       'Some Bulk Message App'.
        * endpoints: A list of `EndpointType` dictionaries, e.g.
                     `[{uuid: 'endpoint-uuid-4', name: 'default'}]`.
        """
        kw['required_fields'] = {
            'uuid': Unicode(),
            'type': Unicode(),
            'name': Unicode(),
            'description': Unicode(),
            'endpoints': List(item_type=EndpointType()),
        }
        super(ConversationType, self).__init__(*args, **kw)
Example #9
0
    def mk_jsonrpc_handler(name, handler, type_name):
        sig = signature(
            **{
                "campaign_key": Unicode("Campaign key."),
                ("%s_key" % type_name): Unicode("%s key." % type_name.title()),
                "params": Dict("Additional action paramaters.", null=True),
                "returns": Dict("Result of the action.", null=True),
            })

        jsonrpc_name = "jsonrpc_%s" % (name, )

        # we use compile and exec to get exactly the signature we need
        code = compile(("def %s(self, campaign_key, %s_key, params=None):"
                        "    return self.dispatch_action("
                        "        handler, campaign_key, %s_key, params)") %
                       (jsonrpc_name, type_name, type_name),
                       "<mk_jsonrpc_handler>", "exec")

        locs = {"handler": handler}
        exec(code, locs)
        jsonrpc_handler = sig(locs[jsonrpc_name])
        return jsonrpc_handler
Example #10
0
 def test_jsonrpc_signature(self):
     s = Signature(lambda slf, x: unicode(x),
                   x=Int("foo"),
                   returns=Unicode("bar"))
     self.assertEqual(s.jsonrpc_signature(), [['string', 'int']])
Example #11
0
 def test_check_params_with_defaults(self):
     s = Signature(lambda slf, x, y=u"default": x, x=Int(), y=Unicode())
     s.check_params([None, 1, u"a"], {})
     s.check_params([None, 1], {})
Example #12
0
                      x=Int("foo"),
                      returns=Unicode("bar"))
        self.assertEqual(s.jsonrpc_signature(), [['string', 'int']])


class DummyApi(object):
    def __init__(self, result=None):
        self.result = result

    @signature(a=Unicode(), b=Int())
    def test(self, a, b):
        """Basic doc."""
        return self.result


@signature(a=Unicode(), b=Int(), returns=Unicode(), requires_self=False)
def dummy_function(a, b):
    return unicode(a * b)


class TestSignatureDecorate(VumiTestCase):
    def test_decorate_unbound_method(self):
        api = DummyApi()
        self.assertEqual(api.test.signature, [['null', 'string', 'int']])
        self.assertTrue(isinstance(api.test.signature_object, Signature))
        self.assertEqual(api.test.__name__, 'test')
        self.assertEqual(api.test.__module__, 'vumi.tests.test_rpc')
        self.assertEqual(
            api.test.__doc__,
            'Basic doc.\n\n:param Unicode a:\n:param Int b:\n:rtype Null:')
Example #13
0
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
Example #14
0
 def __init__(self, *args, **kw):
     kw['required_fields'] = {
         'key': Unicode(),
         'name': Unicode(),
     }
     super(CampaignType, self).__init__(*args, **kw)
Example #15
0
 def __init__(self, *args, **kw):
     kw['required_fields'] = {
         'uuid': Unicode(),
         'name': Unicode(),
     }
     super(EndpointType, self).__init__(*args, **kw)
Example #16
0
 def test_check(self):
     u = Unicode()
     u.check("name", u"foo")
     self.assertRaises(RpcCheckError, u.check, "name", "foo")
     self.assertRaises(RpcCheckError, u.check, "name", 1)
Example #17
0
 def test_check(self):
     u = Unicode()
     u.check("name", u"foo")
     self.assertRaises(RpcCheckError, u.check, "name", "foo")
     self.assertRaises(RpcCheckError, u.check, "name", 1)
Example #18
0
class TagpoolApiServer(JSONRPC):
    def __init__(self, tagpool):
        JSONRPC.__init__(self)
        self.tagpool = tagpool

    @signature(pool=Unicode("Name of pool to acquire tag from."),
               owner=Unicode("Owner acquiring tag (or None).", null=True),
               reason=Dict("Metadata on why tag is being acquired (or None).",
                           null=True),
               returns=Tag("Tag acquired (or None).", null=True))
    def jsonrpc_acquire_tag(self, pool, owner=None, reason=None):
        """Acquire a tag from the pool (returns None if no tags are avaliable).
           """
        d = self.tagpool.acquire_tag(pool, owner, reason)
        return d

    @signature(tag=Tag("Tag to acquire as [pool, tagname] pair."),
               owner=Unicode("Owner acquiring tag (or None).", null=True),
               reason=Dict("Metadata on why tag is being acquired (or None).",
                           null=True),
               returns=Tag("Tag acquired (or None).", null=True))
    def jsonrpc_acquire_specific_tag(self, tag, owner=None, reason=None):
        """Acquire the specific tag (returns None if the tag is unavailable).
           """
        d = self.tagpool.acquire_specific_tag(tag, owner, reason)
        return d

    @signature(tag=Tag("Tag to release."))
    def jsonrpc_release_tag(self, tag):
        """Release the specified tag if it exists and is inuse."""
        return self.tagpool.release_tag(tag)

    @signature(tags=List("List of tags to declare.", item_type=Tag()))
    def jsonrpc_declare_tags(self, tags):
        """Declare all of the listed tags."""
        return self.tagpool.declare_tags(tags)

    @signature(pool=Unicode("Name of pool to retreive metadata for."),
               returns=Dict("Retrieved metadata."))
    def jsonrpc_get_metadata(self, pool):
        """Retrieve the metadata for the given pool."""
        return self.tagpool.get_metadata(pool)

    @signature(pool=Unicode("Name of pool to update metadata for."),
               metadata=Dict("New value of metadata."))
    def jsonrpc_set_metadata(self, pool, metadata):
        """Set the metadata for the given pool."""
        return self.tagpool.set_metadata(pool, metadata)

    @signature(pool=Unicode("Name of the pool to purge."))
    def jsonrpc_purge_pool(self, pool):
        """Delete the given pool and all associated metadata and tags.

           No tags from the pool may be inuse.
           """
        return self.tagpool.purge_pool(pool)

    @signature(returns=List("List of pool names.", item_type=Unicode()))
    def jsonrpc_list_pools(self):
        """Return a list of all available pools."""
        d = self.tagpool.list_pools()
        d.addCallback(list)
        return d

    @signature(pool=Unicode("Name of pool."),
               returns=List("List of free tags.", item_type=Tag()))
    def jsonrpc_free_tags(self, pool):
        """Return a list of free tags in the given pool."""
        d = self.tagpool.free_tags(pool)
        return d

    @signature(pool=Unicode("Name of pool."),
               returns=List("List of tags inuse.", item_type=Tag()))
    def jsonrpc_inuse_tags(self, pool):
        """Return a list of tags currently in use within the given pool."""
        d = self.tagpool.inuse_tags(pool)
        return d

    @signature(tag=Tag("Tag to return ownership information on."),
               returns=List("List of owner and reason.", length=2, null=True))
    def jsonrpc_acquired_by(self, tag):
        """Returns the owner of an acquired tag and why is was acquired."""
        d = self.tagpool.acquired_by(tag)
        d.addCallback(list)
        return d

    @signature(owner=Unicode("Owner of tags (or None for unowned tags).",
                             null=True),
               returns=List("List of tags owned.", item_type=Tag()))
    def jsonrpc_owned_tags(self, owner):
        """Return a list of tags currently owned by an owner."""
        return self.tagpool.owned_tags(owner)