8000 feature #48095 [Messenger] [Sqs] Add `AddFifoStamp` middleware (tyx) · symfony/symfony@e942c1c · GitHub
[go: up one dir, main page]

Skip to content

Commit e942c1c

Browse files
feature #48095 [Messenger] [Sqs] Add AddFifoStamp middleware (tyx)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [Messenger] [Sqs] Add `AddFifoStamp` middleware | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | yes | Deprecations? |no | License | MIT | Doc PR | on my way Currently it is not very easy to use fifo stamp as you need to go down to the envelope when you often handle only message in your app. We also think that the message should be responsible to choose its own groupId. So we come with this very simple middleware and 2 interfaces. We use it in our own system since 3 months. It allows to keep messenger concept outside our messages while continuing to benefit from it. ## Example To group message by user for example ### Current ```php class SmsNotification { public function __construct(private string $userId) {} } //.... $bus->dispatch(new SmsNotification($userId), [ new AmazonSqsFifoStamp($userId) ]); ``` ### After ```php class SmsNotification implements WithMessageGroupId { public function __construct(private string $userId) {} public function messageGroupId() { return $this->userId; } } //.... $bus->dispatch(new SmsNotification($userId)); ``` ## Usage It can be enabled with this kind of config ```yaml # config/packages/messenger.yaml framework: messenger: buses: event_bus: default_middleware: allow_no_handlers: true middleware: - 'Symfony\Component\Messenger\Bridge\AmazonSqs\Middleware\AddFifoStampMiddleware' ``` Commits ------- c424da4 [Messenger] [Sqs] Add `AddFifoStamp` middleware
2 parents 6319e5d + c424da4 commit e942c1c

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed

