Skip to content

Commit

Permalink
bug #31472 [Messenger] Fix routable message bus default bus (weaverryan)
Browse files Browse the repository at this point in the history
This PR was merged into the 4.3 branch.

Discussion
----------

[Messenger] Fix routable message bus default bus

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | none
| License       | MIT
| Doc PR        | not needed

In #31288, we gave the `RoutableMessageBus` a "default" bus. We did that by using the `MessageBusInterface` service in the locator. But, no such service exists - I think that was just a huge oversight (and maybe @dirk39 named a bus this in the project he was testing on?). The services in the locator are very simply the keys under `framework.messenger.buses` or the default, which is a single `messenger.bus.default` id. There is an alias in the container for `MessageBusInterface`, but this is not added to the locator (and adding it would be a bit awkward, as `MessengerPass` is in the component and the interface alias is entirely a framework thing).

Cheers!

Commits
-------

42e0536 Changing how RoutableMessageBus fallback bus works
  • Loading branch information
Tobion committed May 11, 2019
2 parents 008de04 + 42e0536 commit fe0f324
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 20 deletions.
Expand Up @@ -106,6 +106,7 @@
<!-- routable message bus -->
<service id="messenger.routable_message_bus" class="Symfony\Component\Messenger\RoutableMessageBus">
<argument /> <!-- Message bus locator -->
<argument type="service" id="messenger.default_bus" />
</service>
</services>
</container>
24 changes: 20 additions & 4 deletions src/Symfony/Component/Messenger/RoutableMessageBus.php
Expand Up @@ -28,13 +28,15 @@
class RoutableMessageBus implements MessageBusInterface
{
private $busLocator;
private $fallbackBus;

/**
* @param ContainerInterface $busLocator A locator full of MessageBusInterface objects
*/
public function __construct(ContainerInterface $busLocator)
public function __construct(ContainerInterface $busLocator, MessageBusInterface $fallbackBus = null)
{
$this->busLocator = $busLocator;
$this->fallbackBus = $fallbackBus;
}

public function dispatch($envelope, array $stamps = []): Envelope
Expand All @@ -43,14 +45,28 @@ public function dispatch($envelope, array $stamps = []): Envelope
throw new InvalidArgumentException('Messages passed to RoutableMessageBus::dispatch() must be inside an Envelope');
}

/** @var BusNameStamp $busNameStamp */
return $this->getMessageBus($envelope)->dispatch($envelope, $stamps);
}

private function getMessageBus(Envelope $envelope): MessageBusInterface
{
/** @var BusNameStamp|null $busNameStamp */
$busNameStamp = $envelope->last(BusNameStamp::class);
$busName = null !== $busNameStamp ? $busNameStamp->getBusName() : MessageBusInterface::class;

if (null === $busNameStamp) {
if (null === $this->fallbackBus) {
throw new InvalidArgumentException(sprintf('Envelope is missing a BusNameStamp and no fallback message bus is configured on RoutableMessageBus.'));
}

return $this->fallbackBus;
}

$busName = $busNameStamp->getBusName();

if (!$this->busLocator->has($busName)) {
throw new InvalidArgumentException(sprintf('Bus named "%s" does not exist.', $busName));
}

return $this->busLocator->get($busName)->dispatch($envelope, $stamps);
return $this->busLocator->get($busName);
}
}
25 changes: 9 additions & 16 deletions src/Symfony/Component/Messenger/Tests/RoutableMessageBusTest.php
Expand Up @@ -50,41 +50,34 @@ public function testItRoutesToDefaultBus()
->willReturn($envelope);

$container = $this->createMock(ContainerInterface::class);
$container->expects($this->once())->method('has')->with(MessageBusInterface::class)
->willReturn(true);
$container->expects($this->once())->method('get')->with(MessageBusInterface::class)
->willReturn($defaultBus);

$routableBus = new RoutableMessageBus($container);
$routableBus = new RoutableMessageBus($container, $defaultBus);

$this->assertSame($envelope, $routableBus->dispatch($envelope, [$stamp]));
}

public function testItExceptionOnDefaultBusNotFound()
public function testItExceptionOnBusNotFound()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage(sprintf('Bus named "%s" does not exist.', MessageBusInterface::class));
$this->expectExceptionMessage('Bus named "my_cool_bus" does not exist.');

$envelope = new Envelope(new \stdClass());
$envelope = new Envelope(new \stdClass(), [
new BusNameStamp('my_cool_bus'),
]);

$container = $this->createMock(ContainerInterface::class);
$container->expects($this->once())->method('has')->with(MessageBusInterface::class)
->willReturn(false);

$routableBus = new RoutableMessageBus($container);
$routableBus->dispatch($envelope);
}

public function testItExceptionOnBusNotFound()
public function testItExceptionOnDefaultBusNotFound()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage(sprintf('Bus named "%s" does not exist.', 'foo_bus'));
$this->expectExceptionMessage('Envelope is missing a BusNameStamp and no fallback message bus is configured on RoutableMessageBus.');

$envelope = new Envelope(new \stdClass(), [new BusNameStamp('foo_bus')]);
$envelope = new Envelope(new \stdClass());

$container = $this->createMock(ContainerInterface::class);
$container->expects($this->once())->method('has')->willReturn(false);

$routableBus = new RoutableMessageBus($container);
$routableBus->dispatch($envelope);
}
Expand Down

0 comments on commit fe0f324

Please sign in to comment.