Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fb249f0

Browse files
committed
feature #29159 [Messenger] collect all stamps added on Envelope as collections (nicolas-grekas)
This PR was merged into the 4.2-dev branch. Discussion ---------- [Messenger] collect all stamps added on Envelope as collections | Q | A | ------------- | --- | Branch? | 4.2 | Bug fix? | no | New feature? | yes | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | #29156 | License | MIT | Doc PR | - Late small BC break for Messenger: * `Envelope::all()` takes a new optional `$stampFqcn` argument and returns the stamps for the specified FQCN, or all stamps by their class name * `Envelope::get()` has been renamed `Envelope::last()` This fixes the current behavior where we replace any previous stamp with the same type, which is unexpected to me as it silently loses data and more importantly blocks interesting use cases we're going to need in the near future. Basically, that's the same as HTTP headers being allowed to exist several times: most of them make no sense as collections, but some are really useful as collections. Commits ------- 2e98859 [Messenger] collect all stamps added on Envelope as collections
2 parents e947043 + 2e98859 commit fb249f0

File tree

9 files changed

+43
-44
lines changed

9 files changed

+43
-44
lines changed

src/Symfony/Component/Messenger/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ CHANGELOG
3333
* `ActivationMiddlewareDecorator` has been renamed `ActivationMiddleware`
3434
* `AllowNoHandlerMiddleware` has been removed in favor of a new constructor argument on `HandleMessageMiddleware`
3535
* The `ContainerHandlerLocator`, `AbstractHandlerLocator`, `SenderLocator` and `AbstractSenderLocator` classes have been removed
36+
* `Envelope::all()` takes a new optional `$stampFqcn` argument and returns the stamps for the specified FQCN, or all stamps by their class name
37+
* `Envelope::get()` has been renamed `Envelope::last()`
3638

3739
4.1.0
3840
-----

src/Symfony/Component/Messenger/Envelope.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function __construct($message, StampInterface ...$stamps)
3636
$this->message = $message;
3737

3838
foreach ($stamps as $stamp) {
39-
$this->stamps[\get_class($stamp)] = $stamp;
39+
$this->stamps[\get_class($stamp)][] = $stamp;
4040
}
4141
}
4242

@@ -48,22 +48,26 @@ public function with(StampInterface ...$stamps): self
4848
$cloned = clone $this;
4949

5050
foreach ($stamps as $stamp) {
51-
$cloned->stamps[\get_class($stamp)] = $stamp;
51+
$cloned->stamps[\get_class($stamp)][] = $stamp;
5252
}
5353

5454
return $cloned;
5555
}
5656

57-
public function get(string $stampFqcn): ?StampInterface
57+
public function last(string $stampFqcn): ?StampInterface
5858
{
59-
return $this->stamps[$stampFqcn] ?? null;
59+
return isset($this->stamps[$stampFqcn]) ? end($this->stamps[$stampFqcn]) : null;
6060
}
6161

6262
/**
63-
* @return StampInterface[] indexed by fqcn
63+
* @return StampInterface[]|StampInterface[][] The stamps for the specified FQCN, or all stamps by their class name
6464
*/
65-
public function all(): array
65+
public function all(string $stampFqcn = null): array
6666
{
67+
if (null !== $stampFqcn) {
68+
return $this->stamps[$stampFqcn] ?? array();
69+
}
70+
6771
return $this->stamps;
6872
}
6973

