Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aa48465

Browse files
committed
Allow to define multiple buses from the framework.messenger.buses configuration
1 parent a59ef8f commit aa48465

File tree

12 files changed

+216
-14
lines changed

12 files changed

+216
-14
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ private function addMessengerSection(ArrayNodeDefinition $rootNode)
970970
->arrayNode('messenger')
971971
->info('Messenger configuration')
972972
->{!class_exists(FullStack::class) && class_exists(MessageBusInterface::class) ? 'canBeDisabled' : 'canBeEnabled'}()
973+
->fixXmlConfig('bus', 'buses')
973974
->children()
974975
->arrayNode('routing')
975976
->useAttributeAsKey('message_class')
@@ -1010,6 +1011,30 @@ function ($a) {
10101011
->end()
10111012
->end()
10121013
->end()
1014+
->scalarNode('default_bus')->defaultValue('default')->end()
1015+
->arrayNode('buses')
1016+
->defaultValue(array('default' => array('middlewares' => array())))
1017+
->useAttributeAsKey('name')
1018+
->prototype('array')
1019+
->fixXmlConfig('middleware')
1020+
->children()
1021+
->arrayNode('middlewares')
1022+
->prototype('array')
1023+
->beforeNormalization()
1024+
->ifString()
1025+
->then(function(string $middleware) {
1026+
return array('service' => $middleware);
1027+
})
1028+
->end()
1029+
->children()
1030+
->scalarNode('service')->isRequired()->end()
1031+
->integerNode('priority')->defaultValue(0)->end()
1032+
->end()
1033+
->end()
1034+
->end()
1035+
->end()
1036+
->end()
1037+
->end()
10131038
->end()
10141039
->end()
10151040
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
use Symfony\Component\Lock\Store\StoreFactory;
6262
use Symfony\Component\Lock\StoreInterface;
6363
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
64+
use Symfony\Component\Messenger\MessageBus;
6465
use Symfony\Component\Messenger\MessageBusInterface;
6566
use Symfony\Component\Messenger\Transport\ReceiverInterface;
6667
use Symfony\Component\Messenger\Transport\SenderInterface;
@@ -1448,6 +1449,26 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
14481449

14491450
$loader->load('messenger.xml');
14501451

1452+
$container->setParameter('messenger.buses_names', array_keys($config['buses']));
1453+
foreach ($config['buses'] as $name => $bus) {
1454+
$container->setDefinition($busId = 'messenger.bus.'.$name, (new Definition(MessageBus::class, array(array())))->addTag('messenger.bus')->setPublic(true));
1455+
1456+
if ($name == $config['default_bus']) {
1457+
$container->setAlias('message_bus', $busId);
1458+
$container->setAlias(MessageBusInterface::class, $busId);
1459+
}
1460+
1461+
foreach ($bus['middlewares'] as $middleware) {
1462+
if (!$container->has($middleware['service'])) {
1463+
$container->setDefinition($middleware['service'], new Definition($middleware['service']));
1464+
}
1465+
1466+
$container->getDefinition($middleware['service'])->addTag('message_bus_middleware', array(
1467+
'bus' => $name,
1468+
));
1469+
}
1470+
}
1471+
14511472
$senderLocatorMapping = array();
14521473
$messageToSenderIdsMapping = array();
14531474
foreach ($config['routing'] as $message => $messageConfiguration) {

src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@
77
<services>
88
<defaults public="false" />
99

10-
<!-- Bus -->
11-
<service id="message_bus" class="Symfony\Component\Messenger\MessageBus" public="true">
12-
<argument type="tagged" tag="message_bus_middleware" /> <!-- Middlewares -->
13-
</service>
14-
15-
<service id="Symfony\Component\Messenger\MessageBusInterface" alias="message_bus" />
16-
1710
<!-- Handlers -->
1811
<service id="messenger.handler_resolver" class="Symfony\Component\Messenger\ContainerHandlerLocator">
1912
<argument type="service" id="service_container"/>

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,10 @@
353353
<xsd:complexType name="messenger">
354354
<xsd:sequence>
355355
<xsd:element name="routing" type="messenger_routing" minOccurs="0" maxOccurs="unbounded" />
356-
<xsd:element name="middlewares" type="messenger_middleware" minOccurs="0" maxOccurs="unbounded" />
356+
<xsd:element name="middlewares" type="messenger_middlewares" minOccurs="0" maxOccurs="unbounded" />
357+
<xsd:element name="bus" type="messenger_bus" minOccurs="0" maxOccurs="unbounded" />
357358
</xsd:sequence>
359+
<xsd:attribute name="default-bus" type="xsd:string" />
358360
</xsd:complexType>
359361

360362
<xsd:complexType name="messenger_routing">
@@ -368,12 +370,24 @@
368370
<xsd:attribute name="service" type="xsd:string" use="required"/>
369371
</xsd:complexType>
370372

371-
<xsd:complexType name="messenger_middleware">
373+
<xsd:complexType name="messenger_middlewares">
372374
<xsd:sequence>
373375
<xsd:element name="validation" type="messenger_validation" minOccurs="0" maxOccurs="1" />
374376
</xsd:sequence>
375377
</xsd:complexType>
376378

379+
<xsd:complexType name="messenger_bus">
380+
<xsd:sequence>
381+
<xsd:element name="middleware" type="messenger_middleware" minOccurs="0" maxOccurs="unbounded" />
382+
</xsd:sequence>
383+
<xsd:attribute name="name" type="xsd:string" use="required"/>
384+
</xsd:complexType>
385+
386+
<xsd:complexType name="messenger_middleware">
387+
<xsd:attribute name="service" type="xsd:string" use="required"/>
388+
<xsd:attribute name="priority" type="xsd:integer" />
389+
</xsd:complexType>
390+
377391
<xsd:complexType name="messenger_validation">
378392
<xsd:attribute name="enabled" type="xsd:boolean" />
379393
</xsd:complexType>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
258258
'enabled' => !class_exists(FullStack::class),
259259
),
260260
),
261+
'default_bus' => 'default',
262+
'buses' => array('default' => array('middlewares' => array()))
261263
),
262264
);
263265
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', array(
4+
'messenger' => array(
5+
'default_bus' => 'commands',
6+
'buses' => array(
7+
'commands' => null,
8+
'events' => array(
9+
'middlewares' => array(
10+
'Symfony\\Component\\Messenger\\Middleware\\TolerateNoHandler',
11+
),
12+
),
13+
),
14+
),
15+
));
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<framework:config>
9+
<framework:messenger default-bus="commands">
10+
<framework:bus name="commands" />
11+
<framework:bus name="events">
12+
<framework:middleware service="Symfony\Component\Messenger\Middleware\TolerateNoHandler" />
13+
</framework:bus>
14+
</framework:messenger>
15+
</framework:config>
16+
</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
framework:
2+
messenger:
3+
default_bus: commands
4+
buses:
5+
commands: ~
6+
events:
7+
middlewares:
8+
- "Symfony\\Component\\Messenger\\Middleware\\TolerateNoHandler"

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
3434
use Symfony\Component\DependencyInjection\Reference;
3535
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
36+
use Symfony\Component\Messenger\Middleware\TolerateNoHandler;
3637
use Symfony\Component\PropertyAccess\PropertyAccessor;
3738
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
3839
use Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer;
@@ -532,6 +533,24 @@ public function testMessengerValidationDisabled()
532533
$this->assertFalse($container->hasDefinition('messenger.middleware.validator'));
533534
}
534535