src/Symfony/Component/Messenger/Bridge/AmazonSqs/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.4
5+
---
6+
7+
* Add `AddFifoStampMiddleware` to help adding `AmazonSqsFifoStamp`
8+
49
6.1
510
---
611

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Bridge\AmazonSqs;
13+
14+
/**
15+
* @see https://docs.aws.amazon.com/en_gb/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagededuplicationid-property.html
16+
*/
17+
interface MessageDeduplicationAwareInterface
18+
{
19+
/**
20+
* The max length of MessageDeduplicationId is 128 characters.
21+
* Valid values: alphanumeric characters and punctuation (!"#$%&'()*+,-./:;<=>?@[]^_`{|}~).
22+
*/
23+
public function getMessageDeduplicationId(): ?string;
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Bridge\AmazonSqs;
13+
14+
/**
15+
* @see https://docs.aws.amazon.com/en_gb/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html
16+
*/
17+
interface MessageGroupAwareInterface
18+
{
19+
/**
20+
* The max length of MessageGroupId is 128 characters.
21+
* Valid values: alphanumeric characters and punctuation (!"#$%&'()*+,-./:;<=>?@[]^_`{|}~).
22+
*/
23+
public function getMessageGroupId(): ?string;
24+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Bridge\AmazonSqs\Middleware;
13+
14+
use Symfony\Component\Messenger\Bridge\AmazonSqs\MessageDeduplicationAwareInterface;
15+
use Symfony\Component\Messenger\Bridge\AmazonSqs\MessageGroupAwareInterface;
16+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFifoStamp;
17+
use Symfony\Component\Messenger\Envelope;
18+
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
19+
use Symfony\Component\Messenger\Middleware\StackInterface;
20+
21+
final class AddFifoStampMiddleware implements MiddlewareInterface
22+
{
23+
public function handle(Envelope $envelope, StackInterface $stack): Envelope
24+
{
25+
$message = $envelope->getMessage();
26+
$messageGroupId = null;
27+
$messageDeduplicationId = null;
28+
29+
if ($message instanceof MessageGroupAwareInterface) {
30+
$messageGroupId = $message->getMessageGroupId();
31+
}
32+
if ($message instanceof MessageDeduplicationAwareInterface) {
33+
$messageDeduplicationId = $message->getMessageDeduplicationId();
34+
}
35+
36+
if (null !== $messageGroupId || null !== $messageDeduplicationId) {
37+
$envelope = $envelope->with(new AmazonSqsFifoStamp($messageGroupId, $messageDeduplicationId));
38+
}
39+
40+
return $stack->next()->handle($envelope, $stack);
41+
}
42+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Bridge\AmazonSqs\Tests\Middleware;
13+
14+
use Symfony\Component\Messenger\Bridge\AmazonSqs\MessageDeduplicationAwareInterface;
15+
use Symfony\Component\Messenger\Bridge\AmazonSqs\MessageGroupAwareInterface;
16+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Middleware\AddFifoStampMiddleware;
17+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFifoStamp;
18+
use Symfony\Component\Messenger\Envelope;
19+
use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase;
20+
21+
class AddFifoStampTest extends MiddlewareTestCase
22+
{
23+
public function testAddStampWithGroupIdOnly()
24+
{
25+
$middleware = new AddFifoStampMiddleware();
26+
$envelope = new Envelope(new WithMessageGroupIdMessage('groupId'));
27+
$finalEnvelope = $middleware->handle($envelope, $this->getStackMock());
28+
$stamp = $finalEnvelope->last(AmazonSqsFifoStamp::class);
29+
$this->assertInstanceOf(AmazonSqsFifoStamp::class, $stamp);
30+
$this->assertSame('groupId', $stamp->getMessageGroupId());
31+
$this->assertNull($stamp->getMessageDeduplicationId());
32+
}
33+
34+
public function testHandleWithDeduplicationIdOnly()
35+
{
36+
$middleware = new AddFifoStampMiddleware();
37+
$envelope = new Envelope(new WithMessageDeduplicationIdMessage('deduplicationId'));
38+
$finalEnvelope = $middleware->handle($envelope, $this->getStackMock());
39+
$stamp = $finalEnvelope->last(AmazonSqsFifoStamp::class);
40+
$this->assertInstanceOf(AmazonSqsFifoStamp::class, $stamp);
41+
$this->assertSame('deduplicationId', $stamp->getMessageDeduplicationId());
42+
$this->assertNull($stamp->getMessageGroupId());
43+
}
44+
45+
public function testHandleWithGroupIdAndDeduplicationId()
46+
{
47+
$middleware = new AddFifoStampMiddleware();
48+
$envelope = new Envelope(new WithMessageDeduplicationIdAndMessageGroupIdMessage('my_group', 'my_random_id'));
49+
$finalEnvelope = $middleware->handle($envelope, $this->getStackMock());
50+
$stamp = $finalEnvelope->last(AmazonSqsFifoStamp::class);
51+
$this->assertInstanceOf(AmazonSqsFifoStamp::class, $stamp);
52+
$this->assertSame('my_random_id', $stamp->getMessageDeduplicationId());
53+
$this->assertSame('my_group', $stamp->getMessageGroupId());
54+
}
55+
56+
public function testHandleWithoutId()
57+
{
58+
$middleware = new AddFifoStampMiddleware();
59+
$envelope = new Envelope(new WithoutIdMessage());
60+
$finalEnvelope = $middleware->handle($envelope, $this->getStackMock());
61+
$stamp = $finalEnvelope->last(AmazonSqsFifoStamp::class);
62+
$this->assertNull($stamp);
63+
}
64+
}
65+
66+
class WithMessageDeduplicationIdAndMessageGroupIdMessage implements MessageDeduplicationAwareInterface, MessageGroupAwareInterface
67+
{
68+
public function __construct(
69+
private string $messageGroupId,
70+
private string $messageDeduplicationId,
71+
) {
72+
}
73+
74+
public function getMessageDeduplicationId(): ?string
75+
{
76+
return $this->messageDeduplicationId;
77+
}
78+
79+
public function getMessageGroupId(): ?string
80+
{
81+
return $this->messageGroupId;
82+
}
83+
}
84+
85+
class WithMessageDeduplicationIdMessage implements MessageDeduplicationAwareInterface
86+
{
87+
public function __construct(
88+
private string $messageDeduplicationId,
89+
) {
90+
}
91+
92+
public function getMessageDeduplicationId(): ?string
93+
{
94+
return $this->messageDeduplicationId;
95+
}
96+
}
97+
98+
class WithMessageGroupIdMessage implements MessageGroupAwareInterface
99+
{
100+
public function __construct(
101+
private string $messageGroupId,
102+
) {
103+
}
104+
105+
public function getMessageGroupId(): ?string
106+
{
107+
return $this->messageGroupId;
108+
}
109+
}
110+
class WithoutIdMessage
111+
{
112+
}

0 commit comments

Comments
 (0)
0