src/Symfony/Component/Messenger/Middleware/SendMessageMiddleware.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function __construct(SendersLocatorInterface $sendersLocator)
3535
*/
3636
public function handle(Envelope $envelope, StackInterface $stack): Envelope
3737
{
38-
if ($envelope->get(ReceivedStamp::class)) {
38+
if ($envelope->all(ReceivedStamp::class)) {
3939
// it's a received message, do not send it back
4040
return $stack->next()->handle($envelope, $stack);
4141
}

src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
3838
$message = $envelope->getMessage();
3939
$groups = null;
4040
/** @var ValidationStamp|null $validationStamp */
41-
if ($validationStamp = $envelope->get(ValidationStamp::class)) {
41+
if ($validationStamp = $envelope->last(ValidationStamp::class)) {
4242
$groups = $validationStamp->getGroups();
4343
}
4444

src/Symfony/Component/Messenger/Tests/EnvelopeTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function testConstruct()
2929

3030
$this->assertSame($dummy, $envelope->getMessage());
3131
$this->assertArrayHasKey(ReceivedStamp::class, $stamps = $envelope->all());
32-
$this->assertSame($receivedStamp, $stamps[ReceivedStamp::class]);
32+
$this->assertSame($receivedStamp, $stamps[ReceivedStamp::class][0]);
3333
}
3434

3535
public function testWithReturnsNewInstance()
@@ -39,13 +39,13 @@ public function testWithReturnsNewInstance()
3939
$this->assertNotSame($envelope, $envelope->with(new ReceivedStamp()));
4040
}
4141

42-
public function testGet()
42+
public function testGetLast()
4343
{
4444
$receivedStamp = new ReceivedStamp();
4545
$envelope = new Envelope($dummy = new DummyMessage('dummy'), $receivedStamp);
4646

47-
$this->assertSame($receivedStamp, $envelope->get(ReceivedStamp::class));
48-
$this->assertNull($envelope->get(ValidationStamp::class));
47+
$this->assertSame($receivedStamp, $envelope->last(ReceivedStamp::class));
48+
$this->assertNull($envelope->last(ValidationStamp::class));
4949
}
5050

5151
public function testAll()
@@ -57,8 +57,8 @@ public function testAll()
5757

5858
$stamps = $envelope->all();
5959
$this->assertArrayHasKey(ReceivedStamp::class, $stamps);
60-
$this->assertSame($receivedStamp, $stamps[ReceivedStamp::class]);
60+
$this->assertSame($receivedStamp, $stamps[ReceivedStamp::class][0]);
6161
$this->assertArrayHasKey(ValidationStamp::class, $stamps);
62-
$this->assertSame($validationStamp, $stamps[ValidationStamp::class]);
62+
$this->assertSame($validationStamp, $stamps[ValidationStamp::class][0]);
6363
}
6464
}

src/Symfony/Component/Messenger/Tests/TraceableMessageBusTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function testItTracesDispatchWithEnvelope()
5656
$this->assertCount(1, $tracedMessages = $traceableBus->getDispatchedMessages());
5757
$this->assertArraySubset(array(
5858
'message' => $message,
59-
'stamps' => array($stamp),
59+
'stamps' => array(array($stamp)),
6060
'caller' => array(
6161
'name' => 'TraceableMessageBusTest.php',
6262
'file' => __FILE__,

src/Symfony/Component/Messenger/Tests/Transport/Serialization/SerializerTest.php

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,13 @@
1818
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
1919
use Symfony\Component\Messenger\Transport\Serialization\Serializer;
2020
use Symfony\Component\Serializer as SerializerComponent;
21-
use Symfony\Component\Serializer\Encoder\JsonEncoder;
2221
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
2322

2423
class SerializerTest extends TestCase
2524
{
2625
public function testEncodedIsDecodable()
2726
{
28-
$serializer = new Serializer(
29-
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder()))
30-
);
27+
$serializer = new Serializer();
3128

3229
$envelope = new Envelope(new DummyMessage('Hello'));
3330

@@ -36,9 +33,7 @@ public function testEncodedIsDecodable()
3633

3734
public function testEncodedWithStampsIsDecodable()
3835
{
39-
$serializer = new Serializer(
40-
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder()))
41-
);
36+
$serializer = new Serializer();
4237

4338
$envelope = (new Envelope(new DummyMessage('Hello')))
4439
->with(new SerializerStamp(array(ObjectNormalizer::GROUPS => array('foo'))))
@@ -50,9 +45,7 @@ public function testEncodedWithStampsIsDecodable()
5045

5146
public function testEncodedIsHavingTheBodyAndTypeHeader()
5247
{
53-
$serializer = new Serializer(
54-
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder()))
55-
);
48+
$serializer = new Serializer();
5649

5750
$encoded = $serializer->encode(new Envelope(new DummyMessage('Hello')));
5851

@@ -81,11 +74,7 @@ public function testUsesTheCustomFormatAndContext()
8174

8275
public function testEncodedWithSymfonySerializerForStamps()
8376
{
84-
$serializer = new Serializer(
85-
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder())),
86-
'json',
87-
array()
88-
);
77+
$serializer = new Serializer();
8978

9079
$envelope = (new Envelope(new DummyMessage('Hello')))
9180
->with($serializerStamp = new SerializerStamp(array(ObjectNormalizer::GROUPS => array('foo'))))
@@ -102,7 +91,7 @@ public function testEncodedWithSymfonySerializerForStamps()
10291

10392
$decoded = $serializer->decode($encoded);
10493

105-
$this->assertEquals($serializerStamp, $decoded->get(SerializerStamp::class));
106-
$this->assertEquals($validationStamp, $decoded->get(ValidationStamp::class));
94+
$this->assertEquals($serializerStamp, $decoded->last(SerializerStamp::class));
95+
$this->assertEquals($validationStamp, $decoded->last(ValidationStamp::class));
10796
}
10897
}

