Exemplo n.º 1
0
    def acquire_source(self, msg, connector_type, direction, push_hops=True):
        """Determine the `str(go_connector)` value that a msg came
        in on by looking at the connector_type and fetching the
        appropriate values from the `msg` helper_metadata.

        Raises `UnroutableMessageError` if the connector_type has a
        value not appropriate for the direction.

        Note: `str(go_connector)` is what is stored in Go routing tables.
        """
        msg_mdh = self.get_metadata_helper(msg)

        if direction == self.INBOUND:
            allowed_types = (self.TRANSPORT_TAG, self.ROUTER, self.BILLING)
        else:
            allowed_types = (self.CONVERSATION, self.ROUTER,
                             self.OPT_OUT, self.BILLING)

        if connector_type not in allowed_types:
            raise UnroutableMessageError(
                "Source connector of invalid type: %s" % connector_type, msg)

        if connector_type == self.CONVERSATION:
            conv_info = msg_mdh.get_conversation_info()
            src_conn = str(GoConnector.for_conversation(
                conv_info['conversation_type'], conv_info['conversation_key']))

        elif connector_type == self.ROUTER:
            router_info = msg_mdh.get_router_info()
            src_conn = str(GoConnector.for_router(
                router_info['router_type'], router_info['router_key'],
                self.router_direction(direction)))

        elif connector_type == self.TRANSPORT_TAG:
            src_conn = str(GoConnector.for_transport_tag(*msg_mdh.tag))

        elif connector_type == self.OPT_OUT:
            src_conn = str(GoConnector.for_opt_out())

        elif connector_type == self.BILLING:
            # when the source is a billing router, outbound messages
            # are always received from the inbound billing connector
            # and inbound messages are always received from the outbound
            # billing connector.
            src_conn = str(
                GoConnector.for_billing(self.router_direction(direction)))

        else:
            raise UnroutableMessageError(
                "Serious error. Reached apparently unreachable state"
                " in which source connector type is both valid"
                " but unknown. Bad connector type is: %s"
                % connector_type, msg)

        src_conn_str = str(src_conn)
        if push_hops:
            rmeta = RoutingMetadata(msg)
            rmeta.push_source(src_conn_str, msg.get_routing_endpoint())
        return src_conn_str
Exemplo n.º 2
0
 def test_remove_transport_tag(self):
     tag = ["pool1", "tag1"]
     rt = self.make_rt({})
     tag_conn = str(GoConnector.for_transport_tag(*tag))
     rt.add_entry(tag_conn, "default", self.CONV_1, "default")
     rt.add_entry(self.CONV_1, "default", tag_conn, "default")
     rt.remove_transport_tag(tag)
     self.assert_routing_entries(rt, [])
Exemplo n.º 3
0
 def test_remove_transport_tag(self):
     tag = ["pool1", "tag1"]
     rt = self.make_rt({})
     tag_conn = str(GoConnector.for_transport_tag(*tag))
     rt.add_entry(tag_conn, "default", self.CONV_1, "default")
     rt.add_entry(self.CONV_1, "default", tag_conn, "default")
     rt.remove_transport_tag(tag)
     self.assert_routing_entries(rt, [])
Exemplo n.º 4
0
    def publish_outbound_from_billing(self, config, msg):
        """Publish an outbound message to its intended destination
        after billing.
        """
        msg_mdh = self.get_metadata_helper(msg)
        dst_conn = GoConnector.for_transport_tag(*msg_mdh.tag)
        dst_connector_name, dst_endpoint = yield self.set_destination(
            msg, [str(dst_conn), 'default'], self.OUTBOUND)

        yield self.publish_outbound(msg, dst_connector_name, dst_endpoint)
Exemplo n.º 5
0
    def publish_outbound_from_billing(self, config, msg):
        """Publish an outbound message to its intended destination
        after billing.
        """
        msg_mdh = self.get_metadata_helper(msg)
        dst_conn = GoConnector.for_transport_tag(*msg_mdh.tag)
        dst_connector_name, dst_endpoint = yield self.set_destination(
            msg, [str(dst_conn), 'default'], self.OUTBOUND)

        yield self.publish_outbound(msg, dst_connector_name, dst_endpoint)
Exemplo n.º 6
0
    def publish_outbound_optout(self, config, msg):
        """Publish a reply from the opt-out worker.

        It does this by looking up the original message and
        sending the reply out via the same tag the original
        message came in on.
        """
        tag = yield self.tag_for_reply(msg)
        dst_conn = GoConnector.for_transport_tag(*tag)
        dst_connector_name, dst_endpoint = yield self.set_destination(
            msg, [str(dst_conn), 'default'], self.OUTBOUND)
        yield self.publish_outbound(msg, dst_connector_name, dst_endpoint)
