示例#1
0
    def publish(self, exchange, routing_key='', mandatory=False):
        """Publish the message to the exchange with the specified routing
        key.

        In Python 2 if the message is a ``unicode`` value it will be converted
        to a ``str`` using ``str.encode('UTF-8')``. If you do not want the
        auto-conversion to take place, set the body to a ``str`` or ``bytes``
        value prior to publishing.

        In Python 3 if the message is a ``str`` value it will be converted to
        a ``bytes`` value using ``bytes(value.encode('UTF-8'))``. If you do
        not want the auto-conversion to take place, set the body to a
        ``bytes`` value prior to publishing.

        :param exchange: The exchange to publish the message to
        :type exchange: str or :class:`rabbitpy.Exchange`
        :param str routing_key: The routing key to use
        :param bool mandatory: Requires the message is published
        :return: bool or None
        :raises: rabbitpy.exceptions.MessageReturnedException

        """
        if isinstance(exchange, base.AMQPClass):
            exchange = exchange.name

        # Coerce the body to the proper type
        payload = utils.maybe_utf8_encode(self.body)

        frames = [
            specification.Basic.Publish(exchange=exchange,
                                        routing_key=routing_key or '',
                                        mandatory=mandatory),
            header.ContentHeader(body_size=len(payload),
                                 properties=self._properties)
        ]

        # Calculate how many body frames are needed
        pieces = int(
            math.ceil(len(payload) / float(self.channel.maximum_frame_size)))

        # Send the message
        for offset in range(0, pieces):
            start = self.channel.maximum_frame_size * offset
            end = start + self.channel.maximum_frame_size
            if end > len(payload):
                end = len(payload)
            frames.append(body.ContentBody(payload[start:end]))

        # Write the frames out
        self.channel._write_frames(frames)

        # If publisher confirmations are enabled, wait for the response
        if self.channel.publisher_confirms:
            response = self.channel._wait_for_confirmation()
            if isinstance(response, specification.Basic.Ack):
                return True
            elif isinstance(response, specification.Basic.Nack):
                return False
            else:
                raise exceptions.UnexpectedResponseError(response)
示例#2
0
    async def test_basic_return(self):
        async def on_return(msg: message.Message) -> None:
            self.assertEqual(msg.reply_code, 404)
            self.assertEqual(msg.reply_text, 'Not Found')
            self.assertEqual(msg.exchange, self.exchange)
            self.assertEqual(msg.body, self.body)
            self.test_finished.set()

        self.client.register_basic_return_callback(on_return)

        await self.connect()
        await self.client.publish(self.exchange, self.routing_key, self.body)

        # Fake the Basic.Return
        self.client._on_frame(
            self.client._channel,
            commands.Basic.Return(404, 'Not Found', self.exchange,
                                  self.routing_key))
        self.client._on_frame(
            self.client._channel,
            header.ContentHeader(0, len(self.body),
                                 commands.Basic.Properties()))
        self.client._on_frame(self.client._channel,
                              body.ContentBody(self.body))

        await self.test_finished.wait()
示例#3
0
def _unmarshal_body_frame(frame_data):
    """Attempt to unmarshal a body frame

    :param bytes frame_data: Raw frame data to assign to our body frame
    :return tuple: Amount of data consumed and the frame object

    """
    content_body = body.ContentBody()
    content_body.unmarshal(frame_data)
    return content_body
示例#4
0
    def _create_content_body(body):
        """Split body based on the maximum frame size.

            This function is based on code from Rabbitpy.
            https://github.com/gmr/rabbitpy

        :param str body:
        :rtype: collections.Iterable
        """
        frames = int(math.ceil(len(body) / float(FRAME_MAX)))
        for offset in compatibility.RANGE(0, frames):
            start_frame = FRAME_MAX * offset
            end_frame = start_frame + FRAME_MAX
            if end_frame > len(body):
                end_frame = len(body)
            yield pamqp_body.ContentBody(body[start_frame:end_frame])
