Example #1
0
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()
Example #2
0
    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))
Example #3
0
    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")
Example #4
0
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)
Example #5
0
 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)
Example #6
0
    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)
Example #9
0
    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)
Example #11
0
    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)
Example #13
0
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)
Example #16
0
 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'))
Example #17
0
    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)
Example #18
0
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)
Example #21
0
 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
Example #22
0
 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'))
Example #23
0
    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
Example #24
0
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
Example #27
0
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
Example #28
0
 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
Example #29
0
 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)