From 6a5e2b5531ba69075018af7968815d59c59470f1 Mon Sep 17 00:00:00 2001 From: Ian Jenkins Date: Mon, 24 Oct 2022 15:24:54 +0100 Subject: [PATCH] [Messenger][AMQP] Add routing key to data passed to serializer decode. It's often useful to have the routing key available when decoding messages from AMQP. For example, sometimes the routing key contains meta information required for the processing of the message. This introduces an `extra` element which currently only contains the routing key, but there is scope to add other meta information from \AMQPEnvelope such as the exchange name for example. Fixes #43039 --- .../Amqp/Tests/Transport/AmqpReceiverTest.php | 22 +++++++++++++++++++ .../Tests/Transport/AmqpTransportTest.php | 3 ++- .../Bridge/Amqp/Transport/AmqpReceiver.php | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpReceiverTest.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpReceiverTest.php index 9dd86dcd07b42..fd26450a4d30f 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpReceiverTest.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpReceiverTest.php @@ -74,6 +74,27 @@ public function testItThrowsATransportExceptionIfItCannotRejectMessage() $receiver->reject(new Envelope(new \stdClass(), [new AmqpReceivedStamp($amqpEnvelope, 'queueName')])); } + public function testItPassesExpectedDataToSerializerDecode() + { + $amqpEnvelope = $this->createAMQPEnvelope(); + + $connection = $this->createMock(Connection::class); + $connection->method('getQueueNames')->willReturn(['queueName']); + $connection->method('get')->with('queueName')->willReturn($amqpEnvelope); + + $serializer = $this->createMock(SerializerInterface::class); + $serializer->expects($this->once())->method('decode')->with($this->equalTo([ + 'body' => $amqpEnvelope->getBody(), + 'headers' => $amqpEnvelope->getHeaders(), + 'extra' => [ + 'routingKey' => $amqpEnvelope->getRoutingKey(), + ], + ]))->willReturn(new Envelope(new DummyMessage('Hi'))); + + $receiver = new AmqpReceiver($connection, $serializer); + iterator_to_array($receiver->get()); + } + private function createAMQPEnvelope(): \AMQPEnvelope { $envelope = $this->createMock(\AMQPEnvelope::class); @@ -81,6 +102,7 @@ private function createAMQPEnvelope(): \AMQPEnvelope $envelope->method('getHeaders')->willReturn([ 'type' => DummyMessage::class, ]); + $envelope->method('getRoutingKey')->willReturn('Dummy_RoutingKey'); return $envelope; } diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpTransportTest.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpTransportTest.php index 433aeebdfe5d5..b3ef139038dd6 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpTransportTest.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpTransportTest.php @@ -43,8 +43,9 @@ public function testReceivesMessages() $amqpEnvelope = $this->createMock(\AMQPEnvelope::class); $amqpEnvelope->method('getBody')->willReturn('body'); $amqpEnvelope->method('getHeaders')->willReturn(['my' => 'header']); + $amqpEnvelope->method('getRoutingKey')->willReturn('routing-key'); - $serializer->method('decode')->with(['body' => 'body', 'headers' => ['my' => 'header']])->willReturn(new Envelope($decodedMessage)); + $serializer->method('decode')->with(['body' => 'body', 'headers' => ['my' => 'header'], 'extra' => ['routingKey' => 'routing-key']])->willReturn(new Envelope($decodedMessage)); $connection->method('getQueueNames')->willReturn(['queueName']); $connection->method('get')->with('queueName')->willReturn($amqpEnvelope); diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceiver.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceiver.php index fecf39b29afc3..e4e250fcf4d82 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceiver.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceiver.php @@ -66,6 +66,9 @@ private function getEnvelope(string $queueName): iterable $envelope = $this->serializer->decode([ 'body' => false === $body ? '' : $body, // workaround https://github.com/pdezwart/php-amqp/issues/351 'headers' => $amqpEnvelope->getHeaders(), + 'extra' => [ + 'routingKey' => $amqpEnvelope->getRoutingKey(), + ], ]); } catch (MessageDecodingFailedException $exception) { // invalid message of some type