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

Skip to content

Commit c352f53

Browse files
brzuchalnicolas-grekas
authored andcommitted
[FrameworkBundle][Messenger] Add support for namespace wildcard in Messenger routing
1 parent fcfca3e commit c352f53

12 files changed

+101
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Add `DomCrawlerAssertionsTrait::assertSelectorCount(int $count, string $selector)`
88
* Allow to avoid `limit` definition in a RateLimiter configuration when using the `no_limit` policy
99
* Add `--format` option to the `debug:config` command
10+
* Add support to pass namespace wildcard in `framework.messenger.routing`
1011

1112
6.2
1213
---

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2159,7 +2159,11 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
21592159

21602160
$messageToSendersMapping = [];
21612161
foreach ($config['routing'] as $message => $messageConfiguration) {
2162-
if ('*' !== $message && !class_exists($message) && !interface_exists($message, false)) {
2162+
if ('*' !== $message && !class_exists($message) && !interface_exists($message, false) && !preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\\)++\*$/', $message)) {
2163+
if (str_contains($message, '*')) {
2164+
throw new LogicException(sprintf('Invalid Messenger routing configuration: invalid namespace "%s" wildcard.', $message));
2165+
}
2166+
21632167
throw new LogicException(sprintf('Invalid Messenger routing configuration: class or interface "%s" not found.', $message));
21642168
}
21652169

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_routing.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
SecondMessage::class => [
1616
'senders' => ['amqp', 'audit'],
1717
],
18+
'Symfony\*' => 'amqp',
1819
'*' => 'amqp',
1920
],
2021
'transports' => [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'http_method_override' => false,
5+
'serializer' => true,
6+
'messenger' => [
7+
'serializer' => [
8+
'default_serializer' => 'messenger.transport.symfony_serializer',
9+
],
10+
'routing' => [
11+
'Symfony\*\DummyMessage' => ['audit'],
12+
],
13+
'transports' => [
14+
'audit' => 'null://',
15+
],
16+
],
17+
]);

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_routing.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
<framework:routing message-class="*">
2121
<framework:sender service="amqp" />
2222
</framework:routing>
23+
<framework:routing message-class="Symfony\*">
24+
<framework:sender service="amqp" />
25+
</framework:routing>
2326
<framework:transport name="amqp" dsn="amqp://localhost/%2f/messages" />
2427
<framework:transport name="audit" dsn="null://" />
2528
</framework:messenger>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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 https://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<framework:config http-method-override="false">
9+
<framework:serializer enabled="true" />
10+
<framework:messenger>
11+
<framework:serializer default-serializer="messenger.transport.symfony_serializer" />
12+
<framework:routing message-class="Symfony\*\DummyMessage">
13+
<framework:sender service="audit" />
14+
</framework:routing>
15+
<framework:transport name="audit" dsn="null://" />
16+
</framework:messenger>
17+
</framework:config>
18+
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_routing.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ framework:
88
'Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummyMessage': [amqp, messenger.transport.audit]
99
'Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\SecondMessage':
1010
senders: [amqp, audit]
11+
'Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\*': [amqp]
12+
'Symfony\*': [amqp]
1113
'*': amqp
1214
transports:
1315
amqp: 'amqp://localhost/%2f/messages'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
framework:
2+
http_method_override: false
3+
serializer: true
4+
messenger:
5+
serializer:
6+
default_serializer: messenger.transport.symfony_serializer
7+
routing:
8+
'Symfony\*\DummyMessage': [audit]
9+
transports:
10+
audit: 'null://'

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,13 @@ public function testMessengerMiddlewareFactoryErroneousFormat()
10591059
}
10601060

10611061
public function testMessengerInvalidTransportRouting()
1062+
{
1063+
$this->expectException(\LogicException::class);
1064+
$this->expectExceptionMessage('Invalid Messenger routing configuration: invalid namespace "Symfony\*\DummyMessage" wildcard.');
1065+
$this->createContainerFromFile('messenger_routing_invalid_wildcard');
1066+
}
1067+
1068+
public function testMessengerInvalidWildcardRouting()
10621069
{
10631070
$this->expectException(\LogicException::class);
10641071
$this->expectExceptionMessage('Invalid Messenger routing configuration: the "Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummyMessage" class is being routed to a sender called "invalid". This is not a valid transport or service id.');

src/Symfony/Component/Messenger/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
6.3
55
---
66

7+
* Add support for namespace wildcards in the HandlersLocator to allow routing multiple messages within the same namespace
78
* Deprecate `Symfony\Component\Messenger\Transport\InMemoryTransport` and
89
`Symfony\Component\Messenger\Transport\InMemoryTransportFactory` in favor of
910
`Symfony\Component\Messenger\Transport\InMemory\InMemoryTransport` and

src/Symfony/Component/Messenger/Handler/HandlersLocator.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,22 @@ public static function listTypes(Envelope $envelope): array
6868
return [$class => $class]
6969
+ class_parents($class)
7070
+ class_implements($class)
71+
+ self::listWildcards($class)
7172
+ ['*' => '*'];
7273
}
7374

75+
private static function listWildcards(string $type): array
76+
{
77+
$type .= '\*';
78+
$wildcards = [];
79+
while ($i = strrpos($type, '\\', -3)) {
80+
$type = substr_replace($type, '\*', $i);
81+
$wildcards[$type] = $type;
82+
}
83+
84+
return $wildcards;
85+
}
86+
7487
private function shouldHandle(Envelope $envelope, HandlerDescriptor $handlerDescriptor): bool
7588
{
7689
if (null === $received = $envelope->last(ReceivedStamp::class)) {

src/Symfony/Component/Messenger/Tests/Handler/HandlersLocatorTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,29 @@ public function testItReturnsOnlyHandlersMatchingTransport()
5656
new Envelope(new DummyMessage('Body'), [new ReceivedStamp('transportName')])
5757
)));
5858
}
59+
60+
public function testItReturnsOnlyHandlersMatchingMessageNamespace()
61+
{
62+
$firstHandler = $this->createPartialMock(HandlersLocatorTestCallable::class, ['__invoke']);
63+
$secondHandler = $this->createPartialMock(HandlersLocatorTestCallable::class, ['__invoke']);
64+
65+
$locator = new HandlersLocator([
66+
str_replace('DummyMessage', '*', DummyMessage::class) => [
67+
$first = new HandlerDescriptor($firstHandler, ['alias' => 'one']),
68+
],
69+
str_replace('Fixtures\\DummyMessage', '*', DummyMessage::class) => [
70+
$second = new HandlerDescriptor($secondHandler, ['alias' => 'two']),
71+
],
72+
]);
73+
74+
$first->getName();
75+
$second->getName();
76+
77+
$this->assertEquals([
78+
$first,
79+
$second,
80+
], iterator_to_array($locator->getHandlers(new Envelope(new DummyMessage('Body')))));
81+
}
5982
}
6083

6184
class HandlersLocatorTestCallable

0 commit comments

Comments
 (0)