[Messenger] Envelope-aware middleware is never called with a message

This commit is contained in:
Thomas Royer 2018-07-04 11:40:13 +02:00
parent c1f23c859e
commit 9488e2a026
6 changed files with 41 additions and 30 deletions

View File

@ -83,6 +83,11 @@ FrameworkBundle
this will generate 404s for non-UTF-8 URLs, which are incompatible with you app anyway, this will generate 404s for non-UTF-8 URLs, which are incompatible with you app anyway,
and will allow dumping optimized routers and using Unicode classes in requirements. and will allow dumping optimized routers and using Unicode classes in requirements.
Messenger
---------
* The `handle` method of the `Symfony\Component\Messenger\Middleware\ValidationMiddleware` and `Symfony\Component\Messenger\Asynchronous\Middleware\SendMessageMiddleware` middlewares now requires an `Envelope` object to be given (because they implement the `EnvelopeAwareInterface`). When using these middleware with the provided `MessageBus`, you will not have to do anything. If you use the middlewares any other way, you can use `Envelope::wrap($message)` to create an envelope for your message.
Security Security
-------- --------

View File

@ -34,14 +34,15 @@ class SendMessageMiddleware implements MiddlewareInterface, EnvelopeAwareInterfa
} }
/** /**
* @param Envelope $envelope
*
* {@inheritdoc} * {@inheritdoc}
*/ */
public function handle($message, callable $next) public function handle($envelope, callable $next)
{ {
$envelope = Envelope::wrap($message);
if ($envelope->get(ReceivedMessage::class)) { if ($envelope->get(ReceivedMessage::class)) {
// It's a received message. Do not send it back: // It's a received message. Do not send it back:
return $next($message); return $next($envelope);
} }
$sender = $this->senderLocator->getSenderForMessage($envelope->getMessage()); $sender = $this->senderLocator->getSenderForMessage($envelope->getMessage());
@ -54,7 +55,7 @@ class SendMessageMiddleware implements MiddlewareInterface, EnvelopeAwareInterfa
} }
} }
return $next($message); return $next($envelope);
} }
private function mustSendAndHandle($message): bool private function mustSendAndHandle($message): bool

View File

@ -37,12 +37,12 @@ class ActivationMiddlewareDecorator implements MiddlewareInterface, EnvelopeAwar
/** /**
* @param Envelope $message * @param Envelope $message
*/ */
public function handle($message, callable $next) public function handle($envelope, callable $next)
{ {
if (\is_callable($this->activated) ? ($this->activated)($message) : $this->activated) { if (\is_callable($this->activated) ? ($this->activated)($envelope) : $this->activated) {
return $this->inner->handle($message->getMessageFor($this->inner), $next); return $this->inner->handle($envelope->getMessageFor($this->inner), $next);
} }
return $next($message); return $next($envelope);
} }
} }

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Messenger\Middleware; namespace Symfony\Component\Messenger\Middleware;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\EnvelopeAwareInterface; use Symfony\Component\Messenger\EnvelopeAwareInterface;
use Symfony\Component\Messenger\Exception\ValidationFailedException; use Symfony\Component\Messenger\Exception\ValidationFailedException;
use Symfony\Component\Messenger\Middleware\Configuration\ValidationConfiguration; use Symfony\Component\Messenger\Middleware\Configuration\ValidationConfiguration;
@ -29,21 +28,20 @@ class ValidationMiddleware implements MiddlewareInterface, EnvelopeAwareInterfac
$this->validator = $validator; $this->validator = $validator;
} }
public function handle($message, callable $next) public function handle($envelope, callable $next)
{ {
$envelope = Envelope::wrap($message); $message = $envelope->getMessage();
$subject = $envelope->getMessage();
$groups = null; $groups = null;
/** @var ValidationConfiguration|null $validationConfig */ /** @var ValidationConfiguration|null $validationConfig */
if ($validationConfig = $envelope->get(ValidationConfiguration::class)) { if ($validationConfig = $envelope->get(ValidationConfiguration::class)) {
$groups = $validationConfig->getGroups(); $groups = $validationConfig->getGroups();
} }
$violations = $this->validator->validate($subject, null, $groups); $violations = $this->validator->validate($message, null, $groups);
if (\count($violations)) { if (\count($violations)) {
throw new ValidationFailedException($subject, $violations); throw new ValidationFailedException($message, $violations);
} }
return $next($message); return $next($envelope);
} }
} }

View File

