Skip to content

[Messenger] New transport.serializer configuration #49256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 7.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1466,9 +1466,75 @@ function ($a) {
})
->end()
->fixXmlConfig('option')
->validate()
->ifTrue(static fn (array $transportConf) => \count(array_intersect(['serializer', 'incoming_message_serializer', 'outgoing_message_serializer'], array_keys($transportConf))) > 1)
->thenInvalid('Only one of "serializer", "incoming_message_serializer" and "outgoing_message_serializer" could be used.')
->end()
->children()
->scalarNode('dsn')->end()
->scalarNode('serializer')->defaultNull()->info('Service id of a custom serializer to use.')->end()
->arrayNode('serializer')
->info('Transport serializer configuration for messages produced and handled by this application.')
->beforeNormalization()
->ifString()
->then(static fn (string $serviceId) => ['service_id' => $serviceId])
->end()
->children()
->scalarNode('service_id')->info('Service id of a custom transport serializer to use (incompatible with "format", "context" and "serializer" options).')->defaultNull()->end()
->scalarNode('format')->info('Serialization format for this transport\'s serializer (will use Symfony serializer).')->end()
->arrayNode('context')
->normalizeKeys(false)
->useAttributeAsKey('name')
->defaultValue([])
->info('Context serialization array for this transport\'s serializer (will use Symfony serializer).')
->prototype('variable')->end()
->end()
->scalarNode('serializer')->info('Service id of a custom Symfony serializer to use.')->end()
->end()
->validate()
->ifTrue(static fn (array $serializerConf) => !(isset($serializerConf['service_id']) xor (isset($serializerConf['format']) || [] !== $serializerConf['context'] || isset($serializerConf['serializer']))))
->thenInvalid('Either "service_id" OR at least one of "format" or "context" or "serializer" should be provided.')
->end()
->end()
->arrayNode('incoming_message_serializer')
->info('Transport serializer configuration for messages coming from other applications (uses Symfony serializer).')
->children()
->scalarNode('messageClass')
->info('The class in which the message should be deserialized (incompatible with "messageClassResolver" option).')
->validate()
->ifTrue(static fn ($class) => $class && !class_exists($class))
->thenInvalid('The "messageClass" should be a valid class.')
->end()
->end()
->scalarNode('messageClassResolver')->info('Service id of a message class resolver to use (incompatible with "messageClass" option).')->end()
->scalarNode('format')->info('Serialization format for this transport\'s serializer.')->end()
->arrayNode('context')
->normalizeKeys(false)
->useAttributeAsKey('name')
->defaultValue([])
->info('Context serialization array for this transport\'s serializer.')
->prototype('variable')->end()
->end()
->scalarNode('serializer')->info('Service id of a custom Symfony serializer to use.')->end()
->end()
->validate()
->ifTrue(static fn (array $incomingMessageConf) => !(isset($incomingMessageConf['messageClass']) xor isset($incomingMessageConf['messageClassResolver'])))
->thenInvalid('A message class OR a message class resolver should be provided.')
->end()
->end()
->arrayNode('outgoing_message_serializer')
->info('Transport serializer configuration for sending messages to other applications (uses Symfony serializer).')
->children()
->scalarNode('format')->info('Serialization format for this transport\'s serializer.')->end()
->arrayNode('context')
->normalizeKeys(false)
->useAttributeAsKey('name')
->defaultValue([])
->info('Context serialization array for this transport\'s serializer.')
->prototype('variable')->end()
->end()
->scalarNode('serializer')->info('Service id of a custom Symfony serializer to use.')->end()
->end()
->end()
->arrayNode('options')
->normalizeKeys(false)
->defaultValue([])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Middleware\RouterContextMiddleware;
use Symfony\Component\Messenger\Transport\Serialization\IncomingMessageSerializer;
use Symfony\Component\Messenger\Transport\Serialization\OutgoingMessageSerializer;
use Symfony\Component\Messenger\Transport\Serialization\Serializer;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;
use Symfony\Component\Messenger\Transport\TransportInterface;
Expand Down Expand Up @@ -2086,7 +2089,47 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
$transportRetryReferences = [];
$transportRateLimiterReferences = [];
foreach ($config['transports'] as $name => $transport) {
$serializerId = $transport['serializer'] ?? 'messenger.default_serializer';
if (isset($transport['serializer'])) {
$basicSerializerConf = $transport['serializer'];

$serializerId = $basicSerializerConf['service_id'] ?? "messenger.transport.{$name}.serializer";

if (($basicSerializerConf['serializer'] ?? null) || ($basicSerializerConf['format'] ?? null) || [] !== $basicSerializerConf['context']) {
$serializerDefinition = (new Definition(Serializer::class))
->setArguments([
new Reference($basicSerializerConf['serializer'] ?? 'serializer'),
$basicSerializerConf['format'] ?? $config['serializer']['symfony_serializer']['format'],
$basicSerializerConf['context'] ?: $config['serializer']['symfony_serializer']['context'],
]);

$container->setDefinition($serializerId, $serializerDefinition);
}
} elseif (isset($transport['incoming_message_serializer'])) {
$incomingSerializerConf = $transport['incoming_message_serializer'];

$serializerDefinition = (new Definition(IncomingMessageSerializer::class))
->setArguments([
$incomingSerializerConf['messageClass'] ?? new Reference($incomingSerializerConf['messageClassResolver']),
new Reference($incomingSerializerConf['serializer'] ?? 'serializer'),
$incomingSerializerConf['format'] ?? $config['serializer']['symfony_serializer']['format'],
$incomingSerializerConf['context'] ?: $config['serializer']['symfony_serializer']['context'],
]);

$container->setDefinition($serializerId = "messenger.transport.{$name}.serializer", $serializerDefinition);
} elseif (isset($transport['outgoing_message_serializer'])) {
$outgoingSerializerConf = $transport['outgoing_message_serializer'];

$serializerDefinition = (new Definition(OutgoingMessageSerializer::class))
->setArguments([
new Reference($outgoingSerializerConf['serializer'] ?? 'serializer'),
$outgoingSerializerConf['format'] ?? $config['serializer']['symfony_serializer']['format'],
$outgoingSerializerConf['context'] ?: $config['serializer']['symfony_serializer']['context'],
]);

$container->setDefinition($serializerId = "messenger.transport.{$name}.serializer", $serializerDefinition);
}

$serializerId ??= 'messenger.default_serializer';
$transportDefinition = (new Definition(TransportInterface::class))
->setFactory([new Reference('messenger.transport_factory'), 'createTransport'])
->setArguments([$transport['dsn'], $transport['options'] + ['transport_name' => $name], new Reference($serializerId)])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\BarMessage;

$container->loadFromExtension('framework', [
'http_method_override' => false,
'serializer' => true,
'messenger' => [
'serializer' => [
'symfony_serializer' => [
'format' => 'xml',
'context' => ['default' => 'context'],
]
],
'transports' => [
'default_serializer' => ['dsn' => 'null://'],
'custom_serializer_short_notation' => [
'dsn' => 'null://',
'serializer' => 'messenger.transport.native_php_serializer',
],
'custom_serializer_long_notation' => [
'dsn' => 'null://',
'serializer' => [
'service_id' => 'messenger.transport.native_php_serializer',
],
],
'symfony_serializer_with_context' => [
'dsn' => 'null://',
'serializer' => [
'format' => 'json',
'context' => ['some' => 'context'],
'serializer' => 'my_fancy_serializer',
],
],
'incoming_message_transport' => [
'dsn' => 'null://',
'incoming_message_serializer' => [
'messageClass' => BarMessage::class,
'format' => 'json',
'context' => ['some' => 'context'],
'serializer' => 'my_fancy_serializer',
],
],
'incoming_message_transport_with_default_serializer' => [
'dsn' => 'null://',
'incoming_message_serializer' => [
'messageClassResolver' => 'some_message_class_resolver_id',
],
],
'outgoing_message_transport' => [
'dsn' => 'null://',
'outgoing_message_serializer' => [
'format' => 'json',
'context' => ['some' => 'context'],
'serializer' => 'my_fancy_serializer',
],
],
'outgoing_message_transport_with_default_serializer' => [
'dsn' => 'null://',
'outgoing_message_serializer' => [],
],
],
],
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

$container->loadFromExtension('framework', [
'http_method_override' => false,
'serializer' => true,
'messenger' => [
'transports' => [
'invalid_transport' => [
'dsn' => 'null://',
'serializer' => 'messenger.transport.native_php_serializer',
'outgoing_message_serializer' => []
]
],
],
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

$container->loadFromExtension('framework', [
'http_method_override' => false,
'serializer' => true,
'messenger' => [
'transports' => [
'invalid_transport' => [
'dsn' => 'null://',
'serializer' => [
'service_id' => 'messenger.transport.native_php_serializer',
'format' => 'json'
],
]
],
],
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

$container->loadFromExtension('framework', [
'http_method_override' => false,
'serializer' => true,
'messenger' => [
'transports' => [
'invalid_transport' => [
'dsn' => 'null://',
'serializer' => [],
]
],
],
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\BarMessage;

$container->loadFromExtension('framework', [
'http_method_override' => false,
'serializer' => true,
'messenger' => [
'transports' => [
'invalid_transport' => [
'dsn' => 'null://',
'incoming_message_serializer' => [
'messageClass' => BarMessage::class,
'messageClassResolver' => 'foo',
],
]
],
],
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

$container->loadFromExtension('framework', [
'http_method_override' => false,
'serializer' => true,
'messenger' => [
'transports' => [
'invalid_transport' => [
'dsn' => 'null://',
'incoming_message_serializer' => [
'messageClass' => 'foo',
],
]
],
],
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony">
<!--xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"-->


<framework:config http-method-override="false">
<framework:serializer enabled="true" />
<framework:messenger>
<framework:serializer>
<framework:symfony-serializer format="xml">
<framework:context>
<framework:default>context</framework:default>
</framework:context>
</framework:symfony-serializer>
</framework:serializer>

<framework:transport name="default_serializer" dsn="null://" />

<framework:transport name="custom_serializer_short_notation" dsn="null://" serializer="messenger.transport.native_php_serializer" />

<framework:transport name="custom_serializer_long_notation" dsn="null://">
<framework:serializer service_id="messenger.transport.native_php_serializer" />
</framework:transport>

<framework:transport name="symfony_serializer_with_context" dsn="null://">
<framework:serializer format="json" serializer="my_fancy_serializer">
<framework:context>
<framework:some>context</framework:some>
</framework:context>
</framework:serializer>
</framework:transport>

<framework:transport name="incoming_message_transport" dsn="null://">
<framework:incoming_message_serializer format="json" serializer="my_fancy_serializer" messageClass="Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\BarMessage">
<framework:context>
<framework:some>context</framework:some>
</framework:context>
</framework:incoming_message_serializer>
</framework:transport>

<framework:transport name="incoming_message_transport_with_default_serializer" dsn="null://">
<framework:incoming_message_serializer messageClassResolver="some_message_class_resolver_id" />
</framework:transport>

<framework:transport name="outgoing_message_transport" dsn="null://">
<framework:outgoing_message_serializer format="json" serializer="my_fancy_serializer">
<framework:context>
<framework:some>context</framework:some>
</framework:context>
</framework:outgoing_message_serializer>
</framework:transport>

<framework:transport name="outgoing_message_transport_with_default_serializer" dsn="null://">
<framework:outgoing_message_serializer />
</framework:transport>

</framework:messenger>
</framework:config>
</container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony">
<!--xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"-->


<framework:config http-method-override="false">
<framework:serializer enabled="true" />
<framework:messenger>
<framework:transport name="invalid_transport" dsn="null://">
<framework:serializer service_id="messenger.transport.native_php_serializer" />
<framework:outgoing_message_serializer />
</framework:transport>
</framework:messenger>
</framework:config>
</container>
Loading