Skip to content
This repository has been archived by the owner on Jul 28, 2022. It is now read-only.

Commit

Permalink
Merge 4c7d1c5 into 5db745c
Browse files Browse the repository at this point in the history
  • Loading branch information
llupa committed Jan 16, 2020
2 parents 5db745c + 4c7d1c5 commit fe16a8f
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 3 deletions.
5 changes: 4 additions & 1 deletion docs/reference/advanced_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ Full configuration options:
vhost: guest
console_url: 'http://localhost:55672/api'
factory_class: \Enqueue\AmqpLib\AmqpConnectionFactory
# Use this option to specify the delay strategy
# If you want to completely ignore this you can set it to null
delay_strategy_class: null
consumers:
# If set to true, SwiftMailerConsumer and LoggerConsumer will be registered as services
Expand Down Expand Up @@ -141,4 +145,3 @@ run `composer require enqueue/amqp-ext:^0.8` and change `factory_class` option i
.. _`enqueue/amqp-lib`: https://github.com/php-enqueue/enqueue-dev/blob/master/docs/transport/amqp_lib.md
.. _`enqueue/amqp-ext`: https://github.com/php-enqueue/enqueue-dev/blob/master/docs/transport/amqp_ext.md
.. _`enqueue/amqp-bunny`: https://github.com/php-enqueue/enqueue-dev/blob/master/docs/transport/amqp_bunny.md

19 changes: 17 additions & 2 deletions src/Backend/AMQPBackendDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

namespace Sonata\NotificationBundle\Backend;

use Enqueue\AmqpTools\DelayStrategy;
use Enqueue\AmqpTools\DelayStrategyAware;
use Enqueue\AmqpTools\RabbitMqDlxDelayStrategy;
use Guzzle\Http\Client as GuzzleClient;
use Interop\Amqp\AmqpConnectionFactory;
use Interop\Amqp\AmqpContext;
Expand Down Expand Up @@ -130,7 +130,22 @@ final public function getContext()
]);

if ($factory instanceof DelayStrategyAware) {
$factory->setDelayStrategy(new RabbitMqDlxDelayStrategy());
$delayStrategy = $this->settings['delay_strategy_class'];
if (
!empty($delayStrategy) &&
(
!class_exists($delayStrategy) ||
!(new \ReflectionClass($delayStrategy))->implementsInterface(DelayStrategy::class)
)
) {
throw new \LogicException(sprintf(
'The delay_strategy_class option "%s" has to be valid class that implements "%s" or null to ignore',
$delayStrategy,
DelayStrategy::class
));
}

$factory->setDelayStrategy(new $delayStrategy());
}

$this->context = $factory->createContext();
Expand Down
5 changes: 5 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public function getConfigTreeBuilder()
->defaultValue(AmqpConnectionFactory::class)
->info('This option defines an AMQP connection factory to be used to establish a connection with RabbitMQ.')
->end()
->scalarNode('delay_strategy_class')
->isRequired()
->defaultNull()
->info('This option defines the delay strategy to use in case an AMQP connection factory is of DelayStrategyAware type. Defaults to null if should be ignored.')
->end()
->end()
->end()
->end()
Expand Down
72 changes: 72 additions & 0 deletions tests/Backend/AMQPBackendDispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
use Sonata\NotificationBundle\Backend\AMQPBackend;
use Sonata\NotificationBundle\Backend\AMQPBackendDispatcher;
use Sonata\NotificationBundle\Exception\BackendNotFoundException;
use Sonata\NotificationBundle\Tests\Mock\AmqpConnectionFactoryDelayStrategyAwareStub;
use Sonata\NotificationBundle\Tests\Mock\AmqpConnectionFactoryStub;
use Sonata\NotificationBundle\Tests\Mock\AnyDelayStrategyStub;

class AMQPBackendDispatcherTest extends TestCase
{
Expand Down Expand Up @@ -60,6 +62,48 @@ public function testThrowIfFactoryClassIsNotInstanceOfAmqpConnectionFactoryInter
$dispatcher->getContext();
}

