[Messenger] collect all stamps added on Envelope as collections

This commit is contained in:
Nicolas Grekas 2018-11-09 17:32:17 +01:00
parent 99856a9b08
commit 2e9885922a
9 changed files with 43 additions and 44 deletions

View File

@ -33,6 +33,8 @@ CHANGELOG
* `ActivationMiddlewareDecorator` has been renamed `ActivationMiddleware`
* `AllowNoHandlerMiddleware` has been removed in favor of a new constructor argument on `HandleMessageMiddleware`
* The `ContainerHandlerLocator`, `AbstractHandlerLocator`, `SenderLocator` and `AbstractSenderLocator` classes have been removed
* `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()`
4.1.0
-----

View File

@ -36,7 +36,7 @@ final class Envelope
$this->message = $message;
foreach ($stamps as $stamp) {
$this->stamps[\get_class($stamp)] = $stamp;
$this->stamps[\get_class($stamp)][] = $stamp;
}
}
@ -48,22 +48,26 @@ final class Envelope
$cloned = clone $this;
foreach ($stamps as $stamp) {
$cloned->stamps[\get_class($stamp)] = $stamp;
$cloned->stamps[\get_class($stamp)][] = $stamp;
}
return $cloned;
}
public function get(string $stampFqcn): ?StampInterface
public function last(string $stampFqcn): ?StampInterface
{
return $this->stamps[$stampFqcn] ?? null;
return isset($this->stamps[$stampFqcn]) ? end($this->stamps[$stampFqcn]) : null;
}
/**
* @return StampInterface[] indexed by fqcn
* @return StampInterface[]|StampInterface[][] The stamps for the specified FQCN, or all stamps by their class name
*/
public function all(): array
public function all(string $stampFqcn = null): array
{
if (null !== $stampFqcn) {
return $this->stamps[$stampFqcn] ?? array();
}
return $this->stamps;
}

View File

@ -35,7 +35,7 @@ class SendMessageMiddleware implements MiddlewareInterface
*/
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
if ($envelope->get(ReceivedStamp::class)) {
if ($envelope->all(ReceivedStamp::class)) {
// it's a received message, do not send it back
return $stack->next()->handle($envelope, $stack);
}

View File

@ -38,7 +38,7 @@ class ValidationMiddleware implements MiddlewareInterface
$message = $envelope->getMessage();
$groups = null;
/** @var ValidationStamp|null $validationStamp */
if ($validationStamp = $envelope->get(ValidationStamp::class)) {
if ($validationStamp = $envelope->last(ValidationStamp::class)) {
$groups = $validationStamp->getGroups();
}

View File

@ -29,7 +29,7 @@ class EnvelopeTest extends TestCase
$this->assertSame($dummy, $envelope->getMessage());
$this->assertArrayHasKey(ReceivedStamp::class, $stamps = $envelope->all());
$this->assertSame($receivedStamp, $stamps[ReceivedStamp::class]);
$this->assertSame($receivedStamp, $stamps[ReceivedStamp::class][0]);
}
public function testWithReturnsNewInstance()
@ -39,13 +39,13 @@ class EnvelopeTest extends TestCase
$this->assertNotSame($envelope, $envelope->with(new ReceivedStamp()));
}
public function testGet()
public function testGetLast()
{
$receivedStamp = new ReceivedStamp();
$envelope = new Envelope($dummy = new DummyMessage('dummy'), $receivedStamp);
$this->assertSame($receivedStamp, $envelope->get(ReceivedStamp::class));
$this->assertNull($envelope->get(ValidationStamp::class));
$this->assertSame($receivedStamp, $envelope->last(ReceivedStamp::class));
$this->assertNull($envelope->last(ValidationStamp::class));
}
public function testAll()
@ -57,8 +57,8 @@ class EnvelopeTest extends TestCase
$stamps = $envelope->all();
$this->assertArrayHasKey(ReceivedStamp::class, $stamps);
$this->assertSame($receivedStamp, $stamps[ReceivedStamp::class]);
$this->assertSame($receivedStamp, $stamps[ReceivedStamp::class][0]);
$this->assertArrayHasKey(ValidationStamp::class, $stamps);
$this->assertSame($validationStamp, $stamps[ValidationStamp::class]);
$this->assertSame($validationStamp, $stamps[ValidationStamp::class][0]);
}
}

View File

