def simple_notification(connection, queue_name, exchange_name, routing_key, text_body): """ Publishes a simple notification. Inputs: - connection: A rabbitmq connection object. - queue_name: The name of the queue to be checked or created. - exchange_name: The name of the notification exchange. - routing_key: The routing key for the exchange-queue binding. - text_body: The text to be published. """ channel = connection.channel() channel.queue_declare(queue_name, durable=True, exclusive=False, auto_delete=False) try: channel.exchange_declare(exchange_name, type="fanout", durable=True, auto_delete=False) except PreconditionFailed: pass channel.queue_bind(queue_name, exchange_name, routing_key=routing_key) message = Message(text_body) channel.basic_publish(message, exchange_name, routing_key)
def test_defaults(self): """Test how a queue defaults to being bound to an AMQP default exchange, and how publishing defaults to the default exchange, and basic_get defaults to getting from the most recently declared queue, and queue_delete defaults to deleting the most recently declared queue.""" msg = Message( 'funtest message', content_type='text/plain', application_headers={ 'foo': 7, 'bar': 'baz' }, ) qname, _, _ = self.ch.queue_declare() self.ch.basic_publish(msg, routing_key=qname) msg2 = self.ch.basic_get(no_ack=True) self.assertEqual(msg, msg2) n = self.ch.queue_purge() self.assertEqual(n, 0) n = self.ch.queue_delete() self.assertEqual(n, 0)
def test_exchange_bind(self): """Test exchange binding. Network configuration is as follows (-> is forwards to : source_exchange -> dest_exchange -> queue The test checks that once the message is publish to the destination exchange(unittest.topic_dest) it is delivered to the queue. """ test_routing_key = 'unit_test__key' dest_exchange = 'unittest.topic_dest_bind' source_exchange = 'unittest.topic_source_bind' self.ch.exchange_declare(dest_exchange, 'topic', auto_delete=True) self.ch.exchange_declare(source_exchange, 'topic', auto_delete=True) qname, _, _ = self.ch.queue_declare() self.ch.exchange_bind(destination=dest_exchange, source=source_exchange, routing_key=test_routing_key) self.ch.queue_bind(qname, dest_exchange, routing_key=test_routing_key) msg = Message('unittest message', content_type='text/plain', application_headers={ 'foo': 7, 'bar': 'baz' }) self.ch.basic_publish(msg, source_exchange, routing_key=test_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg, msg2)
def put(self, message_dict=None, routing_key='', exchange=None, body=None, priority=0): """ Publishes a message to the queue. message_dict: the json-serializable object that will be published when body is None routing_key: the routing key for the message. exchange: the exchange to which the message will be published. body: The message to be published. If none, message_dict is published. It also works as a context manager: with Publisher(**options) as queue: for msg in msgs: queue.put(msg) """ if exchange is None: exchange = self.default_exchange or '' if body is None: try: body = json.dumps(message_dict) except Exception as e: raise SerializationError(e) message = Message(body, delivery_mode=2, content_type='application/json', priority=priority) return self._try('basic_publish', msg=message, exchange=exchange, routing_key=routing_key)
def put(self, message_dict=None, routing_key='', exchange=None, body=None, priority=0): """ Publishes a message to the queue. message_dict: the json-serializable object that will be published when body is None routing_key: the routing key for the message. exchange: the exchange to which the message will be published. Defaults to the one passed on __init___(). key body: The message to be published. If none, message_dict is published. """ if exchange is None: exchange = self.default_exchange or '' if body is None: try: message_dict = add_trail_keys(message_dict, exchange, routing_key) body = json.dumps(message_dict) except Exception as e: raise SerializationError(e) message = Message(body, delivery_mode=2, content_type='application/json', priority=priority or trail.get_priority()) return self._try('basic_publish', msg=message, exchange=exchange, routing_key=routing_key)
def test_with(self): with Connection(**settings.connect_args) as conn: self.assertEqual(conn.transport is None, False) with conn.channel(1) as ch: self.assertEqual(1 in conn.channels, True) # # Do something with the channel # ch.exchange_declare('unittest.fanout', 'fanout', auto_delete=True) msg = Message('unittest message', content_type='text/plain', application_headers={ 'foo': 7, 'bar': 'baz' }) ch.basic_publish(msg, 'unittest.fanout') # # check that the channel was closed # self.assertEqual(1 in conn.channels, False) self.assertEqual(ch.is_open, False) # # Check that the connection was closed # self.assertEqual(conn.transport, None)
def amqp_publish(exchange, routing_key, data): connection = Connection() channel = connection.channel() msg = Message(json.dumps(data)) channel.basic_publish(msg, exchange=exchange, routing_key=routing_key) channel.close() connection.close()
def test_put_uses_default_exchange_if_not_supplied(self): amqp_msg = Message('body', delivery_mode=2, content_type='application/json', priority=0) self.external_queue.put(body='body') self.assertEqual( self.channel_mock.basic_publish.call_args_list, [call(msg=amqp_msg, exchange='default_exchange', routing_key='')])
def test_publish(self): self.ch.exchange_declare('funtest.fanout', 'fanout', auto_delete=True) msg = Message( 'funtest message', content_type='text/plain', application_headers={'foo': 7, 'bar': 'baz'}, ) self.ch.basic_publish(msg, 'funtest.fanout')
def amqp_publish(exchange, routing_key, data, ex_type='fanout', ex_declare=False): connection = Connection() channel = connection.channel() if ex_declare: channel.exchange_declare(exchange=exchange, type=ex_type) msg = Message(json.dumps(data)) channel.basic_publish(msg, exchange=exchange, routing_key=routing_key) channel.close() connection.close()
def test_invalid_header(self): """ Test sending a message with an unserializable object in the header http://code.google.com/p/py-amqplib/issues/detail?id=17 """ qname, _, _ = self.ch.queue_declare() msg = Message(application_headers={'test': object()}) self.assertRaises( FrameSyntaxError, self.ch.basic_publish, msg, routing_key=qname, )
def test_queue(self): my_routing_key = 'funtest.test_queue' msg = Message( 'funtest message', content_type='text/plain', application_headers={'foo': 7, 'bar': 'baz'}, ) qname, _, _ = self.ch.queue_declare() self.ch.queue_bind(qname, 'amq.direct', routing_key=my_routing_key) self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg, msg2)
def test_basic_publish(self): # Test verifing publishing message. frame_writer_cls_mock = Mock() conn = Connection(frame_writer=frame_writer_cls_mock) with patch.object(conn, 'Transport') as transport_mock: handshake(conn, transport_mock) ch = create_channel(1, conn, transport_mock) frame_writer_mock = frame_writer_cls_mock() frame_writer_mock.reset_mock() msg = Message('test') ch.basic_publish(msg) frame_writer_mock.assert_called_once_with( 1, 1, spec.Basic.Publish, dumps('Bssbb', (0, '', '', False, False)), msg)
def amqp_publish(exchange, routing_key, data, ex_type='fanout', ex_declare=False, auto_delete=True, connection=None): close = False if connection is None: connection = Connection(config.AMQP_URI) close = True channel = connection.channel() if ex_declare: channel.exchange_declare(exchange=exchange, type=ex_type, auto_delete=auto_delete) msg = Message(json.dumps(data)) channel.basic_publish(msg, exchange=exchange, routing_key=routing_key) channel.close() if close: connection.close()
def _process_message(self, message: amqp.Message) -> None: """Processes the message received from the queue.""" if self.shutdown_pending.is_set(): return try: if isinstance(message.body, bytes): message.body = message.body.decode() description = json.loads(message.body) except Exception: logger.error("Cannot decode message. Dropping. Message: %r", message.body) traceback.print_exc() message.channel.basic_reject(message.delivery_tag, requeue=False) else: logger.info("Processing task: %r", description) self._process_description(message, description)
def _process_message(self, message: amqp.Message) -> None: """Processes the message received from the queue.""" if self.shutdown_pending.is_set(): return try: if isinstance(message.body, bytes): message.body = message.body.decode() description = json.loads(message.body) except Exception: logger.error("Cannot decode message. Dropping. Message: %r", message.body) traceback.print_exc() message.channel.basic_reject(message.delivery_tag, requeue=False) else: logger.info("Processing task: %r", description) self._process_description(message, description)
def test_large(self): """ Test sending some extra large messages. """ qname, _, _ = self.ch.queue_declare() for multiplier in [100, 1000, 10000]: msg = Message( 'funtest message' * multiplier, content_type='text/plain', application_headers={'foo': 7, 'bar': 'baz'}, ) self.ch.basic_publish(msg, routing_key=qname) msg2 = self.ch.basic_get(no_ack=True) self.assertEqual(msg, msg2)
def test_basic_return(self): self.ch.exchange_declare('funtest.fanout', 'fanout', auto_delete=True) msg = Message( 'funtest message', content_type='text/plain', application_headers={'foo': 7, 'bar': 'baz'}) self.ch.basic_publish(msg, 'funtest.fanout') self.ch.basic_publish(msg, 'funtest.fanout', mandatory=True) self.ch.basic_publish(msg, 'funtest.fanout', mandatory=True) self.ch.basic_publish(msg, 'funtest.fanout', mandatory=True) self.ch.close() # # 3 of the 4 messages we sent should have been returned # self.assertEqual(self.ch.returned_messages.qsize(), 3)
def basic_publish(amqp_context, msg, exchange, routing_key, mandatory, immediate): if amqp_context.channel is None: amqp_context.echo_error('Not connected to broker. Please retry...') amqp_context.reconnect() else: # XXX Hack to fix Issue #2013 if isinstance(amqp_context.connection.connection, Connection): msg = Message(msg) try: amqp_context.channel.basic_publish(msg, exchange=exchange, routing_key=routing_key, mandatory=mandatory, immediate=immediate) except Exception as e: amqp_context.echo_error(e) amqp_context.reconnect() else: amqp_context.echo_ok()
def build_message(body, ttl, durable): """ Construct a message object. :param body: The message body. :param ttl: Time to Live (seconds) :type ttl: float :param durable: The message is durable. :type durable: bool :return: The message. :rtype: Message """ properties = {} if ttl: ms = ttl * 1000 # milliseconds properties.update(expiration=str(ms)) if durable: properties.update(delivery_mode=2) else: properties.update(delivery_mode=1) return Message(body, **properties)
def basic_publish(self, body, properties={}): properties['delivery_mode'] = 2 msg = Message(body, **properties) self.channel.basic_publish(exchange=self.exchange, routing_key=self.routing_key, msg=msg)
def _parsed_message(body='{"_table": "artist", "id": "42"}', channel="search.index"): msg = Message(body=body) parsed_message = PMessage.from_amqp_message(channel, msg) return parsed_message
def simpler_notification(channel, queue_name, exchange_name, routing_key, text_body): message = Message(text_body) channel.basic_publish(message, exchange_name, routing_key)
def test_encoding(self): my_routing_key = 'funtest.test_queue' qname, _, _ = self.ch.queue_declare() self.ch.queue_bind(qname, 'amq.direct', routing_key=my_routing_key) # # No encoding, body passed through unchanged # msg = Message('hello world') self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) if sys.version_info[0] < 3: self.assertFalse(hasattr(msg2, 'content_encoding')) self.assertTrue(isinstance(msg2.body, str)) self.assertEqual(msg2.body, 'hello world') # # Default UTF-8 encoding of unicode body, returned as unicode # msg = Message(u'hello world') self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg2.content_encoding, 'UTF-8') self.assertTrue(isinstance(msg2.body, unicode)) self.assertEqual(msg2.body, u'hello world') # # Explicit latin_1 encoding, still comes back as unicode # msg = Message(u'hello world', content_encoding='latin_1') self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg2.content_encoding, 'latin_1') self.assertTrue(isinstance(msg2.body, unicode)) self.assertEqual(msg2.body, u'hello world') # # Plain string with specified encoding comes back as unicode # msg = Message('hello w\xf6rld', content_encoding='latin_1') self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg2.content_encoding, 'latin_1') self.assertTrue(isinstance(msg2.body, unicode)) self.assertEqual(msg2.body, u'hello w\u00f6rld') # # Plain string (bytes in Python 3.x) with bogus encoding # # don't really care about latin_1, just want bytes test_bytes = u'hello w\xd6rld'.encode('latin_1') msg = Message(test_bytes, content_encoding='I made this up') self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg2.content_encoding, 'I made this up') self.assertTrue(isinstance(msg2.body, bytes)) self.assertEqual(msg2.body, test_bytes) # # Turn off auto_decode for remaining tests # self.ch.auto_decode = False # # Unicode body comes back as utf-8 encoded str # msg = Message(u'hello w\u00f6rld') self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg2.content_encoding, 'UTF-8') self.assertTrue(isinstance(msg2.body, bytes)) self.assertEqual(msg2.body, u'hello w\xc3\xb6rld'.encode('latin_1')) # # Plain string with specified encoding stays plain string # msg = Message('hello w\xf6rld', content_encoding='latin_1') self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg2.content_encoding, 'latin_1') self.assertTrue(isinstance(msg2.body, bytes)) self.assertEqual(msg2.body, u'hello w\xf6rld'.encode('latin_1')) # # Explicit latin_1 encoding, comes back as str # msg = Message(u'hello w\u00f6rld', content_encoding='latin_1') self.ch.basic_publish(msg, 'amq.direct', routing_key=my_routing_key) msg2 = self.ch.basic_get(qname, no_ack=True) self.assertEqual(msg2.content_encoding, 'latin_1') self.assertTrue(isinstance(msg2.body, bytes)) self.assertEqual(msg2.body, u'hello w\xf6rld'.encode('latin_1'))
def _parsed_message(body="artist 123 456", channel="search.index"): msg = Message(body=body) parsed_message = PMessage.from_amqp_message(channel, msg) return parsed_message
def test_callback(self): msg = Message('["msg"]') self.assertEqual(self.driver.callback(msg), None) self.driver._callback.assert_called_with('msg')