Skip to content

Commit

Permalink
PBC-1677: Adjust ValidationMiddlewarePlugin to only throw exceptions …
Browse files Browse the repository at this point in the history
…on received messages (#10217)

PBC-1677 Fixed MessageBroker ValidationMiddlewarePlugin to only throw exceptions on received messages
  • Loading branch information
danielsantos-spryker authored Jun 9, 2023
1 parent 9a64abc commit d444f24
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,23 @@

namespace Spryker\Zed\MessageBroker\Communication\Plugin\MessageBroker;

use Spryker\Shared\Log\LoggerTrait;
use Spryker\Zed\Kernel\Communication\AbstractPlugin;
use Spryker\Zed\MessageBrokerExtension\Dependency\Plugin\MessageValidatorPluginInterface;
use Spryker\Zed\MessageBrokerExtension\Dependency\Plugin\MiddlewarePluginInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
use Symfony\Component\Messenger\Middleware\StackInterface;
use Symfony\Component\Messenger\Stamp\ReceivedStamp;

/**
* @method \Spryker\Zed\MessageBroker\MessageBrokerConfig getConfig()
* @method \Spryker\Zed\MessageBroker\Business\MessageBrokerFacadeInterface getFacade()
*/
class ValidationMiddlewarePlugin extends AbstractPlugin implements MiddlewarePluginInterface
{
use LoggerTrait;

/**
* {@inheritDoc}
*
Expand All @@ -36,7 +41,13 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
/** @var \Spryker\Shared\Kernel\Transfer\TransferInterface $messageTransfer */
$messageTransfer = $envelope->getMessage();
if (!$this->getFacade()->canHandleMessage($messageTransfer)) {
throw new UnrecoverableMessageHandlingException();
if ($envelope->all(ReceivedStamp::class)) {
throw new UnrecoverableMessageHandlingException();
}

$this->getLogger()->error(sprintf('Message "%s" can not be handled. At least one of the "%s"s attached to the "%s" marked the message as invalid.', get_class($messageTransfer), MessageValidatorPluginInterface::class, static::class));

return $envelope;
}

return $stack->next()->handle($envelope, $stack);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

/**
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
*/

namespace SprykerTest\Zed\MessageBroker\Communication\Plugin\MessageBroker;

use Codeception\Test\Unit;
use SprykerTest\Zed\MessageBroker\MessageBrokerCommunicationTester;
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
use Symfony\Component\Messenger\Stamp\ReceivedStamp;

/**
* Auto-generated group annotations
*
* @group SprykerTest
* @group Zed
* @group MessageBroker
* @group Communication
* @group Plugin
* @group MessageBroker
* @group ValidationMiddlewarePluginTest
* Add your own group annotations below this line
*/
class ValidationMiddlewarePluginTest extends Unit
{
/**
* @var \SprykerTest\Zed\MessageBroker\MessageBrokerCommunicationTester
*/
protected MessageBrokerCommunicationTester $tester;

/**
* @return void
*/
public function testValidationMiddlewarePluginCantHandleReceivedMessageWillThrowException(): void
{
// Arrange
$envelope = $this->tester->haveEnvelopeWithReceivedStamp();

$validationMiddlewarePlugin = $this->tester->createValidationMiddlewarePluginThatCanNotHandleAMessage();

$stackMock = $this->tester->createStackMockWithNeverCalledNextMethod();

// Expectation
$this->expectException(UnrecoverableMessageHandlingException::class);

// Act
$validationMiddlewarePlugin->handle($envelope, $stackMock);
}

/**
* @return void
*/
public function testValidationMiddlewarePluginCantHandleSentMessageWillReturnUnhandledEnvelope(): void
{
// Arrange
$envelope = $this->tester->haveEnvelope();

$validationMiddlewarePlugin = $this->tester->createValidationMiddlewarePluginThatCanNotHandleAMessage();

$stackMock = $this->tester->createStackMockWithNeverCalledNextMethod();

// Act
$handledEnvelope = $validationMiddlewarePlugin->handle($envelope, $stackMock);

// Assert
$this->assertSame($envelope, $handledEnvelope);
$this->assertCount(0, $handledEnvelope->all());
}

/**
* @return void
*/
public function testValidationMiddlewarePluginCanHandleSentMessageWillReturnEnvelope(): void
{
// Arrange
$envelope = $this->tester->haveEnvelope();

$validationMiddlewarePlugin = $this->tester->createValidationMiddlewarePluginThatCanHandleAMessage();

$stackMock = $this->tester->createStackMockWithOnceCalledNextMethod($envelope);

// Act
$handledEnvelope = $validationMiddlewarePlugin->handle($envelope, $stackMock);

// Assert
$this->assertSame($envelope, $handledEnvelope);
$this->assertCount(0, $handledEnvelope->all());
}

/**
* @return void
*/
public function testValidationMiddlewarePluginCanHandleReceivedMessageWillReturnEnvelope(): void
{
// Arrange
$envelope = $this->tester->haveEnvelopeWithReceivedStamp();

$validationMiddlewarePlugin = $this->tester->createValidationMiddlewarePluginThatCanHandleAMessage(true);

$stackMock = $this->tester->createStackMockWithOnceCalledNextMethod($envelope);

// Act
$handledEnvelope = $validationMiddlewarePlugin->handle($envelope, $stackMock);

// Assert
$this->assertSame($envelope, $handledEnvelope);
$this->assertCount(1, $handledEnvelope->all(ReceivedStamp::class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Generated\Shared\DataBuilder\MessageAttributesBuilder;
use Generated\Shared\Transfer\MessageAttributesTransfer;
use Generated\Shared\Transfer\MessageBrokerWorkerConfigTransfer;
use Generated\Shared\Transfer\MessageTransfer;
use Spryker\Zed\MessageBroker\Business\MessageBrokerBusinessFactory;
use Spryker\Zed\MessageBroker\Business\MessageBrokerFacadeInterface;
use Spryker\Zed\MessageBroker\Business\Worker\Worker;
Expand All @@ -29,6 +30,7 @@
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\EventListener\StopWorkerOnTimeLimitListener;
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
use Symfony\Component\Messenger\Stamp\SentStamp;
use Symfony\Component\Messenger\Transport\InMemoryTransport;
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
Expand Down Expand Up @@ -461,4 +463,24 @@ protected function getFactory(): MessageBrokerBusinessFactory

return $messageBrokerFactory;
}

/**
* @return \Symfony\Component\Messenger\Envelope
*/
public function haveEnvelope(): Envelope
{
$messageTransfer = new MessageTransfer();

return new Envelope($messageTransfer);
}

/**
* @return \Symfony\Component\Messenger\Envelope
*/
public function haveEnvelopeWithReceivedStamp(): Envelope
{
$envelope = $this->haveEnvelope();

return $envelope->with(new ReceivedStamp('someTransport'));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@
namespace SprykerTest\Zed\MessageBroker;

use Codeception\Actor;
use Codeception\Stub;
use Codeception\Stub\Expected;
use PHPUnit\Framework\MockObject\MockObject;
use Spryker\Zed\MessageBroker\Business\MessageBrokerFacade;
use Spryker\Zed\MessageBroker\Communication\Plugin\Console\MessageBrokerDebugConsole;
use Spryker\Zed\MessageBroker\Communication\Plugin\Console\MessageBrokerWorkerConsole;
use Spryker\Zed\MessageBroker\Communication\Plugin\MessageBroker\ValidationMiddlewarePlugin;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Middleware\StackInterface;

/**
* Inherited Methods
Expand Down Expand Up @@ -58,4 +66,74 @@ public function getDebugConsoleCommandTester(): CommandTester

return $this->getConsoleTester($command);
}

/**
* @return \Spryker\Zed\MessageBroker\Communication\Plugin\MessageBroker\ValidationMiddlewarePlugin
*/
public function createValidationMiddlewarePluginThatCanHandleAMessage(): ValidationMiddlewarePlugin
{
$messageBrokerFacadeMock = Stub::make(MessageBrokerFacade::class, [
'canHandleMessage' => true,
]);

$validationMiddlewarePlugin = new ValidationMiddlewarePlugin();
$validationMiddlewarePlugin->setFacade($messageBrokerFacadeMock);

return $validationMiddlewarePlugin;
}

/**
* @return \Spryker\Zed\MessageBroker\Communication\Plugin\MessageBroker\ValidationMiddlewarePlugin
*/
public function createValidationMiddlewarePluginThatCanNotHandleAMessage(): ValidationMiddlewarePlugin
{
$messageBrokerFacadeMock = Stub::make(MessageBrokerFacade::class, [
'canHandleMessage' => false,
]);

$validationMiddlewarePlugin = new ValidationMiddlewarePlugin();
$validationMiddlewarePlugin->setFacade($messageBrokerFacadeMock);

return $validationMiddlewarePlugin;
}

/**
* @param \Symfony\Component\Messenger\Envelope $envelope
*
* @return \Symfony\Component\Messenger\Middleware\MiddlewareInterface|\PHPUnit\Framework\MockObject\MockObject
*/
public function createMiddlewareInterfaceMock(Envelope $envelope): MiddlewareInterface|MockObject
{
return Stub::makeEmpty(MiddlewareInterface::class, [
'handle' => $envelope,
]);
}

/**
* @param \Symfony\Component\Messenger\Envelope $envelope
*
* @return \Symfony\Component\Messenger\Middleware\StackInterface|\PHPUnit\Framework\MockObject\MockObject
*/
public function createStackMockWithOnceCalledNextMethod(Envelope $envelope): StackInterface|MockObject
{
$stackMock = Stub::makeEmpty(StackInterface::class);

$middlewareInterfaceMock = $this->createMiddlewareInterfaceMock($envelope);

$stackMock->expects(Expected::once()->getMatcher())->method('next')->willReturn($middlewareInterfaceMock);

return $stackMock;
}

/**
* @return \Symfony\Component\Messenger\Middleware\StackInterface|\PHPUnit\Framework\MockObject\MockObject
*/
public function createStackMockWithNeverCalledNextMethod(): StackInterface|MockObject
{
$stackMock = Stub::makeEmpty(StackInterface::class);

$stackMock->expects(Expected::never()->getMatcher())->method('next');

return $stackMock;
}
}
1 change: 1 addition & 0 deletions tests/SprykerTest/Zed/MessageBroker/codeception.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ suites:
- \SprykerTest\Zed\Application\Helper\ApplicationHelper
- \SprykerTest\Zed\EventDispatcher\Helper\EventDispatcherHelper
- \SprykerTest\Zed\Console\Helper\ConsoleHelper
- \SprykerTest\Shared\Store\Helper\StoreDependencyHelper

0 comments on commit d444f24

Please sign in to comment.