示例#5
0
    def publish(self, exchange, routing_key='', mandatory=False):
        """Publish the message to the exchange with the specified routing
        key.

        :param exchange: The exchange to publish the message to
        :type exchange: str or :class:`rabbitpy.Exchange`
        :param str routing_key: The routing key to use
        :param bool mandatory: Requires the message is published
        :return: bool or None
        :raises: rabbitpy.exceptions.MessageReturnedException

        """
        if isinstance(exchange, base.AMQPClass):
            exchange = exchange.name
        method_frame = specification.Basic.Publish(exchange=exchange,
                                                   routing_key=routing_key
                                                   or '',
                                                   mandatory=mandatory)
        self.channel._write_frame(method_frame)
        header_frame = header.ContentHeader(body_size=len(self.body),
                                            properties=self._properties)
        self.channel._write_frame(header_frame)

        if PYTHON3 and isinstance(self.body, str):
            self.body = bytes(self.body.encode('UTF-8'))

        pieces = int(
            math.ceil(len(self.body) / float(self.channel.maximum_frame_size)))

        # Send the message
        for offset in range(0, pieces):
            start = self.channel.maximum_frame_size * offset
            end = start + self.channel.maximum_frame_size
            if end > len(self.body):
                end = len(self.body)
            self.channel._write_frame(body.ContentBody(self.body[start:end]))

        # If publisher confirmations are enabled, wait for the response
        if self.channel.publisher_confirms:
            response = self.channel._wait_for_confirmation()
            if isinstance(response, specification.Basic.Ack):
                return True
            elif isinstance(response, specification.Basic.Nack):
                return False
            else:
                raise exceptions.UnexpectedResponseError(response)
示例#6
0
    def _create_content_body(self, body):
        """Split body based on the maximum frame size.

            This function is based on code from Rabbitpy.
            https://github.com/gmr/rabbitpy

        :param bytes,str,unicode body: Message payload

        :rtype: collections.Iterable
        """
        frames = int(math.ceil(len(body) / float(self._max_frame_size)))
        for offset in compatibility.RANGE(0, frames):
            start_frame = self._max_frame_size * offset
            end_frame = start_frame + self._max_frame_size
            body_len = len(body)
            if end_frame > body_len:
                end_frame = body_len
            yield pamqp_body.ContentBody(body[start_frame:end_frame])
示例#7
0
    def setUp(self) -> None:
        self.exchange = str(uuid.uuid4())
        self.routing_key = str(uuid.uuid4())
        self.app_id = str(uuid.uuid4())
        self.content_encoding = str(uuid.uuid4())
        self.content_type = str(uuid.uuid4())
        self.correlation_id = str(uuid.uuid4())
        self.delivery_mode = random.randint(1, 2)
        self.expiration = str(int(time.time()) + random.randint(60, 300))
        self.headers = {str(uuid.uuid4()): str(uuid.uuid4())}
        self.message_id = str(uuid.uuid4())
        self.message_type = str(uuid.uuid4())
        self.priority = random.randint(0, 255)
        self.reply_to = str(uuid.uuid4())
        self.timestamp = datetime.datetime.now()
        self.user_id = str(uuid.uuid4())
        self.body = b'-'.join([
            str(uuid.uuid4()).encode('latin-1')
            for _offset in range(0, random.randint(1, 100))
        ])

        self.message = message.Message(self.get_method())
        self.message.header = header.ContentHeader(
            0, len(self.body),
            commands.Basic.Properties(app_id=self.app_id,
                                      content_encoding=self.content_encoding,
                                      content_type=self.content_type,
                                      correlation_id=self.correlation_id,
                                      delivery_mode=self.delivery_mode,
                                      expiration=self.expiration,
                                      headers=self.headers,
                                      message_id=self.message_id,
                                      message_type=self.message_type,
                                      priority=self.priority,
                                      reply_to=self.reply_to,
                                      timestamp=self.timestamp,
                                      user_id=self.user_id))

        value = bytes(self.body)
        while value:
            self.message.body_frames.append(
                body.ContentBody(value[:constants.FRAME_MAX_SIZE]))
            value = value[constants.FRAME_MAX_SIZE:]
示例#8
0
 def test_content_body(self):
     value = str(uuid.uuid4()).encode('utf-8')
     expectation = b'\x03\x00\x01\x00\x00\x00$' + value + b'\xce'
     self.assertEqual(frame.marshal(body.ContentBody(value), 1),
                      expectation)
示例#9
0
文件: frame.py 项目: michael-k/pamqp
def _unmarshal_body_frame(frame_data: bytes) -> body.ContentBody:
    """Attempt to unmarshal a body frame"""
    content_body = body.ContentBody(b'')
    content_body.unmarshal(frame_data)
    return content_body