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

Commit

Permalink
Merge 3.x into master
Browse files Browse the repository at this point in the history
  • Loading branch information
SonataCI committed Dec 23, 2016
2 parents 765fa78 + 96eafb2 commit a0b95aa
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 62 deletions.
25 changes: 18 additions & 7 deletions Backend/AMQPBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,34 @@ class AMQPBackend implements BackendInterface
*/
protected $deadLetterRoutingKey;

/**
* @var null|int
*/
protected $ttl;

/**
* @var AMQPBackendDispatcher
*/
protected $dispatcher = null;

/**
* @param string $exchange
* @param string $queue
* @param string $recover
* @param string $key
* @param string $deadLetterExchange
* @param string $deadLetterRoutingKey
* @param string $exchange
* @param string $queue
* @param string $recover
* @param string $key
* @param string $deadLetterExchange
* @param string $deadLetterRoutingKey
* @param null|int $ttl
*/
public function __construct($exchange, $queue, $recover, $key, $deadLetterExchange = null, $deadLetterRoutingKey = null)
public function __construct($exchange, $queue, $recover, $key, $deadLetterExchange = null, $deadLetterRoutingKey = null, $ttl = null)
{
$this->exchange = $exchange;
$this->queue = $queue;
$this->recover = $recover;
$this->key = $key;
$this->deadLetterExchange = $deadLetterExchange;
$this->deadLetterRoutingKey = $deadLetterRoutingKey;
$this->ttl = $ttl;

if (!class_exists('PhpAmqpLib\Message\AMQPMessage')) {
throw new \RuntimeException('Please install php-amqplib/php-amqplib dependency');
Expand Down Expand Up @@ -107,6 +114,10 @@ public function initialize()
}
}

if ($this->ttl !== null) {
$args['x-message-ttl'] = array('I', $this->ttl);
}

/*
* name: $queue
* passive: false
Expand Down
36 changes: 31 additions & 5 deletions Controller/Api/MessageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Sonata\NotificationBundle\Controller\Api;

use FOS\RestBundle\Context\Context;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\Annotations\Route;
use FOS\RestBundle\Controller\Annotations\View;
Expand Down Expand Up @@ -64,7 +65,6 @@ public function __construct(MessageManagerInterface $messageManager, FormFactory
*
* @QueryParam(name="page", requirements="\d+", default="1", description="Page for message list pagination")
* @QueryParam(name="count", requirements="\d+", default="10", description="Number of messages by page")
* @QueryParam(name="orderBy", array=true, requirements="ASC|DESC", nullable=true, strict=true, description="Order by array (key is field, value is direction)")
* @QueryParam(name="type", nullable=true, description="Message type filter")
* @QueryParam(name="state", requirements="\d+", strict=true, nullable=true, description="Message status filter")
*
Expand All @@ -76,6 +76,20 @@ public function __construct(MessageManagerInterface $messageManager, FormFactory
*/
public function getMessagesAction(ParamFetcherInterface $paramFetcher)
{
$orderByQueryParam = new QueryParam();
$orderByQueryParam->name = 'orderBy';
$orderByQueryParam->requirements = 'ASC|DESC';
$orderByQueryParam->nullable = true;
$orderByQueryParam->strict = true;
$orderByQueryParam->description = 'Query groups order by clause (key is field, value is direction)';
if (property_exists($orderByQueryParam, 'map')) {
$orderByQueryParam->map = true;
} else {
$orderByQueryParam->array = true;
}

$paramFetcher->addParam($orderByQueryParam);

$supportedCriteria = array(
'state' => '',
'type' => '',
Expand Down Expand Up @@ -135,10 +149,22 @@ public function postMessageAction(Request $request)
$this->messageManager->save($message);

$view = FOSRestView::create($message);
$serializationContext = SerializationContext::create();
$serializationContext->setGroups(array('sonata_api_read'));
$serializationContext->enableMaxDepthChecks();
$view->setSerializationContext($serializationContext);

if (class_exists('FOS\RestBundle\Context\Context')) {
$serializationContext = new Context();
if (method_exists($serializationContext, 'enableMaxDepth')) {
$serializationContext->enableMaxDepth();
} else {
$serializationContext->setMaxDepth(10);
}
$serializationContext->setGroups(array('sonata_api_read'));
$view->setContext($serializationContext);
} else {
$serializationContext = SerializationContext::create();
$serializationContext->enableMaxDepthChecks();
$serializationContext->setGroups(array('sonata_api_read'));
$view->setSerializationContext($serializationContext);
}

return $view;
}
Expand Down
15 changes: 13 additions & 2 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,19 @@ protected function getQueueNode()
If is set, failed messages will be rejected and sent to this exchange
EOF;

$deadLetterRoutingKey = <<<'EOF'
$deadLetterRoutingKeyInfo = <<<'EOF'
Only used by RabbitMQ
If set, failed messages will be routed to the queue using this key by dead-letter-exchange,
otherwise it will be requeued to the original queue if `dead-letter-exchange` is set.
If set, the queue must be configured with this key as `routing_key`.
EOF;

$ttlInfo = <<<'EOF'
Only used by RabbitMQ
Defines the per-queue message time-to-live (milliseconds)
EOF;

$typesInfo = <<<'EOF'
Expand Down Expand Up @@ -260,7 +266,12 @@ protected function getQueueNode()
->defaultValue(null)
->end()
->scalarNode('dead_letter_routing_key')
->info($deadLetterRoutingKey)
->info($deadLetterRoutingKeyInfo)
->defaultValue(null)
->end()
->integerNode('ttl')
->info($ttlInfo)
->min(0)
->defaultValue(null)
->end()

Expand Down
8 changes: 6 additions & 2 deletions DependencyInjection/SonataNotificationExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ protected function configureRabbitmq(ContainerBuilder $container, array $config)
'recover' => false,
'dead_letter_exchange' => null,
'dead_letter_routing_key' => null,
'ttl' => null,
));
}

