diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/CHANGELOG.md b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/CHANGELOG.md index f1e036a609f2e..a8b1d1e6a9b93 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/CHANGELOG.md +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.4 +--- + + * Add `AddFifoStampMiddleware` to help adding `AmazonSqsFifoStamp` + 6.1 --- diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/MessageDeduplicationAwareInterface.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/MessageDeduplicationAwareInterface.php new file mode 100644 index 0000000000000..1df44f2c0cb24 --- /dev/null +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/MessageDeduplicationAwareInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Bridge\AmazonSqs; + +/** + * @see https://docs.aws.amazon.com/en_gb/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagededuplicationid-property.html + */ +interface MessageDeduplicationAwareInterface +{ + /** + * The max length of MessageDeduplicationId is 128 characters. + * Valid values: alphanumeric characters and punctuation (!"#$%&'()*+,-./:;<=>?@[]^_`{|}~). + */ + public function getMessageDeduplicationId(): ?string; +} diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/MessageGroupAwareInterface.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/MessageGroupAwareInterface.php new file mode 100644 index 0000000000000..1d716214430e6 --- /dev/null +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/MessageGroupAwareInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Bridge\AmazonSqs; + +/** + * @see https://docs.aws.amazon.com/en_gb/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html + */ +interface MessageGroupAwareInterface +{ + /** + * The max length of MessageGroupId is 128 characters. + * Valid values: alphanumeric characters and punctuation (!"#$%&'()*+,-./:;<=>?@[]^_`{|}~). + */ + public function getMessageGroupId(): ?string; +} diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Middleware/AddFifoStampMiddleware.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Middleware/AddFifoStampMiddleware.php new file mode 100644 index 0000000000000..126596fa34be8 --- /dev/null +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Middleware/AddFifoStampMiddleware.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Bridge\AmazonSqs\Middleware; + +use Symfony\Component\Messenger\Bridge\AmazonSqs\MessageDeduplicationAwareInterface; +use Symfony\Component\Messenger\Bridge\AmazonSqs\MessageGroupAwareInterface; +use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFifoStamp; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Middleware\MiddlewareInterface; +use Symfony\Component\Messenger\Middleware\StackInterface; + +final class AddFifoStampMiddleware implements MiddlewareInterface +{ + public function handle(Envelope $envelope, StackInterface $stack): Envelope + { + $message = $envelope->getMessage(); + $messageGroupId = null; + $messageDeduplicationId = null; + + if ($message instanceof MessageGroupAwareInterface) { + $messageGroupId = $message->getMessageGroupId(); + } + if ($message instanceof MessageDeduplicationAwareInterface) { + $messageDeduplicationId = $message->getMessageDeduplicationId(); + } + + if (null !== $messageGroupId || null !== $messageDeduplicationId) { + $envelope = $envelope->with(new AmazonSqsFifoStamp($messageGroupId, $messageDeduplicationId)); + } + + return $stack->next()->handle($envelope, $stack); + } +} diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Middleware/AddFifoStampTest.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Middleware/AddFifoStampTest.php new file mode 100644 index 0000000000000..5a946743d34de --- /dev/null +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Middleware/AddFifoStampTest.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Bridge\AmazonSqs\Tests\Middleware; + +use Symfony\Component\Messenger\Bridge\AmazonSqs\MessageDeduplicationAwareInterface; +use Symfony\Component\Messenger\Bridge\AmazonSqs\MessageGroupAwareInterface; +use Symfony\Component\Messenger\Bridge\AmazonSqs\Middleware\AddFifoStampMiddleware; +use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFifoStamp; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase; + +class AddFifoStampTest extends MiddlewareTestCase +{ + public function testAddStampWithGroupIdOnly() + { + $middleware = new AddFifoStampMiddleware(); + $envelope = new Envelope(new WithMessageGroupIdMessage('groupId')); + $finalEnvelope = $middleware->handle($envelope, $this->getStackMock()); + $stamp = $finalEnvelope->last(AmazonSqsFifoStamp::class); + $this->assertInstanceOf(AmazonSqsFifoStamp::class, $stamp); + $this->assertSame('groupId', $stamp->getMessageGroupId()); + $this->assertNull($stamp->getMessageDeduplicationId()); + } + + public function testHandleWithDeduplicationIdOnly() + { + $middleware = new AddFifoStampMiddleware(); + $envelope = new Envelope(new WithMessageDeduplicationIdMessage('deduplicationId')); + $finalEnvelope = $middleware->handle($envelope, $this->getStackMock()); + $stamp = $finalEnvelope->last(AmazonSqsFifoStamp::class); + $this->assertInstanceOf(AmazonSqsFifoStamp::class, $stamp); + $this->assertSame('deduplicationId', $stamp->getMessageDeduplicationId()); + $this->assertNull($stamp->getMessageGroupId()); + } + + public function testHandleWithGroupIdAndDeduplicationId() + { + $middleware = new AddFifoStampMiddleware(); + $envelope = new Envelope(new WithMessageDeduplicationIdAndMessageGroupIdMessage('my_group', 'my_random_id')); + $finalEnvelope = $middleware->handle($envelope, $this->getStackMock()); + $stamp = $finalEnvelope->last(AmazonSqsFifoStamp::class); + $this->assertInstanceOf(AmazonSqsFifoStamp::class, $stamp); + $this->assertSame('my_random_id', $stamp->getMessageDeduplicationId()); + $this->assertSame('my_group', $stamp->getMessageGroupId()); + } + + public function testHandleWithoutId() + { + $middleware = new AddFifoStampMiddleware(); + $envelope = new Envelope(new WithoutIdMessage()); + $finalEnvelope = $middleware->handle($envelope, $this->getStackMock()); + $stamp = $finalEnvelope->last(AmazonSqsFifoStamp::class); + $this->assertNull($stamp); + } +} + +class WithMessageDeduplicationIdAndMessageGroupIdMessage implements MessageDeduplicationAwareInterface, MessageGroupAwareInterface +{ + public function __construct( + private string $messageGroupId, + private string $messageDeduplicationId, + ) { + } + + public function getMessageDeduplicationId(): ?string + { + return $this->messageDeduplicationId; + } + + public function getMessageGroupId(): ?string + { + return $this->messageGroupId; + } +} + +class WithMessageDeduplicationIdMessage implements MessageDeduplicationAwareInterface +{ + public function __construct( + private string $messageDeduplicationId, + ) { + } + + public function getMessageDeduplicationId(): ?string + { + return $this->messageDeduplicationId; + } +} + +class WithMessageGroupIdMessage implements MessageGroupAwareInterface +{ + public function __construct( + private string $messageGroupId, + ) { + } + + public function getMessageGroupId(): ?string + { + return $this->messageGroupId; + } +} +class WithoutIdMessage +{ +}