src/Symfony/Component/Messenger/Tests/WorkerTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ public function testWorkerDispatchTheReceivedMessage()
4242

4343
public function testWorkerDoesNotWrapMessagesAlreadyWrappedWithReceivedMessage()
4444
{
45-
$envelope = (new Envelope(new DummyMessage('API')))->with(new ReceivedStamp());
45+
$envelope = new Envelope(new DummyMessage('API'));
4646
$receiver = new CallbackReceiver(function ($handler) use ($envelope) {
4747
$handler($envelope);
4848
});
49+
$envelope = $envelope->with(new ReceivedStamp());
4950

5051
$bus = $this->getMockBuilder(MessageBusInterface::class)->getMock();
5152
$bus->expects($this->at(0))->method('dispatch')->with($envelope)->willReturn($envelope);

src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Messenger\Stamp\SerializerStamp;
1818
use Symfony\Component\Serializer\Encoder\JsonEncoder;
1919
use Symfony\Component\Serializer\Encoder\XmlEncoder;
20+
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
2021
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
2122
use Symfony\Component\Serializer\Serializer as SymfonySerializer;
2223
use Symfony\Component\Serializer\SerializerInterface as SymfonySerializerInterface;
@@ -34,9 +35,9 @@ class Serializer implements SerializerInterface
3435
private $format;
3536
private $context;
3637

37-
public function __construct(SymfonySerializerInterface $serializer, string $format = 'json', array $context = array())
38+
public function __construct(SymfonySerializerInterface $serializer = null, string $format = 'json', array $context = array())
3839
{
39-
$this->serializer = $serializer;
40+
$this->serializer = $serializer ?? self::create()->serializer;
4041
$this->format = $format;
4142
$this->context = $context;
4243
}
@@ -48,7 +49,7 @@ public static function create(): self
4849
}
4950

5051
$encoders = array(new XmlEncoder(), new JsonEncoder());
51-
$normalizers = array(new ObjectNormalizer());
52+
$normalizers = array(new ArrayDenormalizer(), new ObjectNormalizer());
5253
$serializer = new SymfonySerializer($normalizers, $encoders);
5354

5455
return new self($serializer);
@@ -70,9 +71,8 @@ public function decode(array $encodedEnvelope): Envelope
7071
$stamps = $this->decodeStamps($encodedEnvelope);
7172

7273
$context = $this->context;
73-
/** @var SerializerStamp|null $serializerStamp */
74-
if ($serializerStamp = $stamps[SerializerStamp::class] ?? null) {
75-
$context = $serializerStamp->getContext() + $context;
74+
if (isset($stamps[SerializerStamp::class])) {
75+
$context = end($stamps[SerializerStamp::class])->getContext() + $context;
7676
}
7777

7878
$message = $this->serializer->deserialize($encodedEnvelope['body'], $encodedEnvelope['headers']['type'], $this->format, $context);
@@ -87,7 +87,7 @@ public function encode(Envelope $envelope): array
8787
{
8888
$context = $this->context;
8989
/** @var SerializerStamp|null $serializerStamp */
90-
if ($serializerStamp = $envelope->get(SerializerStamp::class)) {
90+
if ($serializerStamp = $envelope->last(SerializerStamp::class)) {
9191
$context = $serializerStamp->getContext() + $context;
9292
}
9393

@@ -107,21 +107,24 @@ private function decodeStamps(array $encodedEnvelope): array
107107
continue;
108108
}
109109

110-
$stamps[] = $this->serializer->deserialize($value, substr($name, \strlen(self::STAMP_HEADER_PREFIX)), $this->format, $this->context);
110+
$stamps[] = $this->serializer->deserialize($value, substr($name, \strlen(self::STAMP_HEADER_PREFIX)).'[]', $this->format, $this->context);
111+
}
112+
if ($stamps) {
113+
$stamps = array_merge(...$stamps);
111114
}
112115

113116
return $stamps;
114117
}
115118

116119
private function encodeStamps(Envelope $envelope): array
117120
{
118-
if (!$stamps = $envelope->all()) {
121+
if (!$allStamps = $envelope->all()) {
119122
return array();
120123
}
121124

122125
$headers = array();
123-
foreach ($stamps as $stamp) {
124-
$headers[self::STAMP_HEADER_PREFIX.\get_class($stamp)] = $this->serializer->serialize($stamp, $this->format, $this->context);
126+
foreach ($allStamps as $class => $stamps) {
127+
$headers[self::STAMP_HEADER_PREFIX.$class] = $this->serializer->serialize($stamps, $this->format, $this->context);
125128
}
126129

127130
return $headers;

0 commit comments

Comments
 (0)