Exemplo n.º 7
0
    def publish_outbound_optout(self, config, msg):
        """Publish a reply from the opt-out worker.

        It does this by looking up the original message and
        sending the reply out via the same tag the original
        message came in on.
        """
        tag = yield self.tag_for_reply(msg)
        dst_conn = GoConnector.for_transport_tag(*tag)
        dst_connector_name, dst_endpoint = yield self.set_destination(
            msg, [str(dst_conn), 'default'], self.OUTBOUND)
        yield self.publish_outbound(msg, dst_connector_name, dst_endpoint)
Exemplo n.º 8
0
    def test_connector_direction(self):
        def assert_inbound(conn):
            self.assertEqual(GoConnector.INBOUND, conn.direction)

        def assert_outbound(conn):
            self.assertEqual(GoConnector.OUTBOUND, conn.direction)

        assert_inbound(GoConnector.for_opt_out())
        assert_inbound(GoConnector.for_conversation("conv_type_1", "12345"))
        assert_outbound(GoConnector.for_transport_tag("tagpool_1", "tag_1"))
        assert_inbound(
            GoConnector.for_router("rb_type_1", "12345", GoConnector.INBOUND))
        assert_outbound(
            GoConnector.for_router("rb_type_1", "12345", GoConnector.OUTBOUND))
Exemplo n.º 9
0
    def test_connector_direction(self):
        def assert_inbound(conn):
            self.assertEqual(GoConnector.INBOUND, conn.direction)

        def assert_outbound(conn):
            self.assertEqual(GoConnector.OUTBOUND, conn.direction)

        assert_inbound(GoConnector.for_opt_out())
        assert_inbound(GoConnector.for_conversation("conv_type_1", "12345"))
        assert_outbound(GoConnector.for_transport_tag("tagpool_1", "tag_1"))
        assert_inbound(
            GoConnector.for_router("rb_type_1", "12345", GoConnector.INBOUND))
        assert_outbound(
            GoConnector.for_router("rb_type_1", "12345", GoConnector.OUTBOUND))
Exemplo n.º 10
0
    def process_inbound(self, config, msg, connector_name):
        """Process an inbound message.

        Inbound messages can be from:

        * transports (these might be opt-out messages)
        * routers
        * the billing worker

        And may go to:

        * routers
        * conversations
        * the opt-out worker
        * the billing worker
        """
        log.debug("Processing inbound: %r" % (msg,))
        msg_mdh = self.get_metadata_helper(msg)
        msg_mdh.set_user_account(config.user_account_key)

        connector_type = self.connector_type(connector_name)
        src_conn = self.acquire_source(msg, connector_type, self.INBOUND)

        if self.billing_inbound_connector:
            if connector_type == self.TRANSPORT_TAG:
                yield self.publish_inbound_to_billing(config, msg)
                return
            if connector_type == self.BILLING:
                # set the src_conn to the transport and keep routing
                src_conn = str(GoConnector.for_transport_tag(*msg_mdh.tag))

        if msg_mdh.is_optout_message():
            yield self.publish_inbound_optout(config, msg)
            return

        target = self.find_target(config, msg, src_conn)
        if target is None:
            raise NoTargetError(
                "No target found for inbound message from %r"
                % (connector_name,), msg)

        dst_connector_name, dst_endpoint = yield self.set_destination(
            msg, target, self.INBOUND)

        yield self.publish_inbound(msg, dst_connector_name, dst_endpoint)
Exemplo n.º 11
0
    def process_inbound(self, config, msg, connector_name):
        """Process an inbound message.

        Inbound messages can be from:

        * transports (these might be opt-out messages)
        * routers
        * the billing worker

        And may go to:

        * routers
        * conversations
        * the opt-out worker
        * the billing worker
        """
        log.debug("Processing inbound: %r" % (msg, ))
        msg_mdh = self.get_metadata_helper(msg)
        msg_mdh.set_user_account(config.user_account_key)

        connector_type = self.connector_type(connector_name)
        src_conn = self.acquire_source(msg, connector_type, self.INBOUND)

        if self.billing_inbound_connector:
            if connector_type == self.TRANSPORT_TAG:
                yield self.publish_inbound_to_billing(config, msg)
                return
            if connector_type == self.BILLING:
                # set the src_conn to the transport and keep routing
                src_conn = str(GoConnector.for_transport_tag(*msg_mdh.tag))

        if msg_mdh.is_optout_message():
            yield self.publish_inbound_optout(config, msg)
            return

        target = self.find_target(config, msg, src_conn)
        if target is None:
            raise NoTargetError(
                "No target found for inbound message from %r" %
                (connector_name, ), msg)

        dst_connector_name, dst_endpoint = yield self.set_destination(
            msg, target, self.INBOUND)

        yield self.publish_inbound(msg, dst_connector_name, dst_endpoint)