public function testThrowIfDelayStrategyClassIsSetButNotRealClass()
{
$dispatcher = new AMQPBackendDispatcher(
[
'host' => 'theHost',
'port' => 'thePort',
'user' => 'theUser',
'pass' => 'thePass',
'vhost' => 'theVhost',
'factory_class' => AmqpConnectionFactoryDelayStrategyAwareStub::class,
'delay_strategy_class' => 'anInvalidClass',
],
[], 'default',
[]
);

$this->expectException(\LogicException::class);
$this->expectExceptionMessage('The delay_strategy_class option "anInvalidClass" has to be valid class that implements "Enqueue\AmqpTools\DelayStrategy"');
$dispatcher->getContext();
}

public function testThrowIfDelayStrategyClassIsSetButNotInstanceOfDelayStrategyInterface()
{
$dispatcher = new AMQPBackendDispatcher(
[
'host' => 'theHost',
'port' => 'thePort',
'user' => 'theUser',
'pass' => 'thePass',
'vhost' => 'theVhost',
'factory_class' => AmqpConnectionFactoryDelayStrategyAwareStub::class,
'delay_strategy_class' => \stdClass::class,
],
[], 'default',
[]
);

$this->expectException(\LogicException::class);
$this->expectExceptionMessage('The delay_strategy_class option "stdClass" has to be valid class that implements "Enqueue\AmqpTools\DelayStrategy"');
$dispatcher->getContext();
}

public function testShouldPassExpectedOptionsToAmqpConnectionFactoryConstructor()
{
$dispatcher = new AMQPBackendDispatcher(
Expand All @@ -70,6 +114,7 @@ public function testShouldPassExpectedOptionsToAmqpConnectionFactoryConstructor(
'pass' => 'thePass',
'vhost' => 'theVhost',
'factory_class' => AmqpConnectionFactoryStub::class,
'delay_strategy_class' => null,
],
[],
'default',
Expand All @@ -87,6 +132,32 @@ public function testShouldPassExpectedOptionsToAmqpConnectionFactoryConstructor(
], AmqpConnectionFactoryStub::$config);
}

public function testShouldSetExpectedDelayStrategyToAmqpConnectionFactoryOfInstanceDelayStrategyAware()
{
$expectedContext = $this->createMock(AmqpContext::class);

$dispatcher = new AMQPBackendDispatcher(
[
'host' => 'aHost',
'port' => 'aPort',
'user' => 'aUser',
'pass' => 'aPass',
'vhost' => 'aVhost',
'factory_class' => AmqpConnectionFactoryDelayStrategyAwareStub::class,
'delay_strategy_class' => AnyDelayStrategyStub::class,
],
[],
'default',
[]
);

AmqpConnectionFactoryDelayStrategyAwareStub::$context = $expectedContext;

$actualContext = $dispatcher->getContext();

$this->assertSame($expectedContext, $actualContext);
}

public function testShouldReturnExpectedAmqpContext()
{
$expectedContext = $this->createMock(AmqpContext::class);
Expand All @@ -99,6 +170,7 @@ public function testShouldReturnExpectedAmqpContext()
'pass' => 'aPass',
'vhost' => 'aVhost',
'factory_class' => AmqpConnectionFactoryStub::class,
'delay_strategy_class' => null,
],
[],
'default',
Expand Down
40 changes: 40 additions & 0 deletions tests/Mock/AmqpConnectionFactoryDelayStrategyAwareStub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\NotificationBundle\Tests\Mock;

use Enqueue\AmqpTools\DelayStrategyAware;
use Enqueue\AmqpTools\DelayStrategyAwareTrait;
use Interop\Amqp\AmqpConnectionFactory;
use Interop\Queue\PsrContext;

class AmqpConnectionFactoryDelayStrategyAwareStub implements AmqpConnectionFactory, DelayStrategyAware
{
use DelayStrategyAwareTrait;

public static $config;
public static $context;

public function __construct($config)
{
static::$config = $config;
}

/**
* @return PsrContext
*/
public function createContext()
{
return static::$context;
}
}
29 changes: 29 additions & 0 deletions tests/Mock/AnyDelayStrategyStub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\NotificationBundle\Tests\Mock;

use Enqueue\AmqpTools\DelayStrategy;
use Interop\Amqp\AmqpContext;
use Interop\Amqp\AmqpDestination;
use Interop\Amqp\AmqpMessage;

class AnyDelayStrategyStub implements DelayStrategy
{
/**
* {@inheritdoc}
*/
public function delayMessage(AmqpContext $context, AmqpDestination $dest, AmqpMessage $message, $delayMsec)
{
}
}

0 comments on commit fe16a8f

Please sign in to comment.