@ -26,15 +26,16 @@ class SendMessageMiddlewareTest extends TestCase
public function testItSendsTheMessageToAssignedSender() public function testItSendsTheMessageToAssignedSender()
{ {
$message = new DummyMessage('Hey'); $message = new DummyMessage('Hey');
$envelope = Envelope::wrap($message);
$sender = $this->getMockBuilder(SenderInterface::class)->getMock(); $sender = $this->getMockBuilder(SenderInterface::class)->getMock();
$next = $this->createPartialMock(\stdClass::class, array('__invoke')); $next = $this->createPartialMock(\stdClass::class, array('__invoke'));
$middleware = new SendMessageMiddleware(new InMemorySenderLocator($sender)); $middleware = new SendMessageMiddleware(new InMemorySenderLocator($sender));
$sender->expects($this->once())->method('send')->with(Envelope::wrap($message)); $sender->expects($this->once())->method('send')->with($envelope);
$next->expects($this->never())->method($this->anything()); $next->expects($this->never())->method($this->anything());
$middleware->handle($message, $next); $middleware->handle($envelope, $next);
} }
public function testItSendsTheMessageToAssignedSenderWithPreWrappedMessage() public function testItSendsTheMessageToAssignedSenderWithPreWrappedMessage()
@ -54,6 +55,7 @@ class SendMessageMiddlewareTest extends TestCase
public function testItAlsoCallsTheNextMiddlewareBasedOnTheMessageClass() public function testItAlsoCallsTheNextMiddlewareBasedOnTheMessageClass()
{ {
$message = new DummyMessage('Hey'); $message = new DummyMessage('Hey');
$envelope = Envelope::wrap($message);
$sender = $this->getMockBuilder(SenderInterface::class)->getMock(); $sender = $this->getMockBuilder(SenderInterface::class)->getMock();
$next = $this->createPartialMock(\stdClass::class, array('__invoke')); $next = $this->createPartialMock(\stdClass::class, array('__invoke'));
@ -61,15 +63,16 @@ class SendMessageMiddlewareTest extends TestCase
DummyMessage::class => true, DummyMessage::class => true,
)); ));
$sender->expects($this->once())->method('send')->with(Envelope::wrap($message)); $sender->expects($this->once())->method('send')->with($envelope);
$next->expects($this->once())->method($this->anything()); $next->expects($this->once())->method($this->anything());
$middleware->handle($message, $next); $middleware->handle($envelope, $next);
} }
public function testItAlsoCallsTheNextMiddlewareBasedOnTheMessageParentClass() public function testItAlsoCallsTheNextMiddlewareBasedOnTheMessageParentClass()
{ {
$message = new ChildDummyMessage('Hey'); $message = new ChildDummyMessage('Hey');
$envelope = Envelope::wrap($message);
$sender = $this->getMockBuilder(SenderInterface::class)->getMock(); $sender = $this->getMockBuilder(SenderInterface::class)->getMock();
$next = $this->createPartialMock(\stdClass::class, array('__invoke')); $next = $this->createPartialMock(\stdClass::class, array('__invoke'));
@ -77,15 +80,16 @@ class SendMessageMiddlewareTest extends TestCase
DummyMessage::class => true, DummyMessage::class => true,
)); ));
$sender->expects($this->once())->method('send')->with(Envelope::wrap($message)); $sender->expects($this->once())->method('send')->with($envelope);
$next->expects($this->once())->method($this->anything()); $next->expects($this->once())->method($this->anything());
$middleware->handle($message, $next); $middleware->handle($envelope, $next);
} }
public function testItAlsoCallsTheNextMiddlewareBasedOnTheMessageInterface() public function testItAlsoCallsTheNextMiddlewareBasedOnTheMessageInterface()
{ {
$message = new DummyMessage('Hey'); $message = new DummyMessage('Hey');
$envelope = Envelope::wrap($message);
$sender = $this->getMockBuilder(SenderInterface::class)->getMock(); $sender = $this->getMockBuilder(SenderInterface::class)->getMock();
$next = $this->createPartialMock(\stdClass::class, array('__invoke')); $next = $this->createPartialMock(\stdClass::class, array('__invoke'));
@ -93,15 +97,16 @@ class SendMessageMiddlewareTest extends TestCase
DummyMessageInterface::class => true, DummyMessageInterface::class => true,
)); ));
$sender->expects($this->once())->method('send')->with(Envelope::wrap($message)); $sender->expects($this->once())->method('send')->with($envelope);
$next->expects($this->once())->method($this->anything()); $next->expects($this->once())->method($this->anything());
$middleware->handle($message, $next); $middleware->handle($envelope, $next);
} }
public function testItAlsoCallsTheNextMiddlewareBasedOnWildcard() public function testItAlsoCallsTheNextMiddlewareBasedOnWildcard()
{ {
$message = new DummyMessage('Hey'); $message = new DummyMessage('Hey');
$envelope = Envelope::wrap($message);
$sender = $this->getMockBuilder(SenderInterface::class)->getMock(); $sender = $this->getMockBuilder(SenderInterface::class)->getMock();
$next = $this->createPartialMock(\stdClass::class, array('__invoke')); $next = $this->createPartialMock(\stdClass::class, array('__invoke'));
@ -109,22 +114,23 @@ class SendMessageMiddlewareTest extends TestCase
'*' => true, '*' => true,
)); ));
$sender->expects($this->once())->method('send')->with(Envelope::wrap($message)); $sender->expects($this->once())->method('send')->with($envelope);
$next->expects($this->once())->method($this->anything()); $next->expects($this->once())->method($this->anything());
$middleware->handle($message, $next); $middleware->handle($envelope, $next);
} }
public function testItCallsTheNextMiddlewareWhenNoSenderForThisMessage() public function testItCallsTheNextMiddlewareWhenNoSenderForThisMessage()
{ {
$message = new DummyMessage('Hey'); $message = new DummyMessage('Hey');
$envelope = Envelope::wrap($message);
$next = $this->createPartialMock(\stdClass::class, array('__invoke')); $next = $this->createPartialMock(\stdClass::class, array('__invoke'));
$middleware = new SendMessageMiddleware(new InMemorySenderLocator(null)); $middleware = new SendMessageMiddleware(new InMemorySenderLocator(null));
$next->expects($this->once())->method($this->anything()); $next->expects($this->once())->method($this->anything());
$middleware->handle($message, $next); $middleware->handle($envelope, $next);
} }
public function testItSkipsReceivedMessages() public function testItSkipsReceivedMessages()