Expand Down Expand Up @@ -375,7 +376,8 @@ protected function configureRabbitmq(ContainerBuilder $container, array $config)
$queue['recover'],
$queue['routing_key'],
$queue['dead_letter_exchange'],
$queue['dead_letter_routing_key']
$queue['dead_letter_routing_key'],
$queue['ttl']
);

$amqBackends[$pos] = array(
Expand Down Expand Up @@ -412,10 +414,11 @@ protected function configureRabbitmq(ContainerBuilder $container, array $config)
* @param string $key
* @param string $deadLetterExchange
* @param string $deadLetterRoutingKey
* @param int|null $ttl
*
* @return string
*/
protected function createAMQPBackend(ContainerBuilder $container, $exchange, $name, $recover, $key = '', $deadLetterExchange = null, $deadLetterRoutingKey = null)
protected function createAMQPBackend(ContainerBuilder $container, $exchange, $name, $recover, $key = '', $deadLetterExchange = null, $deadLetterRoutingKey = null, $ttl = null)
{
$id = 'sonata.notification.backend.rabbitmq.'.$this->amqpCounter++;

Expand All @@ -428,6 +431,7 @@ protected function createAMQPBackend(ContainerBuilder $container, $exchange, $na
$key,
$deadLetterExchange,
$deadLetterRoutingKey,
$ttl,
)
);
$definition->setPublic(false);
Expand Down
141 changes: 97 additions & 44 deletions Tests/Backend/AMQPBackendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class AMQPBackendTest extends \PHPUnit_Framework_TestCase
const KEY = 'message.type.foo';
const DEAD_LETTER_EXCHANGE = 'dlx';
const DEAD_LETTER_ROUTING_KEY = 'message.type.dl';
const TTL = 60000;

protected function setUp()
{
Expand All @@ -32,27 +33,30 @@ public function testInitializeWithNoDeadLetterExchangeAndNoDeadLetterRoutingKey(

$channelMock->expects($this->once())
->method('exchange_declare')
->with($this->equalTo(self::EXCHANGE),
$this->equalTo('direct'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean')
->with(
$this->equalTo(self::EXCHANGE),
$this->equalTo('direct'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean')
);
$channelMock->expects($this->once())
->method('queue_declare')
->with($this->equalTo(self::QUEUE),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->equalTo(array())
->with(
$this->equalTo(self::QUEUE),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->equalTo(array())
);
$channelMock->expects($this->once())
->method('queue_bind')
->with($this->equalTo(self::QUEUE),
$this->equalTo(self::EXCHANGE),
$this->equalTo(self::KEY)
->with(
$this->equalTo(self::QUEUE),
$this->equalTo(self::EXCHANGE),
$this->equalTo(self::KEY)
);

$backend->initialize();
Expand Down Expand Up @@ -82,15 +86,16 @@ public function testInitializeWithDeadLetterExchangeAndNoDeadLetterRoutingKey()
);
$channelMock->expects($this->once())
->method('queue_declare')
->with($this->equalTo(self::QUEUE),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->equalTo(array(
'x-dead-letter-exchange' => array('S', self::DEAD_LETTER_EXCHANGE),
))
->with(
$this->equalTo(self::QUEUE),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->equalTo(array(
'x-dead-letter-exchange' => array('S', self::DEAD_LETTER_EXCHANGE),
))
);
$channelMock->expects($this->exactly(2))
->method('queue_bind')
Expand All @@ -116,39 +121,87 @@ public function testInitializeWithDeadLetterExchangeAndDeadLetterRoutingKey()

$channelMock->expects($this->once())
->method('exchange_declare')
->with($this->equalTo(self::EXCHANGE),
$this->equalTo('direct'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean')
->with(
$this->equalTo(self::EXCHANGE),
$this->equalTo('direct'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean')
);
$channelMock->expects($this->once())
->method('queue_declare')
->with($this->equalTo(self::QUEUE),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->equalTo(array(
'x-dead-letter-exchange' => array('S', self::DEAD_LETTER_EXCHANGE),
'x-dead-letter-routing-key' => array('S', self::DEAD_LETTER_ROUTING_KEY),
))
->with(
$this->equalTo(self::QUEUE),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->equalTo(array(
'x-dead-letter-exchange' => array('S', self::DEAD_LETTER_EXCHANGE),
'x-dead-letter-routing-key' => array('S', self::DEAD_LETTER_ROUTING_KEY),
))
);
$channelMock->expects($this->once())
->method('queue_bind')
->with($this->equalTo(self::QUEUE),
$this->equalTo(self::EXCHANGE),
$this->equalTo(self::KEY)
->with(
$this->equalTo(self::QUEUE),
$this->equalTo(self::EXCHANGE),
$this->equalTo(self::KEY)
);

$backend->initialize();
}

public function testInitializeWithTTL()
{
list($backend, $channelMock) = $this->getBackendAndChannelMock(false, null, null, self::TTL);

$channelMock->expects($this->once())
->method('exchange_declare')
->with(
$this->equalTo(self::EXCHANGE),
$this->equalTo('direct'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean')
);
$channelMock->expects($this->once())
->method('queue_declare')
->with(
$this->equalTo(self::QUEUE),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->isType('boolean'),
$this->equalTo(array(
'x-message-ttl' => array('I', self::TTL),
))
);
$channelMock->expects($this->once())
->method('queue_bind')
->with(
$this->equalTo(self::QUEUE),
$this->equalTo(self::EXCHANGE),
$this->equalTo(self::KEY)
);

$backend->initialize();
}

protected function getBackendAndChannelMock($recover = false, $deadLetterExchange = null, $deadLetterRoutingKey = null)
protected function getBackendAndChannelMock($recover = false, $deadLetterExchange = null, $deadLetterRoutingKey = null, $ttl = null)
{
$mock = $this->getMockBuilder('\Sonata\NotificationBundle\Backend\AMQPBackend')
->setConstructorArgs(array(self::EXCHANGE, self::QUEUE, $recover, self::KEY, $deadLetterExchange, $deadLetterRoutingKey))
->setConstructorArgs(array(
self::EXCHANGE,
self::QUEUE,
$recover,
self::KEY,
$deadLetterExchange,
$deadLetterRoutingKey,
$ttl,
))
->setMethods(array('getIterator'))
->getMock();

Expand Down
4 changes: 3 additions & 1 deletion Tests/Controller/Api/MessageControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ public function testGetMessagesAction()
$messageManager = $this->getMock('Sonata\NotificationBundle\Model\MessageManagerInterface');
$messageManager->expects($this->once())->method('getPager')->will($this->returnValue(array()));

$paramFetcher = $this->getMock('FOS\RestBundle\Request\ParamFetcherInterface');
$paramFetcher = $this->getMockBuilder('FOS\RestBundle\Request\ParamFetcher')
->disableOriginalConstructor()
->getMock();
$paramFetcher->expects($this->exactly(3))->method('get');
$paramFetcher->expects($this->once())->method('all')->will($this->returnValue(array()));

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"liip/monitor-bundle": "^2.0",
"symfony/phpunit-bridge": "^2.7 || ^3.0",
"swiftmailer/swiftmailer": "^4.3 || ^5.0",
"friendsofsymfony/rest-bundle": "^1.1",
"friendsofsymfony/rest-bundle": "^1.5 || ^2.1",
"jms/serializer-bundle": "^0.13 || ^1.0",
"nelmio/api-doc-bundle": "^2.4",
"sllh/php-cs-fixer-styleci-bridge": "^2.0"
Expand Down

0 comments on commit a0b95aa

Please sign in to comment.