예제 #1
0
def event_dispatcher(nameko_config, **kwargs):
    """ Return a function that dispatches nameko events.
    """
    amqp_uri = nameko_config[AMQP_URI_CONFIG_KEY]

    serializer, _ = serialization.setup(nameko_config)
    serializer = kwargs.pop('serializer', serializer)

    ssl = nameko_config.get(AMQP_SSL_CONFIG_KEY)

    # TODO: standalone event dispatcher should accept context event_data
    # and insert a call id

    publisher = Publisher(amqp_uri, serializer=serializer, ssl=ssl, **kwargs)

    def dispatch(service_name, event_type, event_data):
        """ Dispatch an event claiming to originate from `service_name` with
        the given `event_type` and `event_data`.
        """
        exchange = get_event_exchange(service_name)

        publisher.publish(event_data,
                          exchange=exchange,
                          routing_key=event_type)

    return dispatch
예제 #2
0
 def publisher(self, amqp_uri, exchange, queue, routing_key):
     return Publisher(
         amqp_uri,
         serializer="json",
         exchange=exchange,
         routing_key=routing_key,
         declare=[exchange, queue]
     )
예제 #3
0
    def test_use_confirms(self, get_producer):
        """ Verify that publish-confirms can be set as a default specified at
        instantiation time, which can be overriden by a value specified at
        publish time.
        """
        publisher = Publisher("memory://", use_confirms=False)

        publisher.publish("payload")
        use_confirms = get_producer.call_args[0][3].get('confirm_publish')
        assert use_confirms is False

        publisher.publish("payload", use_confirms=True)
        use_confirms = get_producer.call_args[0][3].get('confirm_publish')
        assert use_confirms is True
예제 #4
0
    def test_declaration_precedence(self, producer):
        """ Verify that declarations at publish time extend any provided
        at instantiation time.
        """
        queue1 = Mock()
        publisher = Publisher("memory://", declare=[queue1])

        queue2 = Mock()
        publisher.publish("payload", declare=[queue2])
        assert producer.publish.call_args[1]["declare"] == [queue1, queue2]

        queue3 = Mock()
        publisher.publish("payload", declare=[queue3])
        assert producer.publish.call_args[1]["declare"] == [queue1, queue3]
예제 #5
0
    def test_publish_kwargs(self, producer):
        """ Verify that publish_kwargs at publish time augment any provided
        at instantiation time. Verify that publish_kwargs at publish time
        override any provided at instantiation time in the case of a clash.
        Verify that any keyword argument is transparently passed to kombu.
        """
        publisher = Publisher("memory://", reply_to="queue1")
        publisher.publish(
            "payload", reply_to="queue2", correlation_id="1", bogus="bogus"
        )

        # publish-time kwargs override instantiation-time kwargs
        assert producer.publish.call_args[1]["reply_to"] == "queue2"
        # publish-time kwargs augment instantiation-time kwargs
        assert producer.publish.call_args[1]["correlation_id"] == "1"
        # irrelevant keywords pass through transparently
        assert producer.publish.call_args[1]["bogus"] == "bogus"
예제 #6
0
    def test_header_precedence(self, producer):
        """ Verify that headers at publish time extend any provided
        at instantiation time.
        """
        headers1 = {'h1': Mock()}
        publisher = Publisher("memory://", headers=headers1)

        headers2 = {'h2': Mock()}
        publisher.publish("payload", headers=headers2)

        combined_headers = headers1.copy()
        combined_headers.update(headers2)
        assert producer.publish.call_args[1]["headers"] == combined_headers

        headers3 = {'h3': Mock()}
        publisher.publish("payload", headers=headers3)

        combined_headers = headers1.copy()
        combined_headers.update(headers3)
        assert producer.publish.call_args[1]["headers"] == combined_headers
예제 #7
0
    def republish(self, backoff_exc, message, target_queue):

        expiration = backoff_exc.next(message, self.exchange.name)
        queue = self.make_queue(expiration)

        properties = message.properties.copy()
        headers = properties.pop('application_headers', {})

        headers['backoff'] = expiration
        expiration_seconds = float(expiration) / 1000

        amqp_uri = self.container.config[AMQP_URI_CONFIG_KEY]

        # force redeclaration;
        # In kombu versions prior to 4.3.0, the publisher will skip declaration if
        # the entity has previously been declared by the same connection.
        # (see https://github.com/celery/kombu/pull/884)
        conn = Connection(amqp_uri)
        if KOMBU_PRE_4_3:  # pragma: no cover
            maybe_declare(
                queue, conn.channel(), retry=True, **DEFAULT_RETRY_POLICY
            )

        # republish to appropriate backoff queue
        publisher = Publisher(amqp_uri)
        publisher.publish(
            message.body,
            headers=headers,
            exchange=self.exchange,
            routing_key=target_queue,
            expiration=expiration_seconds,
            mandatory=True,
            retry=True,
            retry_policy=DEFAULT_RETRY_POLICY,
            declare=[queue.exchange, queue],
            **properties
        )