Exemplo n.º 12
0
    def setup_routing(self, user, account_objects):
        connectors = {}
        for conv in account_objects['conversations']:
            connectors[conv['key']] = GoConnector.for_conversation(
                conv['conversation_type'], conv['key'])
        for tag in account_objects['channels']:
            connectors[tag] = GoConnector.for_transport_tag(*(tag.split(':')))
        for router in account_objects['routers']:
            connectors[router['key'] + ':INBOUND'] = GoConnector.for_router(
                router['router_type'], router['key'], GoConnector.INBOUND)
            connectors[router['key'] + ':OUTBOUND'] = GoConnector.for_router(
                router['router_type'], router['key'], GoConnector.OUTBOUND)

        rt = RoutingTable()
        for src, src_ep, dst, dst_ep in account_objects['routing_entries']:
            rt.add_entry(
                str(connectors[src]), src_ep, str(connectors[dst]), dst_ep)

        user_account = vumi_api_for_user(user).get_user_account()
        user_account.routing_table = rt
        user_account.save()

        self.stdout.write('Routing table for %s built\n' % (user.email,))
Exemplo n.º 13
0
 def test_create_transport_tag_connector(self):
     c = GoConnector.for_transport_tag("tagpool_1", "tag_1")
     self.assertEqual(c.ctype, GoConnector.TRANSPORT_TAG)
     self.assertEqual(c.tagpool, "tagpool_1")
     self.assertEqual(c.tagname, "tag_1")
     self.assertEqual(str(c), "TRANSPORT_TAG:tagpool_1:tag_1")
Exemplo n.º 14
0
 def get_connector(self):
     return GoConnector.for_transport_tag(self.tagpool, self.tag)
Exemplo n.º 15
0
 def test_create_transport_tag_connector(self):
     c = GoConnector.for_transport_tag("tagpool_1", "tag_1")
     self.assertEqual(c.ctype, GoConnector.TRANSPORT_TAG)
     self.assertEqual(c.tagpool, "tagpool_1")
     self.assertEqual(c.tagname, "tag_1")
     self.assertEqual(str(c), "TRANSPORT_TAG:tagpool_1:tag_1")
Exemplo n.º 16
0
    def acquire_source(self, msg, connector_type, direction, push_hops=True):
        """Determine the `str(go_connector)` value that a msg came
        in on by looking at the connector_type and fetching the
        appropriate values from the `msg` helper_metadata.

        Raises `UnroutableMessageError` if the connector_type has a
        value not appropriate for the direction.

        Note: `str(go_connector)` is what is stored in Go routing tables.
        """
        msg_mdh = self.get_metadata_helper(msg)

        if direction == self.INBOUND:
            allowed_types = (self.TRANSPORT_TAG, self.ROUTER, self.BILLING)
        else:
            allowed_types = (self.CONVERSATION, self.ROUTER, self.OPT_OUT,
                             self.BILLING)

        if connector_type not in allowed_types:
            raise UnroutableMessageError(
                "Source connector of invalid type: %s" % connector_type, msg)

        if connector_type == self.CONVERSATION:
            conv_info = msg_mdh.get_conversation_info()
            src_conn = str(
                GoConnector.for_conversation(conv_info['conversation_type'],
                                             conv_info['conversation_key']))

        elif connector_type == self.ROUTER:
            router_info = msg_mdh.get_router_info()
            src_conn = str(
                GoConnector.for_router(router_info['router_type'],
                                       router_info['router_key'],
                                       self.router_direction(direction)))

        elif connector_type == self.TRANSPORT_TAG:
            src_conn = str(GoConnector.for_transport_tag(*msg_mdh.tag))

        elif connector_type == self.OPT_OUT:
            src_conn = str(GoConnector.for_opt_out())

        elif connector_type == self.BILLING:
            # when the source is a billing router, outbound messages
            # are always received from the inbound billing connector
            # and inbound messages are always received from the outbound
            # billing connector.
            src_conn = str(
                GoConnector.for_billing(self.router_direction(direction)))

        else:
            raise UnroutableMessageError(
                "Serious error. Reached apparently unreachable state"
                " in which source connector type is both valid"
                " but unknown. Bad connector type is: %s" % connector_type,
                msg)

        src_conn_str = str(src_conn)
        if push_hops:
            rmeta = RoutingMetadata(msg)
            rmeta.push_source(src_conn_str, msg.get_routing_endpoint())
        return src_conn_str