@ -56,7 +56,7 @@ class TraceableMessageBusTest extends TestCase
$this->assertCount(1, $tracedMessages = $traceableBus->getDispatchedMessages());
$this->assertArraySubset(array(
'message' => $message,
'stamps' => array($stamp),
'stamps' => array(array($stamp)),
'caller' => array(
'name' => 'TraceableMessageBusTest.php',
'file' => __FILE__,

View File

@ -18,16 +18,13 @@ use Symfony\Component\Messenger\Stamp\ValidationStamp;
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
use Symfony\Component\Messenger\Transport\Serialization\Serializer;
use Symfony\Component\Serializer as SerializerComponent;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
class SerializerTest extends TestCase
{
public function testEncodedIsDecodable()
{
$serializer = new Serializer(
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder()))
);
$serializer = new Serializer();
$envelope = new Envelope(new DummyMessage('Hello'));
@ -36,9 +33,7 @@ class SerializerTest extends TestCase
public function testEncodedWithStampsIsDecodable()
{
$serializer = new Serializer(
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder()))
);
$serializer = new Serializer();
$envelope = (new Envelope(new DummyMessage('Hello')))
->with(new SerializerStamp(array(ObjectNormalizer::GROUPS => array('foo'))))
@ -50,9 +45,7 @@ class SerializerTest extends TestCase
public function testEncodedIsHavingTheBodyAndTypeHeader()
{
$serializer = new Serializer(
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder()))
);
$serializer = new Serializer();
$encoded = $serializer->encode(new Envelope(new DummyMessage('Hello')));
@ -81,11 +74,7 @@ class SerializerTest extends TestCase
public function testEncodedWithSymfonySerializerForStamps()
{
$serializer = new Serializer(
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder())),
'json',
array()
);
$serializer = new Serializer();
$envelope = (new Envelope(new DummyMessage('Hello')))
->with($serializerStamp = new SerializerStamp(array(ObjectNormalizer::GROUPS => array('foo'))))
@ -102,7 +91,7 @@ class SerializerTest extends TestCase
$decoded = $serializer->decode($encoded);
$this->assertEquals($serializerStamp, $decoded->get(SerializerStamp::class));
$this->assertEquals($validationStamp, $decoded->get(ValidationStamp::class));
$this->assertEquals($serializerStamp, $decoded->last(SerializerStamp::class));
$this->assertEquals($validationStamp, $decoded->last(ValidationStamp::class));
}
}

View File

@ -42,10 +42,11 @@ class WorkerTest extends TestCase
public function testWorkerDoesNotWrapMessagesAlreadyWrappedWithReceivedMessage()
{
$envelope = (new Envelope(new DummyMessage('API')))->with(new ReceivedStamp());
$envelope = new Envelope(new DummyMessage('API'));
$receiver = new CallbackReceiver(function ($handler) use ($envelope) {
$handler($envelope);
});
$envelope = $envelope->with(new ReceivedStamp());
$bus = $this->getMockBuilder(MessageBusInterface::class)->getMock();
$bus->expects($this->at(0))->method('dispatch')->with($envelope)->willReturn($envelope);

View File

@ -17,6 +17,7 @@ use Symfony\Component\Messenger\Exception\LogicException;
use Symfony\Component\Messenger\Stamp\SerializerStamp;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer as SymfonySerializer;
use Symfony\Component\Serializer\SerializerInterface as SymfonySerializerInterface;
@ -34,9 +35,9 @@ class Serializer implements SerializerInterface
private $format;
private $context;
public function __construct(SymfonySerializerInterface $serializer, string $format = 'json', array $context = array())
public function __construct(SymfonySerializerInterface $serializer = null, string $format = 'json', array $context = array())
{
$this->serializer = $serializer;
$this->serializer = $serializer ?? self::create()->serializer;
$this->format = $format;
$this->context = $context;
}
@ -48,7 +49,7 @@ class Serializer implements SerializerInterface
}
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new ObjectNormalizer());
$normalizers = array(new ArrayDenormalizer(), new ObjectNormalizer());
$serializer = new SymfonySerializer($normalizers, $encoders);
return new self($serializer);
@ -70,9 +71,8 @@ class Serializer implements SerializerInterface
$stamps = $this->decodeStamps($encodedEnvelope);
$context = $this->context;
/** @var SerializerStamp|null $serializerStamp */
if ($serializerStamp = $stamps[SerializerStamp::class] ?? null) {
$context = $serializerStamp->getContext() + $context;
if (isset($stamps[SerializerStamp::class])) {
$context = end($stamps[SerializerStamp::class])->getContext() + $context;
}
$message = $this->serializer->deserialize($encodedEnvelope['body'], $encodedEnvelope['headers']['type'], $this->format, $context);
@ -87,7 +87,7 @@ class Serializer implements SerializerInterface
{
$context = $this->context;
/** @var SerializerStamp|null $serializerStamp */
if ($serializerStamp = $envelope->get(SerializerStamp::class)) {
if ($serializerStamp = $envelope->last(SerializerStamp::class)) {
$context = $serializerStamp->getContext() + $context;
}
@ -107,7 +107,10 @@ class Serializer implements SerializerInterface
continue;
}
$stamps[] = $this->serializer->deserialize($value, substr($name, \strlen(self::STAMP_HEADER_PREFIX)), $this->format, $this->context);
$stamps[] = $this->serializer->deserialize($value, substr($name, \strlen(self::STAMP_HEADER_PREFIX)).'[]', $this->format, $this->context);
}
if ($stamps) {
$stamps = array_merge(...$stamps);
}
return $stamps;
@ -115,13 +118,13 @@ class Serializer implements SerializerInterface
private function encodeStamps(Envelope $envelope): array
{
if (!$stamps = $envelope->all()) {
if (!$allStamps = $envelope->all()) {
return array();
}
$headers = array();
foreach ($stamps as $stamp) {
$headers[self::STAMP_HEADER_PREFIX.\get_class($stamp)] = $this->serializer->serialize($stamp, $this->format, $this->context);
foreach ($allStamps as $class => $stamps) {
$headers[self::STAMP_HEADER_PREFIX.$class] = $this->serializer->serialize($stamps, $this->format, $this->context);
}
return $headers;