View File

@ -24,6 +24,7 @@ class ValidationMiddlewareTest extends TestCase
public function testValidateAndNextMiddleware() public function testValidateAndNextMiddleware()
{ {
$message = new DummyMessage('Hey'); $message = new DummyMessage('Hey');
$envelope = Envelope::wrap($message);
$validator = $this->createMock(ValidatorInterface::class); $validator = $this->createMock(ValidatorInterface::class);
$validator $validator
@ -36,11 +37,11 @@ class ValidationMiddlewareTest extends TestCase
$next $next
->expects($this->once()) ->expects($this->once())
->method('__invoke') ->method('__invoke')
->with($message) ->with($envelope)
->willReturn('Hello') ->willReturn('Hello')
; ;
$result = (new ValidationMiddleware($validator))->handle($message, $next); $result = (new ValidationMiddleware($validator))->handle($envelope, $next);
$this->assertSame('Hello', $result); $this->assertSame('Hello', $result);
} }
@ -48,7 +49,6 @@ class ValidationMiddlewareTest extends TestCase
public function testValidateWithConfigurationAndNextMiddleware() public function testValidateWithConfigurationAndNextMiddleware()
{ {
$envelope = Envelope::wrap($message = new DummyMessage('Hey'))->with(new ValidationConfiguration($groups = array('Default', 'Extra'))); $envelope = Envelope::wrap($message = new DummyMessage('Hey'))->with(new ValidationConfiguration($groups = array('Default', 'Extra')));
$validator = $this->createMock(ValidatorInterface::class); $validator = $this->createMock(ValidatorInterface::class);
$validator $validator
->expects($this->once()) ->expects($this->once())
@ -76,6 +76,7 @@ class ValidationMiddlewareTest extends TestCase
public function testValidationFailedException() public function testValidationFailedException()
{ {
$message = new DummyMessage('Hey'); $message = new DummyMessage('Hey');
$envelope = Envelope::wrap($message);
$violationList = $this->createMock(ConstraintViolationListInterface::class); $violationList = $this->createMock(ConstraintViolationListInterface::class);
$violationList $violationList
@ -96,6 +97,6 @@ class ValidationMiddlewareTest extends TestCase
->method('__invoke') ->method('__invoke')
; ;
(new ValidationMiddleware($validator))->handle($message, $next); (new ValidationMiddleware($validator))->handle($envelope, $next);
} }
} }