536+
public function testMessengerWithMultipleBuses()
537+
{
538+
$container = $this->createContainerFromFile('messenger_multiple_buses');
539+
540+
$this->assertTrue($container->has('messenger.bus.commands'));
541+
$this->assertEquals(array(), $container->getDefinition('messenger.bus.commands')->getArgument(0));
542+
$this->assertTrue($container->has('messenger.bus.events'));
543+
$this->assertEquals(array(), $container->getDefinition('messenger.bus.events')->getArgument(0));
544+
545+
$this->assertTrue($container->has(TolerateNoHandler::class));
546+
$this->assertTrue($container->getDefinition(TolerateNoHandler::class)->hasTag('message_bus_middleware'));
547+
548+
$this->assertTrue($container->hasAlias('message_bus'));
549+
$this->assertEquals('messenger.bus.commands', (string) $container->getAlias('message_bus'));
550+
551+
$this->assertEquals(array('commands', 'events'), $container->getParameter('messenger.buses_names'));
552+
}
553+
535554
public function testTranslator()
536555
{
537556
$container = $this->createContainerFromFile('full');

src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@ class MessengerPass implements CompilerPassInterface
2929
{
3030
use PriorityTaggedServiceTrait;
3131

32-
private $messageBusService;
3332
private $messageHandlerResolverService;
3433
private $handlerTag;
3534

36-
public function __construct(string $messageBusService = 'message_bus', string $messageHandlerResolverService = 'messenger.handler_resolver', string $handlerTag = 'messenger.message_handler')
35+
public function __construct(string $messageHandlerResolverService = 'messenger.handler_resolver', string $handlerTag = 'messenger.message_handler')
3736
{
38-
$this->messageBusService = $messageBusService;
3937
$this->messageHandlerResolverService = $messageHandlerResolverService;
4038
$this->handlerTag = $handlerTag;
4139
}
@@ -45,7 +43,7 @@ public function __construct(string $messageBusService = 'message_bus', string $m
4543
*/
4644
public function process(ContainerBuilder $container)
4745
{
48-
if (!$container->hasDefinition($this->messageBusService)) {
46+
if (!$container->hasDefinition('messenger.handler_resolver')) {
4947
return;
5048
}
5149

@@ -61,6 +59,7 @@ public function process(ContainerBuilder $container)
6159

6260
$this->registerReceivers($container);
6361
$this->registerHandlers($container);
62+
$this->registerMiddlewares($container);
6463
}
6564

6665
private function registerHandlers(ContainerBuilder $container)
@@ -162,4 +161,34 @@ private function registerReceivers(ContainerBuilder $container)
162161

163162
$container->getDefinition('messenger.receiver_locator')->replaceArgument(0, $receiverMapping);
164163
}
164+
165+
private function registerMiddlewares(ContainerBuilder $container)
166+
{
167+
if (!$container->hasParameter('messenger.buses_names')) {
168+
return;
169+
}
170+
171+
$busesNames = $container->getParameter('messenger.buses_names');
172+
$middlewaresPerBuses = array();
173+
174+
foreach ($container->findTaggedServiceIds('message_bus_middleware') as $serviceId => $tags) {
175+
foreach ($tags as $tag) {
176+
$priority = $tag['priority'] ?? 0;
177+
$buses = isset($tag['bus']) ? explode(',', $tag['bus']) : $busesNames;
178+
179+
foreach ($buses as $bus) {
180+
$middlewaresPerBuses[$bus][$priority][] = new Reference($serviceId);
181+
}
182+
}
183+
}
184+
185+
foreach ($middlewaresPerBuses as $bus => $middlewares) {
186+
krsort($middlewaresPerBuses[$bus]);
187+
$middlewaresPerBuses[$bus] = call_user_func_array('array_merge', $middlewaresPerBuses[$bus]);
188+
}
189+
190+
foreach ($middlewaresPerBuses as $name => $middlewares) {
191+
$container->getDefinition('messenger.bus.'.$name)->replaceArgument(0, $middlewares);
192+
}
193+
}
165194
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Middleware;
13+
14+
use Symfony\Component\Messenger\Exception\NoHandlerForMessageException;
15+
use Symfony\Component\Messenger\MiddlewareInterface;
16+
17+
/**
18+
* @author Samuel Roze <[email protected]>
19+
*/
20+
class TolerateNoHandler implements MiddlewareInterface
21+
{
22+
public function handle($message, callable $next)
23+
{
24+
try {
25+
return $next($message);
26+
} catch (NoHandlerForMessageException $e) {
27+
// We tolerate not having a handler for this message.
28+
}
29+
}
30+
}

src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,22 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Definition;
1718
use Symfony\Component\DependencyInjection\Reference;
1819
use Symfony\Component\DependencyInjection\ServiceLocator;
20+
use Symfony\Component\Messenger\Asynchronous\Middleware\SendMessageMiddleware;
1921
use Symfony\Component\Messenger\ContainerHandlerLocator;
2022
use Symfony\Component\Messenger\DependencyInjection\MessengerPass;
2123
use Symfony\Component\Messenger\Handler\ChainHandler;
2224
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
25+
use Symfony\Component\Messenger\MessageBus;
26+
use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware;
27+
use Symfony\Component\Messenger\Middleware\TolerateNoHandler;
28+
use Symfony\Component\Messenger\Middleware\ValidationMiddleware;
2329
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
2430
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
2531
use Symfony\Component\Messenger\Transport\ReceiverInterface;
32+
use Symfony\Component\Validator\Validator\ValidatorInterface;
2633

2734
class MessengerPassTest extends TestCase
2835
{
@@ -88,6 +95,30 @@ public function testGetClassesFromTheHandlerSubscriberInterface()
8895
$this->assertEquals(array(new Reference(PrioritizedHandler::class), new Reference(HandlerWithMultipleMessages::class)), $definition->getArgument(0));
8996
}
9097

98+
public function testRegistersMiddlewares()
99+
{
100+
$validator = $this->getMockBuilder(ValidatorInterface::class)->getMock();
101+
102+
$container = $this->getContainerBuilder();
103+
$container->setDefinition('messenger.bus.events', new Definition(MessageBus::class, array(array())));
104+
$container->setDefinition('messenger.bus.commands', new Definition(MessageBus::class, array(array())));
105+
$container->setDefinition(HandleMessageMiddleware::class, (new Definition(HandleMessageMiddleware::class))->addTag('message_bus_middleware', array('priority' => -10)));
106+
$container->setDefinition(SendMessageMiddleware::class, (new Definition(SendMessageMiddleware::class))->addTag('message_bus_middleware', array('priority' => -5, 'bus' => 'events')))->addTag('message_bus_middleware', array('priority' => 10, 'bus' => 'commands'));
107+
$container->setDefinition(TolerateNoHandler::class, (new Definition(TolerateNoHandler::class))->addTag('message_bus_middleware', array('bus' => 'events')));
108+
$container->setDefinition(ValidationMiddleware::class, (new Definition(ValidationMiddleware::class, array($validator)))->addTag('message_bus_middleware', array('bus' => 'commands')));
109+
$container->setParameter('messenger.buses_names', array('events', 'commands'));
110+
111+
(new MessengerPass())->process($container);
112+
113+
$eventBusArguments = $container->getDefinition('messenger.bus.events')->getArguments();
114+
$this->assertCount(1, $eventBusArguments);
115+
$this->assertEquals(array(new Reference(TolerateNoHandler::class), new Reference(SendMessageMiddleware::class), new Reference(HandleMessageMiddleware::class)), $eventBusArguments[0]);
116+
117+
$commandBusArguments = $container->getDefinition('messenger.bus.commands')->getArguments();
118+
$this->assertCount(1, $commandBusArguments);
119+
$this->assertEquals(array(new Reference(SendMessageMiddleware::class), new Reference(ValidationMiddleware::class), new Reference(HandleMessageMiddleware::class)), $commandBusArguments[0]);
120+
}
121+
91122
/**
92123
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
93124
* @expectedExceptionMessage Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandler": message class "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" used as argument type in method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandler::__invoke()" does not exist.
@@ -197,7 +228,6 @@ private function getContainerBuilder(): ContainerBuilder
197228
{
198229
$container = new ContainerBuilder();
199230
$container->setParameter('kernel.debug', true);
200-
$container->register('message_bus', ContainerHandlerLocator::class);
201231

202232
$container
203233
->register('messenger.handler_resolver', ContainerHandlerLocator::class)

0 commit comments

Comments
 (0)