diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index c488af15adaa8..78bb1b0ee9a78 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -1008,6 +1008,21 @@ function ($a) { ->end() ->end() ->end() + ->arrayNode('serializer') + ->canBeDisabled() + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('format')->defaultValue('json')->end() + ->arrayNode('context') + ->normalizeKeys(false) + ->useAttributeAsKey('name') + ->defaultValue(array()) + ->prototype('variable')->end() + ->end() + ->end() + ->end() + ->scalarNode('encoder')->defaultValue('messenger.transport.serializer')->end() + ->scalarNode('decoder')->defaultValue('messenger.transport.serializer')->end() ->arrayNode('middlewares') ->addDefaultsIfNotSet() ->children() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index aaa548b18488c..826d4f0fae72c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -273,7 +273,7 @@ public function load(array $configs, ContainerBuilder $container) } if ($this->isConfigEnabled($container, $config['messenger'])) { - $this->registerMessengerConfiguration($config['messenger'], $container, $loader); + $this->registerMessengerConfiguration($config['messenger'], $container, $loader, $config['serializer']); } else { $container->removeDefinition('console.command.messenger_consume_messages'); } @@ -1438,7 +1438,7 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont } } - private function registerMessengerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + private function registerMessengerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader, array $serializerConfig) { if (!interface_exists(MessageBusInterface::class)) { throw new LogicException('Messenger support cannot be enabled as the Messenger component is not installed.'); @@ -1446,6 +1446,21 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder $loader->load('messenger.xml'); + if ($this->isConfigEnabled($container, $config['serializer'])) { + if (count($config['adapters']) > 0 && !$this->isConfigEnabled($container, $serializerConfig)) { + throw new LogicException('Using the default encoder/decoder, Symfony Messenger requires the Serializer. Enable it or install it by running "composer require symfony/serializer-pack".'); + } + + $container->getDefinition('messenger.transport.serializer') + ->replaceArgument(1, $config['serializer']['format']) + ->replaceArgument(2, $config['serializer']['context']); + } else { + $container->removeDefinition('messenger.transport.serializer'); + } + + $container->setAlias('messenger.transport.encoder', $config['encoder']); + $container->setAlias('messenger.transport.decoder', $config['decoder']); + $messageToSenderIdsMapping = array(); foreach ($config['routing'] as $message => $messageConfiguration) { $messageToSenderIdsMapping[$message] = $messageConfiguration['senders']; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml index ab685fe5a544e..b5edb168b3a2c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml @@ -43,13 +43,12 @@ - + + + - - - @@ -79,8 +78,8 @@ - - + + %kernel.debug% diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 3fbfaa5d9a6ac..40e52179cc4e4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -352,12 +352,23 @@ + + + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 978acc19eeef6..fe683a5efb8e0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -18,6 +18,7 @@ use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Lock\Store\SemaphoreStore; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Serializer\Serializer; class ConfigurationTest extends TestCase { @@ -259,6 +260,13 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor ), ), 'adapters' => array(), + 'serializer' => array( + 'enabled' => true, + 'format' => 'json', + 'context' => array(), + ), + 'encoder' => 'messenger.transport.serializer', + 'decoder' => 'messenger.transport.serializer', ), ); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_adapter.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_adapter.php index 5e8608e4e894f..7165cbd06e456 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_adapter.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_adapter.php @@ -1,6 +1,7 @@ loadFromExtension('framework', array( + 'serializer' => true, 'messenger' => array( 'adapters' => array( 'default' => 'amqp://localhost/%2f/messages', diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport.php new file mode 100644 index 0000000000000..ec90a3197b1ef --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport.php @@ -0,0 +1,10 @@ +loadFromExtension('framework', array( + 'messenger' => array( + 'serializer' => array( + 'format' => 'csv', + 'context' => array('enable_max_depth' => true), + ), + ), +)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_no_serializer.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_no_serializer.php new file mode 100644 index 0000000000000..50bf53dfadd59 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_no_serializer.php @@ -0,0 +1,15 @@ +loadFromExtension('framework', array( + 'serializer' => array( + 'enabled' => false, + ), + 'messenger' => array( + 'serializer' => array( + 'enabled' => true, + ), + 'adapters' => array( + 'default' => 'amqp://localhost/%2f/messages', + ), + ), +)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_adapter.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_adapter.xml index 830ba48a9cc25..3c98299358a7a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_adapter.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_adapter.xml @@ -6,6 +6,7 @@ http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport.xml new file mode 100644 index 0000000000000..ca7c597d44aae --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport.xml @@ -0,0 +1,17 @@ + + + + + + + + true + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport_no_serializer.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport_no_serializer.xml new file mode 100644 index 0000000000000..40db4118a2aad --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport_no_serializer.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_adapter.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_adapter.yml index 2ec24e9aa15db..0f3846d3611af 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_adapter.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_adapter.yml @@ -1,4 +1,5 @@ framework: + serializer: true messenger: adapters: default: 'amqp://localhost/%2f/messages' diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transport.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transport.yml new file mode 100644 index 0000000000000..af590a5169973 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transport.yml @@ -0,0 +1,6 @@ +framework: + messenger: + serializer: + format: csv + context: + enable_max_depth: true diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transport_no_serializer.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transport_no_serializer.yml new file mode 100644 index 0000000000000..f82d9789d7959 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transport_no_serializer.yml @@ -0,0 +1,8 @@ +framework: + serializer: + enabled: false + messenger: + serializer: + enabled: true + adapters: + default: 'amqp://localhost/%2f/messages' diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index cca0295230eef..45a4fd3f49577 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -569,6 +569,27 @@ public function testMessengerAdapter() $this->assertSame(array('queue_name' => 'Queue'), $receiverArguments[1]); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException + * @expectedExceptionMessage Using the default encoder/decoder, Symfony Messenger requires the Serializer. Enable it or install it by running "composer require symfony/serializer-pack". + */ + public function testMessengerTransportConfigurationWithoutSerializer() + { + $this->createContainerFromFile('messenger_transport_no_serializer'); + } + + public function testMessengerTransportConfiguration() + { + $container = $this->createContainerFromFile('messenger_transport'); + + $this->assertSame('messenger.transport.serializer', (string) $container->getAlias('messenger.transport.encoder')); + $this->assertSame('messenger.transport.serializer', (string) $container->getAlias('messenger.transport.decoder')); + + $serializerTransportDefinition = $container->getDefinition('messenger.transport.serializer'); + $this->assertSame('csv', $serializerTransportDefinition->getArgument(1)); + $this->assertSame(array('enable_max_depth' => true), $serializerTransportDefinition->getArgument(2)); + } + public function testTranslator() { $container = $this->createContainerFromFile('full'); diff --git a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php index 361f45f163901..81700499c234a 100644 --- a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php +++ b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php @@ -53,12 +53,6 @@ public function process(ContainerBuilder $container) $container->removeDefinition('messenger.middleware.debug.logging'); } - if (!$container->has('serializer')) { - $container->removeDefinition('messenger.transport.serialize_message_with_type_in_headers'); - $container->removeAlias('messenger.transport.default_encoder'); - $container->removeAlias('messenger.transport.default_decoder'); - } - $this->registerReceivers($container); $this->registerSenders($container); $this->registerHandlers($container); diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Serialization/SerializerTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Serialization/SerializerTest.php index 8b6199144b7c7..2e227c0f2f717 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Serialization/SerializerTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Serialization/SerializerTest.php @@ -44,4 +44,21 @@ public function testEncodedIsHavingTheBodyAndTypeHeader() $this->assertArrayHasKey('type', $encoded['headers']); $this->assertEquals(DummyMessage::class, $encoded['headers']['type']); } + + public function testUsesTheCustomFormatAndContext() + { + $message = new DummyMessage('Foo'); + + $serializer = $this->getMockBuilder(SerializerComponent\SerializerInterface::class)->getMock(); + $serializer->expects($this->once())->method('serialize')->with($message, 'csv', array('foo' => 'bar'))->willReturn('Yay'); + $serializer->expects($this->once())->method('deserialize')->with('Yay', DummyMessage::class, 'csv', array('foo' => 'bar'))->willReturn($message); + + $encoder = new Serializer($serializer, 'csv', array('foo' => 'bar')); + + $encoded = $encoder->encode($message); + $decoded = $encoder->decode($encoded); + + $this->assertSame('Yay', $encoded['body']); + $this->assertSame($message, $decoded); + } } diff --git a/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php b/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php index afa0c5d159f92..65c2ac55e8886 100644 --- a/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php +++ b/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php @@ -20,11 +20,13 @@ class Serializer implements DecoderInterface, EncoderInterface { private $serializer; private $format; + private $context; - public function __construct(SerializerInterface $serializer, string $format = 'json') + public function __construct(SerializerInterface $serializer, string $format = 'json', array $context = array()) { $this->serializer = $serializer; $this->format = $format; + $this->context = $context; } /** @@ -40,7 +42,7 @@ public function decode(array $encodedMessage) throw new \InvalidArgumentException('Encoded message does not have a `type` header.'); } - return $this->serializer->deserialize($encodedMessage['body'], $encodedMessage['headers']['type'], $this->format); + return $this->serializer->deserialize($encodedMessage['body'], $encodedMessage['headers']['type'], $this->format, $this->context); } /** @@ -49,7 +51,7 @@ public function decode(array $encodedMessage) public function encode($message): array { return array( - 'body' => $this->serializer->serialize($message, $this->format), + 'body' => $this->serializer->serialize($message, $this->format, $this->context), 'headers' => array('type' => \get_class($message)), ); }