def _pack_json_msg(self, msg): """Qpid cannot serialize dicts containing strings longer than 65535 characters. This function dumps the message content to a JSON string, which Qpid is able to handle. :param msg: May be either a Qpid Message object or a bare dict. :returns: A Qpid Message with its content field JSON encoded. """ try: msg.content = jsonutils.dumps(msg.content) except AttributeError: # Need to have a Qpid message so we can set the content_type. msg = qpid_messaging.Message(jsonutils.dumps(msg)) msg.content_type = JSON_CONTENT_TYPE return msg
def serialize_msg(raw_msg): # NOTE(russellb) See the docstring for _RPC_ENVELOPE_VERSION for more # information about this format. msg = {_VERSION_KEY: _RPC_ENVELOPE_VERSION, _MESSAGE_KEY: jsonutils.dumps(raw_msg)} return msg
def test_notifier(self, mock_utcnow): self.config(notification_driver=["log"]) transport = _FakeTransport(self.conf) notifier = messaging.Notifier(transport, "test.localhost") message_id = uuid.uuid4() self.mox.StubOutWithMock(uuid, "uuid4") uuid.uuid4().AndReturn(message_id) mock_utcnow.return_value = datetime.datetime.utcnow() message = { "message_id": str(message_id), "publisher_id": "test.localhost", "event_type": "test.notify", "priority": "INFO", "payload": "bar", "timestamp": str(timeutils.utcnow()), } logger = self.mox.CreateMockAnything() self.mox.StubOutWithMock(logging, "getLogger") logging.getLogger("oslo.messaging.notification.test.notify").AndReturn(logger) logger.info(jsonutils.dumps(message)) self.mox.ReplayAll() notifier.info({}, "test.notify", "bar")
def marshal_request(request, context, envelope): msg = proton.Message() if envelope: request = common.serialize_msg(request) data = {"request": request, "context": context} msg.body = jsonutils.dumps(data) return msg
def __init__(self, session, node_name, node_opts=None): """Init the Publisher class with the exchange_name, routing_key, and other options """ self.sender = None self.session = session addr_opts = { "create": "always", "node": { "type": "topic", "x-declare": { "durable": False, # auto-delete isn't implemented for exchanges in qpid, # but put in here anyway "auto-delete": True, }, }, } if node_opts: addr_opts["node"]["x-declare"].update(node_opts) self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts)) self.reconnect(session)
def test_notifier(self): self.config(notification_driver=['log']) transport = _FakeTransport(self.conf) notifier = messaging.Notifier(transport, 'test.localhost') message_id = uuid.uuid4() self.mox.StubOutWithMock(uuid, 'uuid4') uuid.uuid4().AndReturn(message_id) timeutils.set_time_override() message = { 'message_id': str(message_id), 'publisher_id': 'test.localhost', 'event_type': 'test.notify', 'priority': 'INFO', 'payload': 'bar', 'timestamp': str(timeutils.utcnow.override_time), } logger = self.mox.CreateMockAnything() self.mox.StubOutWithMock(logging, 'getLogger') logging.getLogger('oslo.messaging.notification.test.notify').\ AndReturn(logger) logger.info(jsonutils.dumps(message)) self.mox.ReplayAll() notifier.info({}, 'test.notify', 'bar')
def test_notifier(self, mock_utcnow): self.config(notification_driver=['log']) transport = _FakeTransport(self.conf) notifier = messaging.Notifier(transport, 'test.localhost') message_id = uuid.uuid4() self.mox.StubOutWithMock(uuid, 'uuid4') uuid.uuid4().AndReturn(message_id) mock_utcnow.return_value = datetime.datetime.utcnow() message = { 'message_id': str(message_id), 'publisher_id': 'test.localhost', 'event_type': 'test.notify', 'priority': 'INFO', 'payload': 'bar', 'timestamp': str(timeutils.utcnow()), } logger = self.mox.CreateMockAnything() self.mox.StubOutWithMock(logging, 'getLogger') logging.getLogger('oslo.messaging.notification.test.notify').\ AndReturn(logger) logger.info(jsonutils.dumps(message)) self.mox.ReplayAll() notifier.info({}, 'test.notify', 'bar')
def __init__(self, conf, session, node_name, node_opts=None): """Init the Publisher class with the exchange_name, routing_key, and other options """ self.sender = None self.session = session if conf.qpid_topology_version == 1: addr_opts = { "create": "always", "node": { "type": "topic", "x-declare": { "durable": False, # auto-delete isn't implemented for exchanges in qpid, # but put in here anyway "auto-delete": True, }, }, } if node_opts: addr_opts["node"]["x-declare"].update(node_opts) self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts)) elif conf.qpid_topology_version == 2: self.address = node_name else: raise_invalid_topology_version(conf) self.reconnect(session)
def __init__(self, conf, session, callback, node_name, node_opts, link_name, link_opts): """Declare a queue on an amqp session. 'session' is the amqp session to use 'callback' is the callback to call when messages are received 'node_name' is the first part of the Qpid address string, before ';' 'node_opts' will be applied to the "x-declare" section of "node" in the address string. 'link_name' goes into the "name" field of the "link" in the address string 'link_opts' will be applied to the "x-declare" section of "link" in the address string. """ self.callback = callback self.receiver = None self.rcv_capacity = conf.qpid_receiver_capacity self.session = None if conf.qpid_topology_version == 1: addr_opts = { "create": "always", "node": { "type": "topic", "x-declare": { "durable": True, "auto-delete": True, }, }, "link": { "durable": True, "x-declare": { "durable": False, "auto-delete": True, "exclusive": False, }, }, } addr_opts["node"]["x-declare"].update(node_opts) elif conf.qpid_topology_version == 2: addr_opts = { "link": { "x-declare": { "auto-delete": True, "exclusive": False, }, }, } else: raise_invalid_topology_version(conf) addr_opts["link"]["x-declare"].update(link_opts) if link_name: addr_opts["link"]["name"] = link_name self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts)) self.connect(session)
def _post_envelope(marconi, envelope, queue_name): LOG.debug('Posting envelope to %s' % queue_name) envelope = rpc_common.serialize_msg(envelope) envelope = jsonutils.dumps(envelope) q = marconi.queue(queue_name) q.ensure_exists() q.post({'ttl': 60, 'body': envelope})
def marshal_request(request, context, envelope): msg = proton.Message() if envelope: request = common.serialize_msg(request) data = { "request": request, "context": context } msg.body = jsonutils.dumps(data) return msg
def marshal_response(reply=None, failure=None): # TODO(grs): do replies have a context? msg = proton.Message() if failure: failure = common.serialize_remote_exception(failure) data = {"failure": failure} else: data = {"response": reply} msg.body = jsonutils.dumps(data) return msg
def _serialize(data): """Serialization wrapper. We prefer using JSON, but it cannot encode all types. Error if a developer passes us bad data. """ try: return jsonutils.dumps(data, ensure_ascii=True) except TypeError: with excutils.save_and_reraise_exception(): LOG.error(_("JSON serialization failed."))
def test_reply_wire_format(self): if hasattr(self, 'skip_msg'): self.skipTest(self.skip_msg) transport = messaging.get_transport(self.conf) self.addCleanup(transport.cleanup) driver = transport._driver target = messaging.Target(topic=self.topic, server=self.server, fanout=self.fanout) listener = driver.listen(target) connection, producer = _create_producer(target) self.addCleanup(connection.release) msg = { 'oslo.version': '2.0', 'oslo.message': {} } msg['oslo.message'].update(self.msg) msg['oslo.message'].update(self.ctxt) msg['oslo.message'].update({ '_msg_id': uuid.uuid4().hex, '_unique_id': uuid.uuid4().hex, '_reply_q': 'reply_' + uuid.uuid4().hex, }) msg['oslo.message'] = jsonutils.dumps(msg['oslo.message']) producer.publish(msg) received = listener.poll() self.assertIsNotNone(received) self.assertEqual(self.expected_ctxt, received.ctxt) self.assertEqual(self.expected, received.message)
def test_deserialize_remote_exception(self): failure = { 'class': self.clsname, 'module': self.modname, 'message': 'test', 'tb': ['traceback\ntraceback\n'], 'args': self.args, 'kwargs': self.kwargs, } serialized = jsonutils.dumps(failure) ex = exceptions.deserialize_remote_exception(serialized, self.allowed) self.assertIsInstance(ex, self.cls) self.assertEqual(ex.__class__.__name__, self.remote_name) self.assertEqual(six.text_type(ex), self.str) if hasattr(self, 'msg'): self.assertEqual(six.text_type(ex), self.msg) self.assertEqual(ex.args, (self.msg,) + self.remote_args) else: self.assertEqual(ex.args, self.remote_args)
def test_deserialize_remote_exception(self): failure = { 'class': self.clsname, 'module': self.modname, 'message': 'test', 'tb': ['traceback\ntraceback\n'], 'args': self.args, 'kwargs': self.kwargs, } serialized = jsonutils.dumps(failure) ex = exceptions.deserialize_remote_exception(serialized, self.allowed) self.assertIsInstance(ex, self.cls) self.assertEqual(ex.__class__.__name__, self.remote_name) self.assertEqual(str(ex), self.str) if hasattr(self, 'msg'): self.assertEqual(ex.msg, self.msg) else: self.assertEqual(ex.message, self.message) self.assertEqual(ex.args, self.remote_args)
def serialize_remote_exception(failure_info, log_failure=True): """Prepares exception data to be sent over rpc. Failure_info should be a sys.exc_info() tuple. """ tb = traceback.format_exception(*failure_info) failure = failure_info[1] if log_failure: LOG.error(_("Returning exception %s to caller"), six.text_type(failure)) LOG.error(tb) kwargs = {} if hasattr(failure, 'kwargs'): kwargs = failure.kwargs # NOTE(matiu): With cells, it's possible to re-raise remote, remote # exceptions. Lets turn it back into the original exception type. cls_name = six.text_type(failure.__class__.__name__) mod_name = six.text_type(failure.__class__.__module__) if (cls_name.endswith(_REMOTE_POSTFIX) and mod_name.endswith(_REMOTE_POSTFIX)): cls_name = cls_name[:-len(_REMOTE_POSTFIX)] mod_name = mod_name[:-len(_REMOTE_POSTFIX)] data = { 'class': cls_name, 'module': mod_name, 'message': six.text_type(failure), 'tb': tb, 'args': failure.args, 'kwargs': kwargs } json_data = jsonutils.dumps(data) return json_data
def serialize_remote_exception(failure_info, log_failure=True): """Prepares exception data to be sent over rpc. Failure_info should be a sys.exc_info() tuple. """ tb = traceback.format_exception(*failure_info) failure = failure_info[1] if log_failure: LOG.error(_("Returning exception %s to caller"), six.text_type(failure)) LOG.error(tb) kwargs = {} if hasattr(failure, 'kwargs'): kwargs = failure.kwargs # NOTE(matiu): With cells, it's possible to re-raise remote, remote # exceptions. Lets turn it back into the original exception type. cls_name = str(failure.__class__.__name__) mod_name = str(failure.__class__.__module__) if (cls_name.endswith(_REMOTE_POSTFIX) and mod_name.endswith(_REMOTE_POSTFIX)): cls_name = cls_name[:-len(_REMOTE_POSTFIX)] mod_name = mod_name[:-len(_REMOTE_POSTFIX)] data = { 'class': cls_name, 'module': mod_name, 'message': six.text_type(failure), 'tb': tb, 'args': failure.args, 'kwargs': kwargs } json_data = jsonutils.dumps(data) return json_data
def notify(self, ctxt, message, priority): logger = logging.getLogger('%s.%s' % (self.LOGGER_BASE, message['event_type'])) getattr(logger, priority.lower())(jsonutils.dumps(message))
def notify(self, ctxt, message, priority, retry): logger = logging.getLogger('%s.%s' % (self.LOGGER_BASE, message['event_type'])) method = getattr(logger, priority.lower(), None) if method: method(jsonutils.dumps(message))