-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Messenger] availability to add serializer config at transport level #44951
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -107,6 +107,7 @@ | |
use Symfony\Component\Messenger\MessageBus; | ||
use Symfony\Component\Messenger\MessageBusInterface; | ||
use Symfony\Component\Messenger\Middleware\RouterContextMiddleware; | ||
use Symfony\Component\Messenger\Transport\Serialization\FormatAndContextAwareSerializerInterface; | ||
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface; | ||
use Symfony\Component\Messenger\Transport\TransportFactoryInterface; | ||
use Symfony\Component\Messenger\Transport\TransportInterface; | ||
|
@@ -1947,8 +1948,8 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder | |
$container->removeAlias(SerializerInterface::class); | ||
} else { | ||
$container->getDefinition('messenger.transport.symfony_serializer') | ||
->replaceArgument(1, $config['serializer']['symfony_serializer']['format']) | ||
->replaceArgument(2, $config['serializer']['symfony_serializer']['context']); | ||
->addMethodCall('setFormat', [$config['serializer']['symfony_serializer']['format']]) | ||
->addMethodCall('setContext', [$config['serializer']['symfony_serializer']['context']]); | ||
$container->setAlias('messenger.default_serializer', $config['serializer']['default_serializer']); | ||
} | ||
|
||
|
@@ -1976,6 +1977,22 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder | |
$transportRetryReferences = []; | ||
foreach ($config['transports'] as $name => $transport) { | ||
$serializerId = $transport['serializer'] ?? 'messenger.default_serializer'; | ||
|
||
if (isset($transport['symfony_serializer'])) { | ||
$serializerDefinition = $container->findDefinition($serializerId); | ||
|
||
if (!isset(class_implements($serializerDefinition->getClass())[FormatAndContextAwareSerializerInterface::class])) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO it's safer to rely on an interface to inject these parameters instead of constructor's parameters order: the service could be defined in user land There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this interface makes sense in the Messenger package. It's way too much tied to the Symfony Serializer implementation, and it's not even used at runtime, only here for DI.
If the user defines the service in userland, then they can inject the format and context themselves and won't need this configuration entry, right? I'd remove the interface, trait and method call to inject format and context using constructor's parameters, as for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
it depends: presently there is no way to define a custom serializer in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @ogizanagi here |
||
throw new InvalidArgumentException(sprintf('Serializer for transport "%s" should implement "%s" in order to have custom format or context.', $name, FormatAndContextAwareSerializerInterface::class)); | ||
} | ||
|
||
$container->setDefinition($serializerWithCustomConfigurationId = "messenger.transport.{$name}.serializer", new ChildDefinition($serializerId)) | ||
->addMethodCall('setFormat', [$transport['symfony_serializer']['format'] ?? $config['serializer']['symfony_serializer']['format']]) | ||
->addMethodCall('setContext', [($transport['symfony_serializer']['context'] ?? []) + $config['serializer']['symfony_serializer']['context']]) | ||
; | ||
Comment on lines
+1988
to
+1991
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new definition(s) needed here: if we want different config with the same service (for example default symfony's serializer) it has to be duplicated. |
||
|
||
$serializerId = $serializerWithCustomConfigurationId; | ||
} | ||
|
||
$transportDefinition = (new Definition(TransportInterface::class)) | ||
->setFactory([new Reference('messenger.transport_factory'), 'createTransport']) | ||
->setArguments([$transport['dsn'], $transport['options'] + ['transport_name' => $name], new Reference($serializerId)]) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
$container->loadFromExtension('framework', [ | ||
'messenger' => [ | ||
'serializer' => [ | ||
'default_serializer' => 'messenger.transport.symfony_serializer', | ||
'symfony_serializer' => [ | ||
'format' => 'json', | ||
'context' => ['some_context' => true] | ||
] | ||
], | ||
'transports' => [ | ||
'foo' => [ | ||
'dsn' => 'null://', | ||
'symfony_serializer' => [ | ||
'format' => 'xml', | ||
'context' => ['some_other_context' => true] | ||
] | ||
], | ||
], | ||
], | ||
]); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
|
||
$container->loadFromExtension('framework', [ | ||
'messenger' => [ | ||
'transports' => [ | ||
'foo' => [ | ||
'dsn' => 'null://', | ||
'symfony_serializer' => [ | ||
'format' => 'xml', | ||
] | ||
], | ||
], | ||
], | ||
]); |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,26 @@ | ||||
<?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> | ||||
<framework:messenger> | ||||
<framework:serializer default-serializer="messenger.transport.symfony_serializer"> | ||||
<framework:symfony-serializer format="xml"> | ||||
<framework:context> | ||||
<framework:some_context>true</framework:some_context> | ||||
</framework:context> | ||||
</framework:symfony-serializer> | ||||
</framework:serializer> | ||||
<framework:transport name="foo" dsn="null://"> | ||||
<framework:symfony_serializer format="xml"> | ||||
<framework:context> | ||||
<framework:some_other_context>true</framework:some_other_context> | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tests are failing here
don't know how to make them pass There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The schema needs an update symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd Line 499 in 6b9fafb
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok thanks, I was thinking it was something automatically generated |
||||
</framework:context> | ||||
</framework:symfony_serializer> | ||||
</framework:transport> | ||||
</framework:messenger> | ||||
</framework:config> | ||||
</container> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?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> | ||
<framework:messenger> | ||
<framework:transport name="foo" dsn="null://"> | ||
<framework:symfony_serializer format="xml"/> | ||
</framework:transport> | ||
</framework:messenger> | ||
</framework:config> | ||
</container> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
framework: | ||
messenger: | ||
serializer: | ||
default_serializer: messenger.transport.symfony_serializer | ||
symfony_serializer: | ||
format: 'json' | ||
context: | ||
some_context: true | ||
transports: | ||
foo: | ||
dsn: 'null://' | ||
symfony_serializer: | ||
format: 'xml' | ||
context: | ||
some_other_context: true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
framework: | ||
messenger: | ||
transports: | ||
foo: | ||
dsn: 'null://' | ||
symfony_serializer: | ||
format: 'xml' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Messenger\Transport\Serialization; | ||
|
||
/** | ||
* @author Nicolas PHILIPPE <nikophil@gmail.com> | ||
*/ | ||
interface FormatAndContextAwareSerializerInterface extends SerializerInterface | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've introduced this new interface to not break BC |
||
{ | ||
public function setFormat(string $format): void; | ||
|
||
public function setContext(array $context): void; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Messenger\Transport\Serialization; | ||
|
||
/** | ||
* @author Nicolas PHILIPPE <nikophil@gmail.com> | ||
*/ | ||
trait FormatAndContextAwareSerializerTrait | ||
{ | ||
private string $format; | ||
private array $context; | ||
|
||
public function setFormat(string $format): void | ||
{ | ||
$this->format = $format; | ||
} | ||
|
||
public function setContext(array $context): void | ||
{ | ||
$this->context = $context + [Serializer::MESSENGER_SERIALIZATION_CONTEXT => true]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,20 +29,20 @@ | |
/** | ||
* @author Samuel Roze <samuel.roze@gmail.com> | ||
*/ | ||
class Serializer implements SerializerInterface | ||
class Serializer implements FormatAndContextAwareSerializerInterface | ||
{ | ||
use FormatAndContextAwareSerializerTrait; | ||
|
||
public const MESSENGER_SERIALIZATION_CONTEXT = 'messenger_serialization'; | ||
private const STAMP_HEADER_PREFIX = 'X-Message-Stamp-'; | ||
|
||
private SymfonySerializerInterface $serializer; | ||
private string $format; | ||
private array $context; | ||
|
||
public function __construct(SymfonySerializerInterface $serializer = null, string $format = 'json', array $context = []) | ||
{ | ||
$this->serializer = $serializer ?? self::create()->serializer; | ||
$this->format = $format; | ||
$this->context = $context + [self::MESSENGER_SERIALIZATION_CONTEXT => true]; | ||
$this->setFormat($format); | ||
$this->setContext($context); | ||
} | ||
Comment on lines
41
to
46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think removing |
||
|
||
public static function create(): self | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about a less specific
context
node, eg.context.format
to be used by SF serializerThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you mean we could have this kind of configuration?
and then
$context['format']
would be passsed to$this->serializer->(de)serialize()
inSymfony\Component\Messenger\Transport\Serialization\SerializerInterface
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, but it was it bit pre-mature of me. I think
messenger.transports.N.serializer
is what couples transports with a serializer, and this new config complexifies things for little gain.In that sense, i prefer to add a new prototyped
messenger.serializers
and deprecatemessenger.serializer