def test_send_messages(mock_gsd, mock_bc, app): mock_sender_one = mock.Mock() mock_sender_two = mock.Mock() mock_connection = mock.Mock() mock_connection.create_sender.side_effect = [ mock_sender_one, mock_sender_two ] mock_bc.return_value = mock_connection msg_one = proton.Message('{"han": "solo"}') msg_two = proton.Message('{"star": "wars"}') envelopes = [ messaging.Envelope('topic://VirtualTopic.eng.star_wars', msg_one), messaging.Envelope('topic://VirtualTopic.eng.star_wars2', msg_one), messaging.Envelope('topic://VirtualTopic.eng.star_wars', msg_two), ] messaging.send_messages(envelopes) mock_bc.assert_called_once_with(urls=['amqps://message-broker:5671'], timeout=30, ssl_domain=mock_gsd.return_value) # Verify that even though three messages were sent, only two senders were created since only # two unique addresses were used assert mock_connection.create_sender.call_count == 2 # Ensure the order is respected mock_connection.create_sender.assert_has_calls(( mock.call('topic://VirtualTopic.eng.star_wars'), mock.call('topic://VirtualTopic.eng.star_wars2'), )) assert mock_sender_one.send.call_count == 2 mock_sender_one.send.assert_has_calls( (mock.call(msg_one, timeout=30), mock.call(msg_two, timeout=30))) mock_sender_two.send.assert_called_once_with(msg_one, timeout=30) mock_connection.close.assert_called_once_with()
def send_message(self, message: Any, subject: str, content_type='application/json') -> None: """ Sends the provided message via the broker. The subject will serve as a routing key in the broker. Typically it should be the respective topic_id. :param message: :param subject: :param content_type: """ if not isinstance(message, proton.Message): message = proton.Message(body=message) message.subject = subject message.content_type = content_type if self._sender and self._sender.credit: self._sender.send(message) _logger.info( truncate_message(message=f"Message sent: {message}", max_length=100)) else: _logger.info( truncate_message( message=f"No credit to send message {message}", max_length=100))
def test_message_user_id_proxy_zzz_credit_handled(self): # Test for DISPATCH-519. Make sure the REJECTED messages result # in the client receiving credit. credit_limit = 250 # router issues 250 credits ssl_opts = dict() ssl_opts['ssl-trustfile'] = self.ssl_file('ca-certificate.pem') ssl_opts['ssl-certificate'] = self.ssl_file('client-certificate.pem') ssl_opts['ssl-key'] = self.ssl_file('client-private-key.pem') ssl_opts['ssl-password'] = '******' # create the SSL domain object domain = self.create_ssl_domain(ssl_opts) # Send a message with bad user_id. This message should be rejected. # Connection has user_id 'user13'. addr = self.address(13).replace("amqp", "amqps") blocking_connection = BlockingConnection(addr, ssl_domain=domain) blocking_sender = blocking_connection.create_sender("$management") request = proton.Message() request.user_id = BINARY("bad-user-id") for i in range(0, credit_limit + 1): result = Delivery.ACCEPTED try: delivery = blocking_sender.send(request, timeout=10) result = delivery.remote_state except proton.utils.SendException as e: result = e.state except proton.utils.Timeout as e: self.fail("Timed out waiting for send credit") self.assertTrue(result == Delivery.REJECTED, "Router accepted a message with user_id that did not match connection user_id")
def produce_message(options, args): producer_config = { 'urls': broker_envs[options.env], 'certificate': options.cert_file, 'private_key': options.private_key_file, 'trusted_certificates': options.ca_certs, } if options.properties: properties = dict((prop.split('=', 1) for prop in options.properties)) else: properties = {} with AMQProducer(**producer_config) as producer: if options.producer_queue: producer.through_queue(options.producer_queue) if options.producer_topic: producer.through_topic(options.producer_topic) message = proton.Message() message.body = ' '.join(args) if isinstance(message.body, six.binary_type): # On python2, convert to unicode message.body = message.body.decode('utf-8', 'replace') message.properties = properties.copy() message.subject = options.subject producer.send(message)
def _create_jms_mapmessage(self, test_value_type, test_value, name, hdr_kwargs, hdr_annotations): """Create a JMS map message""" if test_value_type == 'boolean': value = test_value == 'True' elif test_value_type == 'byte': value = proton.byte(int(test_value, 16)) elif test_value_type == 'bytes': value = base64.b64decode(test_value) elif test_value_type == 'char': value = proton.char(base64.b64decode(test_value).decode('utf-8')) elif test_value_type == 'double': value = struct.unpack('!d', test_value[2:].decode('hex'))[0] elif test_value_type == 'float': value = proton.float32( struct.unpack('!f', test_value[2:].decode('hex'))[0]) elif test_value_type == 'int': value = proton.int32(int(test_value, 16)) elif test_value_type == 'long': value = int(test_value, 16) elif test_value_type == 'short': value = proton.short(int(test_value, 16)) elif test_value_type == 'string': value = test_value else: raise InteropTestError( 'JmsSenderShim._create_jms_mapmessage: Unknown or unsupported subtype "%s"' % test_value_type) return proton.Message(id=(self.sent + 1), body={name: value}, inferred=False, annotations=JmsHdrsPropsTestSender.merge_dicts( create_annotation('JMS_MAPMESSAGE_TYPE'), hdr_annotations), **hdr_kwargs)
def _processIncoming(self, delivery, connector): link = proton.pn_delivery_link(delivery) ssn = proton.pn_link_session(link) msg = [] self.log.debug("Receiving '%s'", proton.pn_delivery_tag(delivery)) while True: rc, buff = proton.pn_link_recv(link, 1024) msg.append(buff) if rc == proton.PN_EOS: break msg = ''.join(msg) self.log.debug("Received '%s'", proton.pn_delivery_tag(delivery)) proton.pn_link_advance(link) proton.pn_delivery_update(delivery, proton.PN_ACCEPTED) proton.pn_delivery_settle(delivery) msgObj = proton.Message() msgObj.decode(msg) ctx = proton.pn_session_get_context(ssn) ctx._pushIncomingMessage(msgObj.body) # if more credit is needed, grant it if proton.pn_link_credit(link) == 0: proton.pn_link_flow(link, MBUFF_SIZE)
def test_message_user_id_proxy_bad_name_disallowed(self): ssl_opts = dict() ssl_opts['ssl-trustfile'] = self.ssl_file('ca-certificate.pem') ssl_opts['ssl-certificate'] = self.ssl_file('client-certificate.pem') ssl_opts['ssl-key'] = self.ssl_file('client-private-key.pem') ssl_opts['ssl-password'] = '******' # create the SSL domain object domain = self.create_ssl_domain(ssl_opts) # Send a message with bad user_id. This message should be rejected. # Connection has user_id 'user13'. addr = self.address(13).replace("amqp", "amqps") blocking_connection = BlockingConnection(addr, ssl_domain=domain) blocking_sender = blocking_connection.create_sender("$management") request = proton.Message() request.user_id = u"bad-user-id" result = Delivery.ACCEPTED try: delivery = blocking_sender.send(request, timeout=10) result = delivery.remote_state except proton.utils.SendException as e: result = e.state self.assertTrue( result == Delivery.REJECTED, "Router accepted a message with user_id that did not match connection user_id" )
def _rhmsg_publish(topic, msg): """Send message to Unified Message Bus :param str topic: the topic where message will be sent to, e.g. ``build.tagged``. :param dict msg: the message that will be sent. """ import proton from rhmsg.activemq.producer import AMQProducer producer_config = { 'urls': conf.rhmsg_brokers, 'certificate': conf.rhmsg_certificate, 'private_key': conf.rhmsg_private_key, 'trusted_certificates': conf.rhmsg_ca_cert, } with AMQProducer(**producer_config) as producer: topic = f'{conf.rhmsg_topic_prefix.rstrip(".")}.{topic}' producer.through_topic(topic) outgoing_msg = proton.Message() outgoing_msg.body = json.dumps(msg) if conf.dry_run: logger.info('DRY-RUN: AMQProducer.send(%s) through topic %s', outgoing_msg, topic) else: logger.debug('Send message: %s', outgoing_msg) producer.send(outgoing_msg)
def qpidMsg(self): """ Construct a NEW QPID message. """ msg = proton.Message(content_type="text/plain", durable=True) msg.body = self.content() return msg
def _create_jms_streammessage(self, test_value_type, test_value, hdr_kwargs, hdr_annotations): """Create a JMS stream message""" if test_value_type == 'boolean': body_list = [test_value == 'True'] elif test_value_type == 'byte': body_list = [proton.byte(int(test_value, 16))] elif test_value_type == 'bytes': body_list = [base64.b64decode(test_value)] elif test_value_type == 'char': body_list = [proton.char(base64.b64decode(test_value).decode('utf-8'))] elif test_value_type == 'double': body_list = [struct.unpack('!d', test_value[2:].decode('hex'))[0]] elif test_value_type == 'float': body_list = [proton.float32(struct.unpack('!f', test_value[2:].decode('hex'))[0])] elif test_value_type == 'int': body_list = [proton.int32(int(test_value, 16))] elif test_value_type == 'long': body_list = [_compat.str2long(test_value, 16)] elif test_value_type == 'short': body_list = [proton.short(int(test_value, 16))] elif test_value_type == 'string': body_list = [test_value] else: raise InteropTestError('JmsSenderShim._create_jms_streammessage: Unknown or unsupported subtype "%s"' % test_value_type) return proton.Message(id=(self.sent+1), body=body_list, inferred=True, annotations=JmsHdrsPropsTestSender.merge_dicts(create_annotation('JMS_STREAMMESSAGE_TYPE'), hdr_annotations), **hdr_kwargs)
def _queueOutgoingDeliveries(self, conn): for ssn in self._iterSessions(conn, proton.PN_LOCAL_ACTIVE): ctx = proton.pn_session_get_context(ssn) sender = ctx.sender if sender is None: # No sender link sender = proton.pn_sender(ctx.session, "sender-%s" % str(uuid.uuid4())) ctx.sender = sender continue while proton.pn_link_credit(sender) > 0: try: data = ctx._popPendingMessage() except Empty: break else: msg = proton.Message() msg.body = data d = proton.pn_delivery(sender, "delivery-%s" % str(uuid.uuid4())) proton.pn_delivery_set_context(d, msg.encode()) self.log.debug("Queueing delivery (%s)", proton.pn_delivery_tag(d))
def _create_jms_bytesmessage(self, test_value_type, test_value, hdr_kwargs, hdr_annotations): """Create a JMS bytes message""" # NOTE: test_value contains all unicode strings u'...' as returned by json body_bytes = None if test_value_type == 'boolean': body_bytes = b'\x01' if test_value == 'True' else b'\x00' elif test_value_type == 'byte': body_bytes = struct.pack('b', int(test_value, 16)) elif test_value_type == 'bytes': body_bytes = base64.b64decode(test_value) elif test_value_type == 'char': # JMS expects two-byte chars, ASCII chars can be prefixed with '\x00' body_bytes = b'\x00' + base64.b64decode(test_value) elif test_value_type == 'double' or test_value_type == 'float': body_bytes = test_value[2:].decode('hex') elif test_value_type == 'int': body_bytes = struct.pack('!i', int(test_value, 16)) elif test_value_type == 'long': body_bytes = struct.pack('!q', _compat.str2long(test_value, 16)) elif test_value_type == 'short': body_bytes = struct.pack('!h', proton.short(test_value, 16)) elif test_value_type == 'string': # NOTE: First two bytes must be string length test_value_str = str(test_value) # remove unicode body_bytes = struct.pack('!H', len(test_value_str)) + test_value_str else: raise InteropTestError('JmsSenderShim._create_jms_bytesmessage: Unknown or unsupported subtype "%s"' % test_value_type) return proton.Message(id=(self.sent+1), body=body_bytes, inferred=True, content_type='application/octet-stream', annotations=JmsHdrsPropsTestSender.merge_dicts(create_annotation('JMS_BYTESMESSAGE_TYPE'), hdr_annotations), **hdr_kwargs)
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): import proton self.messenger = proton.Messenger() self.messenger.certificate = settings.MESSAGE_BUS['CERT_FILE'] self.messenger.private_key = settings.MESSAGE_BUS['KEY_FILE'] self.messenger.start() self.message = proton.Message()
def _rhmsg_publish(topic, msg): """Send message to Unified Message Bus :param str topic: the topic where message will be sent to, e.g. ``build.tagged``. :param dict msg: the message that will be sent. """ import proton from rhmsg.activemq.producer import AMQProducer config = conf.messaging_backends['rhmsg'] producer_config = { 'urls': config['brokers'], 'certificate': config['certificate'], 'private_key': config['private_key'], 'trusted_certificates': config['ca_cert'], } with AMQProducer(**producer_config) as producer: prefix = config['topic_prefix'].rstrip('.') topic = f'{prefix}.{topic}' producer.through_topic(topic) outgoing_msg = proton.Message() outgoing_msg.body = json.dumps(msg) if conf.dry_run: logger.info('DRY-RUN: AMQProducer.send(%s) through topic %s', outgoing_msg, topic) else: producer.send(outgoing_msg)
def _create_jms_mapmessage(self, test_value_type, test_value, name): """Create a JMS map message""" if test_value_type == 'boolean': value = test_value == 'True' elif test_value_type == 'byte': value = proton.byte(int(test_value, 16)) elif test_value_type == 'bytes': value = test_value.encode('utf-8') elif test_value_type == 'char': value = proton.char(test_value) elif test_value_type == 'double': value = struct.unpack('!d', _compat.decode_hex(test_value[2:]))[0] elif test_value_type == 'float': value = proton.float32( struct.unpack('!f', _compat.decode_hex(test_value[2:]))[0]) elif test_value_type == 'int': value = proton.int32(int(test_value, 16)) elif test_value_type == 'long': value = _compat.str2long(test_value, 16) elif test_value_type == 'short': value = proton.short(int(test_value, 16)) elif test_value_type == 'string': value = test_value else: raise InteropTestError('JmsMessagesTestSender._create_jms_mapmessage: ' \ 'Unknown or unsupported subtype "%s"' % test_value_type) return proton.Message( id=(self.sent + 1), body={name: value}, inferred=False, annotations=create_annotation('JMS_MAPMESSAGE_TYPE'))
def run(self): self.command.ready.wait() with self.command.input_file as f: while True: if self.command.done.is_set(): break string = f.readline() if string == "": self.command.send_input(None) break if string.endswith("\n"): string = string[:-1] if string.startswith("{") and string.endswith("}"): data = _json.loads(string) message = convert_data_to_message(data) else: string = unicode(string) message = _proton.Message(string) self.command.send_input(message)
def wrap_proton_message(impl): if impl is None: return None wrapper = proton.Message() wrapper._msg.decode(impl) wrapper._post_decode() return wrapper
def _create_jms_textmessage(self, test_value_text, hdr_kwargs, hdr_annotations): """Create a JMS text message""" return proton.Message(id=(self.sent+1), body=_compat.unicode(test_value_text), annotations=JmsHdrsPropsTestSender.merge_dicts(create_annotation('JMS_TEXTMESSAGE_TYPE'), hdr_annotations), **hdr_kwargs)
def on_message(self, event): import proton fake_msg = proton.Message( body=ReceiverHandler.fake_msg_body, id='msg-id-01', address='topic://VirtualTopic.eng.app.event', ) self.callback(fake_msg, data=None)
def request(self, body=None, **properties): """ Make a L{proton.Message} containining a management request. """ request = proton.Message() request.properties = properties request.body = body or {} return request
def _create_jms_objectmessage(self, test_value): """Create a JMS object message""" java_binary = self._s_get_java_obj_binary(test_value) return proton.Message( id=(self.sent + 1), body=java_binary, inferred=True, content_type='application/x-java-serialized-object', annotations=create_annotation('JMS_OBJECTMESSAGE_TYPE'))
def query( self, entity_type: str = 'org.apache.qpid.dispatch.router.node') -> list: """ Queries the related router instance, retrieving information for the provided Entity Type. The result is an array of a named tuple, whose fields are the attribute names returned by the router. In example, if querying entity type: org.apache.qpid.dispatch.allocator, the results can be accessed as: result.typeName, result.typeSize, ... same names returned by the router. :param entity_type: :return: """ # Scheme to use scheme: str = 'amqp' if self._connection_options['ssl_domain']: scheme = 'amqps' # URL to test url: Url = Url('%s://%s:%s/$management' % (scheme, self.host, self.port)) self._logger.info('Querying router at: %s://%s:%s/$management' % (scheme, self.host, self.port)) # Proton connection self._logger.debug('Connection options: %s' % self._connection_options) connection: BlockingConnection = BlockingConnection( url, **self._connection_options) # Proton sync client client: SyncRequestResponse = SyncRequestResponse(connection, url.path) # Request message object request: proton.Message = proton.Message() request.properties = { u'operation': u'QUERY', u'entityType': u'%s' % entity_type, } request.body = {u'attributeNames': []} # Sending the request response: client.call = client.call(request) # Closing connection client.connection.close() # Namedtuple that represents the query response from the router # so fields can be read based on their attribute names. RouterQueryResults = namedtuple( 'RouterQueryResults', response.body['attributeNames']) # type: ignore records: list = [] for record in response.body['results']: records.append(RouterQueryResults(*record)) return records
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 _create_jms_objectmessage(self, test_value, hdr_kwargs, hdr_annotations): """Create a JMS object message""" java_binary = self._s_get_java_obj_binary(test_value) return proton.Message(id=(self.sent+1), body=java_binary, inferred=True, content_type='application/x-java-serialized-object', annotations=JmsHdrsPropsTestSender.merge_dicts(create_annotation('JMS_MAPMESSAGE_TYPE'), hdr_annotations), **hdr_kwargs)
def test_umb_message(self): from message_tagging_service.consumer import UMBMessage import proton msg = UMBMessage(proton.Message( body=json.dumps({'name': 'modulea'}), id='msg-id-01', address='topic://VirtualTopic.event', )) assert 'msg-id-01' == msg.id assert {'name': 'modulea'} == msg.body assert 'topic://VirtualTopic.event' == msg.topic
def process_input_line(line): if line.endswith("\n"): line = line[:-1] if line.startswith("{") and line.endswith("}"): data = _json.loads(line) message = convert_data_to_message(data) else: message = _proton.Message(line) return message
def request(self, body=None, **properties): """ Make a L{proton.Message} containining a management request. @param body: The request body, a dict or list. @param properties: Keyword arguments for application-properties of the request. @return: L{proton.Message} containining the management request. """ if self.locales: properties.setdefault(u'locales', self.locales) request = proton.Message() request.properties = clean_dict(properties) request.body = body or {} return request
def _create_jms_message(self, test_value_type, test_value): """Create a JMS message type (without message body)""" if test_value_type != 'none': raise InteropTestError('JmsMessagesTestSender._create_jms_message: ' \ 'Unknown or unsupported subtype "%s"' % test_value_type) if test_value is not None: raise InteropTestError('JmsMessagesTestSender._create_jms_message: ' \ 'Invalid value "%s" for subtype "%s"' % (test_value, test_value_type)) return proton.Message( id=(self.sent + 1), content_type='application/octet-stream', annotations=create_annotation('JMS_MESSAGE_TYPE'))
def _create_jms_message(self, test_value_type, test_value, hdr_kwargs, hdr_annotations): """Create a JMS message type (without message body)""" if test_value_type != 'none': raise InteropTestError('JmsSenderShim._create_jms_message: Unknown or unsupported subtype "%s"' % test_value_type) if test_value is not None: raise InteropTestError('JmsSenderShim._create_jms_message: Invalid value "%s" for subtype "%s"' % (test_value, test_value_type)) return proton.Message(id=(self.sent+1), content_type='application/octet-stream', annotations=JmsHdrsPropsTestSender.merge_dicts(create_annotation('JMS_MESSAGE_TYPE'), hdr_annotations), **hdr_kwargs)