feature #28270 [Messenger] Uses Symfony Serializer by default for envelope items (sroze)
This PR was merged into the 4.2-dev branch.
Discussion
----------
[Messenger] Uses Symfony Serializer by default for envelope items
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | yes
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #28164
| License | MIT
| Doc PR | ø
The original approach was to use `serialize`/`unserialize` for envelope items. It turns out it has limitations (see #28247) and reduces the compatibility with 3rd party systems (see #28164). This pull-request changes the existing mechanism by using Symfony Serializer by default.
It keeps the `serialize`/`unserialize` mechanism to allow users of the experimental component to keep using it in 4.2 and allow to have a non-disruptive upgrade to 4.2.
Commits
-------
9b575ab263
Uses Symfony Serializer by default for envelope items
This commit is contained in:
commit
5a63f19bad
@ -80,15 +80,17 @@ class SerializerTest extends TestCase
|
||||
$this->assertSame($message, $decoded->getMessage());
|
||||
}
|
||||
|
||||
public function testEncodedWithSerializationConfiguration()
|
||||
public function testEncodedWithSymfonySerializerForItems()
|
||||
{
|
||||
$serializer = new Serializer(
|
||||
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder()))
|
||||
new SerializerComponent\Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder())),
|
||||
'json',
|
||||
array()
|
||||
);
|
||||
|
||||
$envelope = Envelope::wrap(new DummyMessage('Hello'))
|
||||
->with(new SerializerConfiguration(array(ObjectNormalizer::GROUPS => array('foo'))))
|
||||
->with(new ValidationConfiguration(array('foo', 'bar')))
|
||||
->with($serializerConfiguration = new SerializerConfiguration(array(ObjectNormalizer::GROUPS => array('foo'))))
|
||||
->with($validationConfiguration = new ValidationConfiguration(array('foo', 'bar')))
|
||||
;
|
||||
|
||||
$encoded = $serializer->encode($envelope);
|
||||
@ -96,8 +98,12 @@ class SerializerTest extends TestCase
|
||||
$this->assertArrayHasKey('body', $encoded);
|
||||
$this->assertArrayHasKey('headers', $encoded);
|
||||
$this->assertArrayHasKey('type', $encoded['headers']);
|
||||
$this->assertEquals(DummyMessage::class, $encoded['headers']['type']);
|
||||
$this->assertArrayHasKey('X-Message-Envelope-Items', $encoded['headers']);
|
||||
$this->assertSame('a:2:{s:75:"Symfony\Component\Messenger\Transport\Serialization\SerializerConfiguration";O:75:"Symfony\Component\Messenger\Transport\Serialization\SerializerConfiguration":1:{s:84:"'."\0".'Symfony\Component\Messenger\Transport\Serialization\SerializerConfiguration'."\0".'context";a:1:{s:6:"groups";a:1:{i:0;s:3:"foo";}}}s:76:"Symfony\Component\Messenger\Middleware\Configuration\ValidationConfiguration";O:76:"Symfony\Component\Messenger\Middleware\Configuration\ValidationConfiguration":1:{s:84:"'."\0".'Symfony\Component\Messenger\Middleware\Configuration\ValidationConfiguration'."\0".'groups";a:2:{i:0;s:3:"foo";i:1;s:3:"bar";}}}', $encoded['headers']['X-Message-Envelope-Items']);
|
||||
$this->assertArrayHasKey('X-Message-Envelope-Symfony\Component\Messenger\Transport\Serialization\SerializerConfiguration', $encoded['headers']);
|
||||
$this->assertArrayHasKey('X-Message-Envelope-Symfony\Component\Messenger\Middleware\Configuration\ValidationConfiguration', $encoded['headers']);
|
||||
|
||||
$decoded = $serializer->decode($encoded);
|
||||
|
||||
$this->assertEquals($serializerConfiguration, $decoded->get(SerializerConfiguration::class));
|
||||
$this->assertEquals($validationConfiguration, $decoded->get(ValidationConfiguration::class));
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class Serializer implements DecoderInterface, EncoderInterface
|
||||
throw new \InvalidArgumentException('Encoded envelope does not have a `type` header.');
|
||||
}
|
||||
|
||||
$envelopeItems = isset($encodedEnvelope['headers']['X-Message-Envelope-Items']) ? unserialize($encodedEnvelope['headers']['X-Message-Envelope-Items']) : array();
|
||||
$envelopeItems = $this->decodeEnvelopeItems($encodedEnvelope);
|
||||
|
||||
$context = $this->context;
|
||||
/** @var SerializerConfiguration|null $serializerConfig */
|
||||
@ -67,14 +67,39 @@ class Serializer implements DecoderInterface, EncoderInterface
|
||||
$context = $serializerConfig->getContext() + $context;
|
||||
}
|
||||
|
||||
$headers = array('type' => \get_class($envelope->getMessage()));
|
||||
if ($configurations = $envelope->all()) {
|
||||
$headers['X-Message-Envelope-Items'] = serialize($configurations);
|
||||
}
|
||||
$headers = array('type' => \get_class($envelope->getMessage())) + $this->encodeEnvelopeItems($envelope);
|
||||
|
||||
return array(
|
||||
'body' => $this->serializer->serialize($envelope->getMessage(), $this->format, $context),
|
||||
'headers' => $headers,
|
||||
);
|
||||
}
|
||||
|
||||
private function decodeEnvelopeItems($encodedEnvelope)
|
||||
{
|
||||
$items = array();
|
||||
foreach ($encodedEnvelope['headers'] as $name => $value) {
|
||||
if (0 !== strpos($name, $prefix = 'X-Message-Envelope-')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$items[] = $this->serializer->deserialize($value, substr($name, \strlen($prefix)), $this->format, $this->context);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
private function encodeEnvelopeItems(Envelope $envelope)
|
||||
{
|
||||
if (!$configurations = $envelope->all()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$headers = array();
|
||||
foreach ($configurations as $configuration) {
|
||||
$headers['X-Message-Envelope-'.\get_class($configuration)] = $this->serializer->serialize($configuration, $this->format, $this->context);
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user