From f15cf64fdf575c555f138c34472b2c9ebbd60489 Mon Sep 17 00:00:00 2001 From: Oskar Pfeifer-Bley Date: Wed, 2 May 2018 08:47:25 +0200 Subject: [PATCH 1/4] Verify that popo command handlers cannot be automatically detected --- .../AbstractServiceBusExtensionTestCase.php | 21 +++++++++++++++++++ .../Model/CommandHandlerForPopoCommand.php | 16 ++++++++++++++ .../Fixture/Model/PopoCommand.php | 9 ++++++++ .../config/xml/command_bus_with_tags.xml | 3 +++ .../config/yml/command_bus_with_tags.yml | 5 +++++ 5 files changed, 54 insertions(+) create mode 100644 test/DependencyInjection/Fixture/Model/CommandHandlerForPopoCommand.php create mode 100644 test/DependencyInjection/Fixture/Model/PopoCommand.php diff --git a/test/DependencyInjection/AbstractServiceBusExtensionTestCase.php b/test/DependencyInjection/AbstractServiceBusExtensionTestCase.php index 7278969..7642ca4 100644 --- a/test/DependencyInjection/AbstractServiceBusExtensionTestCase.php +++ b/test/DependencyInjection/AbstractServiceBusExtensionTestCase.php @@ -31,8 +31,10 @@ use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\AcmeRegisterUserCommand; use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\AcmeRegisterUserHandler; use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\AcmeUserWasRegisteredEvent; +use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandHandlerForPopoCommand; use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandWithPrivateConstructor; use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\MockPlugin; +use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\PopoCommand; use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; @@ -357,6 +359,25 @@ public function it_adds_command_bus_routes_based_on_tags_with_automatic_message_ $commandBus->dispatch(CommandWithPrivateConstructor::create()); } + /** + * @test + */ + public function it_supports_automatic_message_detection_with_popo_messages_and_invokable_handlers() + { + $container = $this->loadContainer('command_bus_with_tags', new PluginsPass(), new RoutePass()); + + /* @var $commandBus CommandBus */ + $commandBus = $container->get('prooph_service_bus.main_command_bus'); + + /** @var CommandHandlerForPopoCommand $mockHandler */ + $mockHandler = $container->get(CommandHandlerForPopoCommand::class); + $command = new PopoCommand(); + + $commandBus->dispatch($command); + + self::assertSame($command, $mockHandler->lastCommand); + } + /** * @test */ diff --git a/test/DependencyInjection/Fixture/Model/CommandHandlerForPopoCommand.php b/test/DependencyInjection/Fixture/Model/CommandHandlerForPopoCommand.php new file mode 100644 index 0000000..4fd2bbb --- /dev/null +++ b/test/DependencyInjection/Fixture/Model/CommandHandlerForPopoCommand.php @@ -0,0 +1,16 @@ +lastCommand = $command; + } +} diff --git a/test/DependencyInjection/Fixture/Model/PopoCommand.php b/test/DependencyInjection/Fixture/Model/PopoCommand.php new file mode 100644 index 0000000..52522c3 --- /dev/null +++ b/test/DependencyInjection/Fixture/Model/PopoCommand.php @@ -0,0 +1,9 @@ + + + + diff --git a/test/DependencyInjection/Fixture/config/yml/command_bus_with_tags.yml b/test/DependencyInjection/Fixture/config/yml/command_bus_with_tags.yml index 6b6d95f..904c0d9 100644 --- a/test/DependencyInjection/Fixture/config/yml/command_bus_with_tags.yml +++ b/test/DependencyInjection/Fixture/config/yml/command_bus_with_tags.yml @@ -19,3 +19,8 @@ services: ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandHandlerForCommandWithPrivateConstructor: tags: - { name: 'prooph_service_bus.main_command_bus.route_target', message_detection: true } + + ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandHandlerForPopoCommand: + public: true + tags: + - { name: 'prooph_service_bus.main_command_bus.route_target', message_detection: true } From 8b2d329c4c28135f456ac7aaffbbc5bf3d93e2ee Mon Sep 17 00:00:00 2001 From: Oskar Pfeifer-Bley Date: Wed, 2 May 2018 08:55:32 +0200 Subject: [PATCH 2/4] Detect handlers for popo-messages --- doc/routing.md | 4 ++++ src/DependencyInjection/Compiler/RoutePass.php | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/routing.md b/doc/routing.md index ef8c008..2a7ce2a 100644 --- a/doc/routing.md +++ b/doc/routing.md @@ -61,6 +61,10 @@ The bundle will try to detect the message itself by analyzing the methods of the handler and creating instances of the message objects. But don't worry about performance because this will happen on compiling. +> **Important:** Automatic message detection can only detect handlers where either +> the message implements `Prooph\Common\Messaging\HasMessageName` or the +> name of the message is `__invoke`. In both cases the object must be a non abstract class. + > **Hint:** If you rely on automatic message detection and your handler handles multiple messages of the same message bus, > you need to tag the handler just once. diff --git a/src/DependencyInjection/Compiler/RoutePass.php b/src/DependencyInjection/Compiler/RoutePass.php index 2143fe9..c21528f 100644 --- a/src/DependencyInjection/Compiler/RoutePass.php +++ b/src/DependencyInjection/Compiler/RoutePass.php @@ -18,6 +18,9 @@ class RoutePass implements CompilerPassInterface { private static function detectMessageName(ReflectionClass $messageReflection): ?string { + if (! $messageReflection->implementsInterface(HasMessageName::class)) { + return $messageReflection->getName(); + } $instance = $messageReflection->newInstanceWithoutConstructor(); /* @var $instance HasMessageName */ if ($messageReflection->hasMethod('init')) { $init = $messageReflection->getMethod('init'); @@ -111,7 +114,8 @@ private function recognizeMessageNames( function (ReflectionMethod $method) { return ($method->getNumberOfRequiredParameters() === 1 || $method->getNumberOfRequiredParameters() === 2) && $method->getParameters()[0]->getClass() - && $method->getParameters()[0]->getClass()->implementsInterface(HasMessageName::class) + && ($method->getParameters()[0]->getClass()->implementsInterface(HasMessageName::class) + || $method->getName() === '__invoke') && ! ($method->getParameters()[0]->getClass()->isInterface() || $method->getParameters()[0]->getClass()->isAbstract() || $method->getParameters()[0]->getClass()->isTrait()); From 658217d916fb194c9b144aa8854b8483336c6100 Mon Sep 17 00:00:00 2001 From: Oskar Pfeifer-Bley Date: Wed, 2 May 2018 09:18:58 +0200 Subject: [PATCH 3/4] Fix tests with service-bus:v6.0.0 --- .../Fixture/Model/CommandHandlerForPopoCommand.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/DependencyInjection/Fixture/Model/CommandHandlerForPopoCommand.php b/test/DependencyInjection/Fixture/Model/CommandHandlerForPopoCommand.php index 4fd2bbb..c1a972e 100644 --- a/test/DependencyInjection/Fixture/Model/CommandHandlerForPopoCommand.php +++ b/test/DependencyInjection/Fixture/Model/CommandHandlerForPopoCommand.php @@ -13,4 +13,13 @@ public function __invoke(PopoCommand $command) { $this->lastCommand = $command; } + + /** + * Do not take notice of this method. + * It is necessary to run the tests against prooph/service-bus:6.0.0 + * @see https://github.com/prooph/service-bus/pull/159 + */ + public function handle(): void + { + } } From df3c5366bbd34407eb215b8b68749de593738ac5 Mon Sep 17 00:00:00 2001 From: Oskar Pfeifer-Bley Date: Fri, 4 May 2018 07:18:27 +0200 Subject: [PATCH 4/4] Fix wrong word in docs --- doc/routing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/routing.md b/doc/routing.md index 2a7ce2a..110f5a0 100644 --- a/doc/routing.md +++ b/doc/routing.md @@ -63,7 +63,7 @@ But don't worry about performance because this will happen on compiling. > **Important:** Automatic message detection can only detect handlers where either > the message implements `Prooph\Common\Messaging\HasMessageName` or the -> name of the message is `__invoke`. In both cases the object must be a non abstract class. +> name of the method is `__invoke`. In both cases the object must be a non abstract class. > **Hint:** If you rely on automatic message detection and your handler handles multiple messages of the same message bus, > you need to tag the handler just once.