From 78f949e289cbb67d35d70cf78447eba338091f47 Mon Sep 17 00:00:00 2001 From: Christophe Deliens Date: Mon, 11 Sep 2017 16:17:18 +0200 Subject: [PATCH 0001/1581] fixed NS was causing "PHP Fatal error: Cannot use Interop\Amqp\AmqpConsumer as AmqpConsumer because the name is already in use in enqueue/amqp-ext/Flags.php on line 5" --- pkg/amqp-ext/Flags.php | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/pkg/amqp-ext/Flags.php b/pkg/amqp-ext/Flags.php index e433250da..778d83810 100644 --- a/pkg/amqp-ext/Flags.php +++ b/pkg/amqp-ext/Flags.php @@ -2,11 +2,11 @@ namespace Enqueue\AmqpExt; -use Interop\Amqp\AmqpConsumer; -use Interop\Amqp\AmqpDestination; -use Interop\Amqp\AmqpMessage; -use Interop\Amqp\AmqpQueue; -use Interop\Amqp\AmqpTopic; +use Interop\Amqp\AmqpConsumer as InteropAmqpConsumer; +use Interop\Amqp\AmqpDestination as InteropAmqpDestination; +use Interop\Amqp\AmqpMessage as InteropAmqpMessage; +use Interop\Amqp\AmqpQueue as InteropAmqpQueue; +use Interop\Amqp\AmqpTopic as InteropAmqpTopic; class Flags { @@ -19,11 +19,11 @@ public static function convertMessageFlags($interop) { $flags = AMQP_NOPARAM; - if ($interop & AmqpMessage::FLAG_MANDATORY) { + if ($interop & InteropAmqpMessage::FLAG_MANDATORY) { $flags |= AMQP_MANDATORY; } - if ($interop & AmqpMessage::FLAG_IMMEDIATE) { + if ($interop & InteropAmqpMessage::FLAG_IMMEDIATE) { $flags |= AMQP_IMMEDIATE; } @@ -41,7 +41,7 @@ public static function convertTopicFlags($interop) $flags |= static::convertDestinationFlags($interop); - if ($interop & AmqpTopic::FLAG_INTERNAL) { + if ($interop & InteropAmqpTopic::FLAG_INTERNAL) { $flags |= AMQP_INTERNAL; } @@ -59,7 +59,7 @@ public static function convertQueueFlags($interop) $flags |= static::convertDestinationFlags($interop); - if ($interop & AmqpQueue::FLAG_EXCLUSIVE) { + if ($interop & InteropAmqpQueue::FLAG_EXCLUSIVE) { $flags |= AMQP_EXCLUSIVE; } @@ -75,19 +75,19 @@ public static function convertDestinationFlags($interop) { $flags = AMQP_NOPARAM; - if ($interop & AmqpDestination::FLAG_PASSIVE) { + if ($interop & InteropAmqpDestination::FLAG_PASSIVE) { $flags |= AMQP_PASSIVE; } - if ($interop & AmqpDestination::FLAG_DURABLE) { + if ($interop & InteropAmqpDestination::FLAG_DURABLE) { $flags |= AMQP_DURABLE; } - if ($interop & AmqpDestination::FLAG_AUTODELETE) { + if ($interop & InteropAmqpDestination::FLAG_AUTODELETE) { $flags |= AMQP_AUTODELETE; } - if ($interop & AmqpDestination::FLAG_NOWAIT) { + if ($interop & InteropAmqpDestination::FLAG_NOWAIT) { $flags |= AMQP_NOWAIT; } @@ -103,19 +103,19 @@ public static function convertConsumerFlags($interop) { $flags = AMQP_NOPARAM; - if ($interop & AmqpConsumer::FLAG_NOLOCAL) { + if ($interop & InteropAmqpConsumer::FLAG_NOLOCAL) { $flags |= AMQP_NOLOCAL; } - if ($interop & AmqpConsumer::FLAG_NOACK) { + if ($interop & InteropAmqpConsumer::FLAG_NOACK) { $flags |= AMQP_AUTOACK; } - if ($interop & AmqpConsumer::FLAG_EXCLUSIVE) { + if ($interop & InteropAmqpConsumer::FLAG_EXCLUSIVE) { $flags |= AMQP_EXCLUSIVE; } - if ($interop & AmqpConsumer::FLAG_NOWAIT) { + if ($interop & InteropAmqpConsumer::FLAG_NOWAIT) { $flags |= AMQP_NOWAIT; } From aeff8ddd7dee1838f655deac5c60788a3f2d1d3c Mon Sep 17 00:00:00 2001 From: Vladimir Tsykun Date: Tue, 12 Sep 2017 01:04:33 +0300 Subject: [PATCH 0002/1581] Fixed losing message priority for dbal driver --- pkg/dbal/Client/DbalDriver.php | 30 ++++++++++++++++++++++++++++- pkg/dbal/DbalConsumer.php | 2 +- pkg/dbal/Tests/DbalConsumerTest.php | 21 +++++++++++++++++--- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/pkg/dbal/Client/DbalDriver.php b/pkg/dbal/Client/DbalDriver.php index 86bc0e176..1cb93e171 100644 --- a/pkg/dbal/Client/DbalDriver.php +++ b/pkg/dbal/Client/DbalDriver.php @@ -30,6 +30,17 @@ class DbalDriver implements DriverInterface */ private $queueMetaRegistry; + /** + * @var array + */ + private static $priorityMap = [ + MessagePriority::VERY_LOW => 0, + MessagePriority::LOW => 1, + MessagePriority::NORMAL => 2, + MessagePriority::HIGH => 3, + MessagePriority::VERY_HIGH => 4, + ]; + /** * @param DbalContext $context * @param Config $config @@ -63,6 +74,9 @@ public function createTransportMessage(Message $message) $transportMessage->setDelay($message->getDelay()); $transportMessage->setReplyTo($message->getReplyTo()); $transportMessage->setCorrelationId($message->getCorrelationId()); + if (array_key_exists($message->getPriority(), self::$priorityMap)) { + $transportMessage->setPriority(self::$priorityMap[$message->getPriority()]); + } return $transportMessage; } @@ -83,11 +97,17 @@ public function createClientMessage(PsrMessage $message) $clientMessage->setContentType($message->getHeader('content_type')); $clientMessage->setMessageId($message->getMessageId()); $clientMessage->setTimestamp($message->getTimestamp()); - $clientMessage->setPriority(MessagePriority::NORMAL); $clientMessage->setDelay($message->getDelay()); $clientMessage->setReplyTo($message->getReplyTo()); $clientMessage->setCorrelationId($message->getCorrelationId()); + $priorityMap = array_flip(self::$priorityMap); + $priority = array_key_exists($message->getPriority(), $priorityMap) ? + $priorityMap[$message->getPriority()] : + MessagePriority::NORMAL; + $clientMessage->setPriority($priority); + + return $clientMessage; } @@ -156,4 +176,12 @@ public function getConfig() { return $this->config; } + + /** + * @return array + */ + public static function getPriorityMap() + { + return self::$priorityMap; + } } diff --git a/pkg/dbal/DbalConsumer.php b/pkg/dbal/DbalConsumer.php index 5546d9100..6368e24a2 100644 --- a/pkg/dbal/DbalConsumer.php +++ b/pkg/dbal/DbalConsumer.php @@ -176,7 +176,7 @@ protected function receiveMessage() ->where('queue = :queue') ->andWhere('(delayed_until IS NULL OR delayed_until <= :delayedUntil)') ->orderBy('priority', 'desc') - ->orderBy('id', 'asc') + ->addOrderBy('id', 'asc') ->setMaxResults(1) ; diff --git a/pkg/dbal/Tests/DbalConsumerTest.php b/pkg/dbal/Tests/DbalConsumerTest.php index 3e7695315..6fcf7fa9e 100644 --- a/pkg/dbal/Tests/DbalConsumerTest.php +++ b/pkg/dbal/Tests/DbalConsumerTest.php @@ -172,10 +172,15 @@ public function testShouldReceiveMessage() ->will($this->returnSelf()) ; $queryBuilder - ->expects($this->exactly(2)) + ->expects($this->exactly(1)) ->method('orderBy') ->will($this->returnSelf()) ; + $queryBuilder + ->expects($this->exactly(1)) + ->method('addOrderBy') + ->will($this->returnSelf()) + ; $platform = $this->createPlatformMock(); @@ -264,10 +269,15 @@ public function testShouldReturnNullIfThereIsNoNewMessage() ->will($this->returnSelf()) ; $queryBuilder - ->expects($this->exactly(2)) + ->expects($this->exactly(1)) ->method('orderBy') ->will($this->returnSelf()) ; + $queryBuilder + ->expects($this->exactly(1)) + ->method('addOrderBy') + ->will($this->returnSelf()) + ; $platform = $this->createPlatformMock(); @@ -352,10 +362,15 @@ public function testShouldThrowIfMessageWasNotRemoved() ->will($this->returnSelf()) ; $queryBuilder - ->expects($this->exactly(2)) + ->expects($this->exactly(1)) ->method('orderBy') ->will($this->returnSelf()) ; + $queryBuilder + ->expects($this->exactly(1)) + ->method('addOrderBy') + ->will($this->returnSelf()) + ; $platform = $this->createPlatformMock(); From 8b83c3a75b98b1828295f437e7603f3c1ba167d2 Mon Sep 17 00:00:00 2001 From: Vladimir Tsykun Date: Tue, 12 Sep 2017 01:33:54 +0300 Subject: [PATCH 0003/1581] Fixed tests --- pkg/dbal/Tests/Client/DbalDriverTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/dbal/Tests/Client/DbalDriverTest.php b/pkg/dbal/Tests/Client/DbalDriverTest.php index 4eb95ffb9..232e3ceaf 100644 --- a/pkg/dbal/Tests/Client/DbalDriverTest.php +++ b/pkg/dbal/Tests/Client/DbalDriverTest.php @@ -92,6 +92,7 @@ public function testShouldConvertTransportMessageToClientMessage() $transportMessage->setHeader('content_type', 'ContentType'); $transportMessage->setMessageId('MessageId'); $transportMessage->setTimestamp(1000); + $transportMessage->setPriority(2); $transportMessage->setDelay(12345); $driver = new DbalDriver( From 02b254f6cb8bab27f3dea453f05283c765b3aed5 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Tue, 12 Sep 2017 17:05:38 +0300 Subject: [PATCH 0004/1581] Release 0.7.12 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d44bdab9..6f5fdae11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## [0.7.12](https://github.com/php-enqueue/enqueue-dev/tree/0.7.12) (2017-09-12) +[Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.11...0.7.12) + +- fixed NS [\#194](https://github.com/php-enqueue/enqueue-dev/pull/194) ([chdeliens](https://github.com/chdeliens)) + ## [0.7.11](https://github.com/php-enqueue/enqueue-dev/tree/0.7.11) (2017-09-11) [Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.10...0.7.11) From f3086c7fc6a8d16bd656134eca1427e64f8b9e5b Mon Sep 17 00:00:00 2001 From: Vladimir Tsykun Date: Tue, 12 Sep 2017 22:03:03 +0300 Subject: [PATCH 0005/1581] Fix pull request remarks --- pkg/dbal/Client/DbalDriver.php | 1 - .../Tests/DbalSendPriorityMessagesTest.php | 90 +++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 pkg/dbal/Tests/DbalSendPriorityMessagesTest.php diff --git a/pkg/dbal/Client/DbalDriver.php b/pkg/dbal/Client/DbalDriver.php index 1cb93e171..8196a9b84 100644 --- a/pkg/dbal/Client/DbalDriver.php +++ b/pkg/dbal/Client/DbalDriver.php @@ -107,7 +107,6 @@ public function createClientMessage(PsrMessage $message) MessagePriority::NORMAL; $clientMessage->setPriority($priority); - return $clientMessage; } diff --git a/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php b/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php new file mode 100644 index 000000000..c9d475516 --- /dev/null +++ b/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php @@ -0,0 +1,90 @@ +createContext(); + $queue = $this->createQueue($context, 'default'); + $consumer = $context->createConsumer($queue); + + // guard + $this->assertNull($consumer->receiveNoWait()); + + $messagePriorities = [1, 0, 3]; + $producer = $context->createProducer(); + foreach ($messagePriorities as $priority) { + $producer->send($queue, $this->createMessage($context, $priority)); + } + + sort($messagePriorities); + foreach (array_reverse($messagePriorities) as $priority) { + $message = $consumer->receive(8000); // 8 sec + + $this->assertInstanceOf(PsrMessage::class, $message); + $consumer->acknowledge($message); + $this->assertSame('priority'.$priority, $message->getBody()); + } + } + + /** + * @return PsrContext + */ + protected function createContext() + { + $factory = new DbalConnectionFactory( + [ + 'lazy' => true, + 'connection' => [ + 'dbname' => getenv('SYMFONY__DB__NAME'), + 'user' => getenv('SYMFONY__DB__USER'), + 'password' => getenv('SYMFONY__DB__PASSWORD'), + 'host' => getenv('SYMFONY__DB__HOST'), + 'port' => getenv('SYMFONY__DB__PORT'), + 'driver' => getenv('SYMFONY__DB__DRIVER'), + ] + ] + ); + + return $factory->createContext(); + } + + /** + * {@inheritdoc} + * + * @param DbalContext $context + */ + protected function createQueue(PsrContext $context, $queueName) + { + $queue = $context->createQueue($queueName); + $context->createDataBaseTable(); + + return $queue; + } + + /** + * @param PsrContext $context + * @param int $priority + * @return DbalMessage + */ + protected function createMessage(PsrContext $context, $priority) + { + /** @var DbalMessage $message */ + $message = $context->createMessage('priority'.$priority); + $message->setPriority($priority); + + return $message; + } +} From 3ad37410c09f167e3766c033e9424b23603340a3 Mon Sep 17 00:00:00 2001 From: Vladimir Tsykun Date: Tue, 12 Sep 2017 22:09:16 +0300 Subject: [PATCH 0006/1581] Cs fixes --- pkg/dbal/Tests/DbalSendPriorityMessagesTest.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php b/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php index c9d475516..e470565d8 100644 --- a/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php +++ b/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php @@ -44,7 +44,7 @@ public function test() */ protected function createContext() { - $factory = new DbalConnectionFactory( + $factory = new DbalConnectionFactory( [ 'lazy' => true, 'connection' => [ @@ -54,7 +54,7 @@ protected function createContext() 'host' => getenv('SYMFONY__DB__HOST'), 'port' => getenv('SYMFONY__DB__PORT'), 'driver' => getenv('SYMFONY__DB__DRIVER'), - ] + ], ] ); @@ -76,7 +76,8 @@ protected function createQueue(PsrContext $context, $queueName) /** * @param PsrContext $context - * @param int $priority + * @param int $priority + * * @return DbalMessage */ protected function createMessage(PsrContext $context, $priority) From 3f95717a8e8396e255942299ea3c266731e1e090 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Wed, 13 Sep 2017 09:14:37 +0300 Subject: [PATCH 0007/1581] [bundle] add tests for the case where topic subscriber does not def processor name --- .../Compiler/BuildClientRoutingPassTest.php | 25 +++++++++++++++++++ .../BuildProcessorRegistryPassTest.php | 23 +++++++++++++++++ .../WithoutProcessorNameTopicSubscriber.php | 18 +++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/Mock/WithoutProcessorNameTopicSubscriber.php diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/BuildClientRoutingPassTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/BuildClientRoutingPassTest.php index a4b769c02..d553d53f0 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/BuildClientRoutingPassTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/BuildClientRoutingPassTest.php @@ -9,6 +9,7 @@ use Enqueue\Bundle\Tests\Unit\DependencyInjection\Compiler\Mock\ProcessorNameCommandSubscriber; use Enqueue\Bundle\Tests\Unit\DependencyInjection\Compiler\Mock\ProcessorNameTopicSubscriber; use Enqueue\Bundle\Tests\Unit\DependencyInjection\Compiler\Mock\QueueNameTopicSubscriber; +use Enqueue\Bundle\Tests\Unit\DependencyInjection\Compiler\Mock\WithoutProcessorNameTopicSubscriber; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -213,6 +214,30 @@ public function testShouldBuildRouteFromSubscriberIfQueueNameSpecified() $this->assertEquals($expectedRoutes, $router->getArgument(1)); } + public function testShouldBuildRouteFromWithoutProcessorNameTopicSubscriber() + { + $container = $this->createContainerBuilder(); + + $processor = new Definition(WithoutProcessorNameTopicSubscriber::class); + $processor->addTag('enqueue.client.processor'); + $container->setDefinition('processor-service-id', $processor); + + $router = new Definition(); + $router->setArguments([null, null, null]); + $container->setDefinition('enqueue.client.router_processor', $router); + + $pass = new BuildClientRoutingPass(); + $pass->process($container); + + $expectedRoutes = [ + 'without-processor-name' => [ + ['processor-service-id', 'a_queue_name'], + ], + ]; + + $this->assertEquals($expectedRoutes, $router->getArgument(1)); + } + public function testShouldThrowExceptionWhenTopicSubscriberConfigurationIsInvalid() { $container = $this->createContainerBuilder(); diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/BuildProcessorRegistryPassTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/BuildProcessorRegistryPassTest.php index 0ad3d3483..c84a5aeba 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/BuildProcessorRegistryPassTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/BuildProcessorRegistryPassTest.php @@ -10,6 +10,7 @@ use Enqueue\Bundle\Tests\Unit\DependencyInjection\Compiler\Mock\OnlyTopicNameTopicSubscriber; use Enqueue\Bundle\Tests\Unit\DependencyInjection\Compiler\Mock\ProcessorNameCommandSubscriber; use Enqueue\Bundle\Tests\Unit\DependencyInjection\Compiler\Mock\ProcessorNameTopicSubscriber; +use Enqueue\Bundle\Tests\Unit\DependencyInjection\Compiler\Mock\WithoutProcessorNameTopicSubscriber; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -132,6 +133,28 @@ public function testShouldBuildRouteFromSubscriberIfOnlyTopicNameSpecified() $this->assertEquals($expectedValue, $processorRegistry->getArgument(0)); } + public function testShouldBuildRouteFromWithoutProcessorNameTopicSubscriber() + { + $container = $this->createContainerBuilder(); + + $processor = new Definition(WithoutProcessorNameTopicSubscriber::class); + $processor->addTag('enqueue.client.processor'); + $container->setDefinition('processor-id', $processor); + + $processorRegistry = new Definition(); + $processorRegistry->setArguments([]); + $container->setDefinition('enqueue.client.processor_registry', $processorRegistry); + + $pass = new BuildProcessorRegistryPass(); + $pass->process($container); + + $expectedValue = [ + 'processor-id' => 'processor-id', + ]; + + $this->assertEquals($expectedValue, $processorRegistry->getArgument(0)); + } + public function testShouldBuildRouteFromSubscriberIfProcessorNameSpecified() { $container = $this->createContainerBuilder(); diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/Mock/WithoutProcessorNameTopicSubscriber.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/Mock/WithoutProcessorNameTopicSubscriber.php new file mode 100644 index 000000000..fa30d9f78 --- /dev/null +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/Compiler/Mock/WithoutProcessorNameTopicSubscriber.php @@ -0,0 +1,18 @@ + [ + 'queueName' => 'a_queue_name', + 'queueNameHardcoded' => true, + ], + ]; + } +} From 6e16be88c03db5eb646dcfa53bfd402dd78d287d Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Wed, 13 Sep 2017 09:31:56 +0300 Subject: [PATCH 0008/1581] [dbal] add priority support on transport level. --- pkg/dbal/DbalConsumer.php | 2 +- pkg/dbal/DbalProducer.php | 22 +++-- .../Tests/DbalSendPriorityMessagesTest.php | 91 ------------------- ...ndReceivePriorityMessagesFromQueueTest.php | 62 +++++++++++++ 4 files changed, 78 insertions(+), 99 deletions(-) delete mode 100644 pkg/dbal/Tests/DbalSendPriorityMessagesTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php diff --git a/pkg/dbal/DbalConsumer.php b/pkg/dbal/DbalConsumer.php index 6368e24a2..169837aa4 100644 --- a/pkg/dbal/DbalConsumer.php +++ b/pkg/dbal/DbalConsumer.php @@ -176,7 +176,7 @@ protected function receiveMessage() ->where('queue = :queue') ->andWhere('(delayed_until IS NULL OR delayed_until <= :delayedUntil)') ->orderBy('priority', 'desc') - ->addOrderBy('id', 'asc') + ->addOrderBy('id', 'desc') ->setMaxResults(1) ; diff --git a/pkg/dbal/DbalProducer.php b/pkg/dbal/DbalProducer.php index 4d125bb10..85231d621 100644 --- a/pkg/dbal/DbalProducer.php +++ b/pkg/dbal/DbalProducer.php @@ -13,6 +13,11 @@ class DbalProducer implements PsrProducer { + /** + * @var int|null + */ + private $priority; + /** * @var DbalContext */ @@ -29,14 +34,19 @@ public function __construct(DbalContext $context) /** * {@inheritdoc} * - * @param PsrDestination $destination - * @param PsrMessage $message + * @param DbalDestination $destination + * @param DbalMessage $message * * @throws Exception */ public function send(PsrDestination $destination, PsrMessage $message) { InvalidDestinationException::assertDestinationInstanceOf($destination, DbalDestination::class); + InvalidMessageException::assertMessageInstanceOf($message, DbalMessage::class); + + if (null !== $this->priority && null === $message->getPriority()) { + $message->setPriority($this->priority); + } $body = $message->getBody(); if (is_scalar($body) || null === $body) { @@ -111,11 +121,9 @@ public function getDeliveryDelay() */ public function setPriority($priority) { - if (null === $priority) { - return; - } + $this->priority = $priority; - throw new \LogicException('Not implemented'); + return $this; } /** @@ -123,7 +131,7 @@ public function setPriority($priority) */ public function getPriority() { - return null; + return $this->priority; } /** diff --git a/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php b/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php deleted file mode 100644 index e470565d8..000000000 --- a/pkg/dbal/Tests/DbalSendPriorityMessagesTest.php +++ /dev/null @@ -1,91 +0,0 @@ -createContext(); - $queue = $this->createQueue($context, 'default'); - $consumer = $context->createConsumer($queue); - - // guard - $this->assertNull($consumer->receiveNoWait()); - - $messagePriorities = [1, 0, 3]; - $producer = $context->createProducer(); - foreach ($messagePriorities as $priority) { - $producer->send($queue, $this->createMessage($context, $priority)); - } - - sort($messagePriorities); - foreach (array_reverse($messagePriorities) as $priority) { - $message = $consumer->receive(8000); // 8 sec - - $this->assertInstanceOf(PsrMessage::class, $message); - $consumer->acknowledge($message); - $this->assertSame('priority'.$priority, $message->getBody()); - } - } - - /** - * @return PsrContext - */ - protected function createContext() - { - $factory = new DbalConnectionFactory( - [ - 'lazy' => true, - 'connection' => [ - 'dbname' => getenv('SYMFONY__DB__NAME'), - 'user' => getenv('SYMFONY__DB__USER'), - 'password' => getenv('SYMFONY__DB__PASSWORD'), - 'host' => getenv('SYMFONY__DB__HOST'), - 'port' => getenv('SYMFONY__DB__PORT'), - 'driver' => getenv('SYMFONY__DB__DRIVER'), - ], - ] - ); - - return $factory->createContext(); - } - - /** - * {@inheritdoc} - * - * @param DbalContext $context - */ - protected function createQueue(PsrContext $context, $queueName) - { - $queue = $context->createQueue($queueName); - $context->createDataBaseTable(); - - return $queue; - } - - /** - * @param PsrContext $context - * @param int $priority - * - * @return DbalMessage - */ - protected function createMessage(PsrContext $context, $priority) - { - /** @var DbalMessage $message */ - $message = $context->createMessage('priority'.$priority); - $message->setPriority($priority); - - return $message; - } -} diff --git a/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php b/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php new file mode 100644 index 000000000..455d4f1ce --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php @@ -0,0 +1,62 @@ + true, + 'connection' => [ + 'dbname' => getenv('SYMFONY__DB__NAME'), + 'user' => getenv('SYMFONY__DB__USER'), + 'password' => getenv('SYMFONY__DB__PASSWORD'), + 'host' => getenv('SYMFONY__DB__HOST'), + 'port' => getenv('SYMFONY__DB__PORT'), + 'driver' => getenv('SYMFONY__DB__DRIVER'), + ], + ]); + + $context = $factory->createContext(); + $context->createDataBaseTable(); + + return $context; + } + + /** + * {@inheritdoc} + * + * @return DbalMessage + */ + protected function createMessage(PsrContext $context, $priority) + { + /** @var DbalMessage $message */ + $message = $context->createMessage('priority'.$priority); + $message->setPriority($priority); + + return $message; + } + + /** + * {@inheritdoc} + * + * @return DbalDestination + */ + protected function createQueue(PsrContext $context, $queueName) + { + return parent::createQueue($context, $queueName.time()); + } +} From 1b9981c1a11aca2c0cca8b1de9b421d13fe2f411 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Wed, 13 Sep 2017 09:49:14 +0300 Subject: [PATCH 0009/1581] Release 0.7.13 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f5fdae11..bbb9f45ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Change Log +## [0.7.13](https://github.com/php-enqueue/enqueue-dev/tree/0.7.13) (2017-09-13) +[Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.12...0.7.13) + +- \[dbal\] add priority support on transport level. [\#198](https://github.com/php-enqueue/enqueue-dev/pull/198) ([makasim](https://github.com/makasim)) + +- Topic subscriber doesn't work with 2 separate apps [\#196](https://github.com/php-enqueue/enqueue-dev/issues/196) +- \\[dbal\\] add priority support on transport level. [\#198](https://github.com/php-enqueue/enqueue-dev/pull/198) ([makasim](https://github.com/makasim)) +- Fixed losing message priority for dbal driver [\#195](https://github.com/php-enqueue/enqueue-dev/pull/195) ([vtsykun](https://github.com/vtsykun)) + +- \[bundle\] add tests for the case where topic subscriber does not def p… [\#197](https://github.com/php-enqueue/enqueue-dev/pull/197) ([makasim](https://github.com/makasim)) + ## [0.7.12](https://github.com/php-enqueue/enqueue-dev/tree/0.7.12) (2017-09-12) [Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.11...0.7.12) From 9667cace27ee87d4db922b65c89adbefcaffaafa Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Wed, 13 Sep 2017 12:25:39 +0300 Subject: [PATCH 0010/1581] [dbal] revert unwanted change in dbal consumer. the change accidentaly changed behavior from FIFO to LIFO. --- pkg/dbal/DbalConsumer.php | 2 +- .../Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/dbal/DbalConsumer.php b/pkg/dbal/DbalConsumer.php index 169837aa4..6368e24a2 100644 --- a/pkg/dbal/DbalConsumer.php +++ b/pkg/dbal/DbalConsumer.php @@ -176,7 +176,7 @@ protected function receiveMessage() ->where('queue = :queue') ->andWhere('(delayed_until IS NULL OR delayed_until <= :delayedUntil)') ->orderBy('priority', 'desc') - ->addOrderBy('id', 'desc') + ->addOrderBy('id', 'asc') ->setMaxResults(1) ; diff --git a/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php b/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php index 455d4f1ce..8ebf430f0 100644 --- a/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php +++ b/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php @@ -13,6 +13,11 @@ */ class DbalSendAndReceivePriorityMessagesFromQueueTest extends SendAndReceivePriorityMessagesFromQueueSpec { + public function test() + { + $this->markTestSkipped('Skip for now. The dbal transport will be reworked in 0.8'); + } + /** * @return PsrContext */ From 332542467a10a884145f324671413478a6d022fb Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Wed, 13 Sep 2017 15:15:58 +0300 Subject: [PATCH 0011/1581] [dbal] Performance improvements and new features. --- pkg/dbal/Client/DbalDriver.php | 4 +- pkg/dbal/DbalConsumer.php | 97 ++++-- pkg/dbal/DbalContext.php | 11 +- pkg/dbal/DbalMessage.php | 41 ++- pkg/dbal/DbalProducer.php | 64 +++- pkg/dbal/Tests/Client/DbalDriverTest.php | 2 +- pkg/dbal/Tests/DbalConsumerTest.php | 298 ------------------ pkg/dbal/Tests/DbalMessageTest.php | 2 +- pkg/dbal/Tests/DbalProducerTest.php | 67 ---- .../Tests/Spec/CreateDbalContextTrait.php | 23 ++ .../Tests/Spec/DbalConnectionFactoryTest.php | 17 + pkg/dbal/Tests/Spec/DbalContextTest.php | 21 ++ pkg/dbal/Tests/Spec/DbalProducerTest.php | 21 ++ pkg/dbal/Tests/Spec/DbalQueueTest.php | 17 + ...dAndReceiveDelayedMessageFromQueueTest.php | 21 ++ ...ndReceivePriorityMessagesFromQueueTest.php | 34 +- ...ReceiveTimeToLiveMessagesFromQueueTest.php | 21 ++ .../DbalSendToAndReceiveFromQueueTest.php | 21 ++ .../DbalSendToAndReceiveFromTopicTest.php | 21 ++ ...balSendToAndReceiveNoWaitFromQueueTest.php | 21 ++ ...balSendToAndReceiveNoWaitFromTopicTest.php | 21 ++ pkg/dbal/Tests/Spec/DbalTopicTest.php | 17 + 22 files changed, 411 insertions(+), 451 deletions(-) create mode 100644 pkg/dbal/Tests/Spec/CreateDbalContextTrait.php create mode 100644 pkg/dbal/Tests/Spec/DbalConnectionFactoryTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalContextTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalProducerTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalQueueTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalSendAndReceiveDelayedMessageFromQueueTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalSendAndReceiveTimeToLiveMessagesFromQueueTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromTopicTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalSendToAndReceiveNoWaitFromQueueTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalSendToAndReceiveNoWaitFromTopicTest.php create mode 100644 pkg/dbal/Tests/Spec/DbalTopicTest.php diff --git a/pkg/dbal/Client/DbalDriver.php b/pkg/dbal/Client/DbalDriver.php index 8196a9b84..d5fd9a5a2 100644 --- a/pkg/dbal/Client/DbalDriver.php +++ b/pkg/dbal/Client/DbalDriver.php @@ -71,7 +71,7 @@ public function createTransportMessage(Message $message) $transportMessage->setProperties($properties); $transportMessage->setMessageId($message->getMessageId()); $transportMessage->setTimestamp($message->getTimestamp()); - $transportMessage->setDelay($message->getDelay()); + $transportMessage->setDeliveryDelay($message->getDelay()); $transportMessage->setReplyTo($message->getReplyTo()); $transportMessage->setCorrelationId($message->getCorrelationId()); if (array_key_exists($message->getPriority(), self::$priorityMap)) { @@ -97,7 +97,7 @@ public function createClientMessage(PsrMessage $message) $clientMessage->setContentType($message->getHeader('content_type')); $clientMessage->setMessageId($message->getMessageId()); $clientMessage->setTimestamp($message->getTimestamp()); - $clientMessage->setDelay($message->getDelay()); + $clientMessage->setDelay($message->getDeliveryDelay()); $clientMessage->setReplyTo($message->getReplyTo()); $clientMessage->setCorrelationId($message->getCorrelationId()); diff --git a/pkg/dbal/DbalConsumer.php b/pkg/dbal/DbalConsumer.php index 6368e24a2..f898e567f 100644 --- a/pkg/dbal/DbalConsumer.php +++ b/pkg/dbal/DbalConsumer.php @@ -169,31 +169,7 @@ protected function receiveMessage() try { $now = time(); - $query = $this->dbal->createQueryBuilder(); - $query - ->select('*') - ->from($this->context->getTableName()) - ->where('queue = :queue') - ->andWhere('(delayed_until IS NULL OR delayed_until <= :delayedUntil)') - ->orderBy('priority', 'desc') - ->addOrderBy('id', 'asc') - ->setMaxResults(1) - ; - - $sql = $query->getSQL().' '.$this->dbal->getDatabasePlatform()->getWriteLockSQL(); - - $dbalMessage = $this->dbal->executeQuery( - $sql, - [ - 'queue' => $this->queue->getQueueName(), - 'delayedUntil' => $now, - ], - [ - 'queue' => Type::STRING, - 'delayedUntil' => Type::INTEGER, - ] - )->fetch(); - + $dbalMessage = $this->fetchPrioritizedMessage($now) ?: $dbalMessage = $this->fetchMessage($now); if (false == $dbalMessage) { $this->dbal->commit(); @@ -211,9 +187,12 @@ protected function receiveMessage() $this->dbal->commit(); - return $this->convertMessage($dbalMessage); + if (empty($dbalMessage['time_to_live']) || $dbalMessage['time_to_live'] > time()) { + return $this->convertMessage($dbalMessage); + } } catch (\Exception $e) { $this->dbal->rollBack(); + throw $e; } } @@ -241,4 +220,70 @@ protected function convertMessage(array $dbalMessage) return $message; } + + /** + * @param int $now + * + * @return array|null + */ + private function fetchPrioritizedMessage($now) + { + $query = $this->dbal->createQueryBuilder(); + $query + ->select('*') + ->from($this->context->getTableName()) + ->andWhere('queue = :queue') + ->andWhere('priority IS NOT NULL') + ->andWhere('(delayed_until IS NULL OR delayed_until <= :delayedUntil)') + ->addOrderBy('priority', 'desc') + ->setMaxResults(1) + ; + + $sql = $query->getSQL().' '.$this->dbal->getDatabasePlatform()->getWriteLockSQL(); + + return $this->dbal->executeQuery( + $sql, + [ + 'queue' => $this->queue->getQueueName(), + 'delayedUntil' => $now, + ], + [ + 'queue' => Type::STRING, + 'delayedUntil' => Type::INTEGER, + ] + )->fetch(); + } + + /** + * @param int $now + * + * @return array|null + */ + private function fetchMessage($now) + { + $query = $this->dbal->createQueryBuilder(); + $query + ->select('*') + ->from($this->context->getTableName()) + ->andWhere('queue = :queue') + ->andWhere('priority IS NULL') + ->andWhere('(delayed_until IS NULL OR delayed_until <= :delayedUntil)') + ->addOrderBy('published_at', 'asc') + ->setMaxResults(1) + ; + + $sql = $query->getSQL().' '.$this->dbal->getDatabasePlatform()->getWriteLockSQL(); + + return $this->dbal->executeQuery( + $sql, + [ + 'queue' => $this->queue->getQueueName(), + 'delayedUntil' => $now, + ], + [ + 'queue' => Type::STRING, + 'delayedUntil' => Type::INTEGER, + ] + )->fetch(); + } } diff --git a/pkg/dbal/DbalContext.php b/pkg/dbal/DbalContext.php index 222492791..0570a4463 100644 --- a/pkg/dbal/DbalContext.php +++ b/pkg/dbal/DbalContext.php @@ -56,7 +56,7 @@ public function __construct($connection, array $config = []) * * @return DbalMessage */ - public function createMessage($body = null, array $properties = [], array $headers = []) + public function createMessage($body = '', array $properties = [], array $headers = []) { $message = new DbalMessage(); $message->setBody($body); @@ -170,8 +170,13 @@ public function createDataBaseTable() return; } + if ($this->getDbalConnection()->getDatabasePlatform()->hasNativeGuidType()) { + throw new \LogicException('The platform does not support UUIDs natively'); + } + $table = new Table($this->getTableName()); - $table->addColumn('id', 'integer', ['unsigned' => true, 'autoincrement' => true]); + $table->addColumn('id', 'guid'); + $table->addColumn('published_at', 'bigint'); $table->addColumn('body', 'text', ['notnull' => false]); $table->addColumn('headers', 'text', ['notnull' => false]); $table->addColumn('properties', 'text', ['notnull' => false]); @@ -179,8 +184,10 @@ public function createDataBaseTable() $table->addColumn('queue', 'string'); $table->addColumn('priority', 'smallint'); $table->addColumn('delayed_until', 'integer', ['notnull' => false]); + $table->addColumn('time_to_live', 'integer', ['notnull' => false]); $table->setPrimaryKey(['id']); + $table->addIndex(['published_at']); $table->addIndex(['queue']); $table->addIndex(['priority']); $table->addIndex(['delayed_until']); diff --git a/pkg/dbal/DbalMessage.php b/pkg/dbal/DbalMessage.php index a0409856e..979a53657 100644 --- a/pkg/dbal/DbalMessage.php +++ b/pkg/dbal/DbalMessage.php @@ -32,9 +32,14 @@ class DbalMessage implements PsrMessage private $priority; /** - * @var int + * @var int milliseconds + */ + private $deliveryDelay; + + /** + * @var int milliseconds */ - private $delay; + private $timeToLive; /** * @param string $body @@ -48,7 +53,7 @@ public function __construct($body = '', array $properties = [], array $headers = $this->headers = $headers; $this->redelivered = false; $this->priority = 0; - $this->delay = null; + $this->deliveryDelay = null; } /** @@ -182,19 +187,37 @@ public function setPriority($priority) /** * @return int */ - public function getDelay() + public function getDeliveryDelay() + { + return $this->deliveryDelay; + } + + /** + * Set delay in milliseconds. + * + * @param int $deliveryDelay + */ + public function setDeliveryDelay($deliveryDelay) + { + $this->deliveryDelay = $deliveryDelay; + } + + /** + * @return int|float|null + */ + public function getTimeToLive() { - return $this->delay; + return $this->timeToLive; } /** - * Set delay in seconds. + * Set time to live in milliseconds. * - * @param int $delay + * @param int|float|null $timeToLive */ - public function setDelay($delay) + public function setTimeToLive($timeToLive) { - $this->delay = $delay; + $this->timeToLive = $timeToLive; } /** diff --git a/pkg/dbal/DbalProducer.php b/pkg/dbal/DbalProducer.php index 85231d621..c8f58bc20 100644 --- a/pkg/dbal/DbalProducer.php +++ b/pkg/dbal/DbalProducer.php @@ -18,6 +18,16 @@ class DbalProducer implements PsrProducer */ private $priority; + /** + * @var int|float|null + */ + private $deliveryDelay; + + /** + * @var int|float|null + */ + private $timeToLive; + /** * @var DbalContext */ @@ -47,6 +57,12 @@ public function send(PsrDestination $destination, PsrMessage $message) if (null !== $this->priority && null === $message->getPriority()) { $message->setPriority($this->priority); } + if (null !== $this->deliveryDelay && null === $message->getDeliveryDelay()) { + $message->setDeliveryDelay($this->deliveryDelay); + } + if (null !== $this->timeToLive && null === $message->getTimeToLive()) { + $message->setTimeToLive($this->timeToLive); + } $body = $message->getBody(); if (is_scalar($body) || null === $body) { @@ -58,7 +74,16 @@ public function send(PsrDestination $destination, PsrMessage $message) )); } + $sql = 'SELECT '.$this->context->getDbalConnection()->getDatabasePlatform()->getGuidExpression(); + $uuid = $this->context->getDbalConnection()->query($sql)->fetchColumn(0); + + if (empty($uuid)) { + throw new \LogicException('The generated uuid is empty'); + } + $dbalMessage = [ + 'id' => $uuid, + 'published_at' => (int) microtime(true) * 10000, 'body' => $body, 'headers' => JSON::encode($message->getHeaders()), 'properties' => JSON::encode($message->getProperties()), @@ -66,7 +91,7 @@ public function send(PsrDestination $destination, PsrMessage $message) 'queue' => $destination->getQueueName(), ]; - $delay = $message->getDelay(); + $delay = $message->getDeliveryDelay(); if ($delay) { if (!is_int($delay)) { throw new \LogicException(sprintf( @@ -79,16 +104,35 @@ public function send(PsrDestination $destination, PsrMessage $message) throw new \LogicException(sprintf('Delay must be positive integer but got: "%s"', $delay)); } - $dbalMessage['delayed_until'] = time() + $delay; + $dbalMessage['delayed_until'] = time() + (int) $delay / 1000; + } + + $timeToLive = $message->getTimeToLive(); + if ($timeToLive) { + if (!is_int($timeToLive)) { + throw new \LogicException(sprintf( + 'TimeToLive must be integer but got: "%s"', + is_object($timeToLive) ? get_class($timeToLive) : gettype($timeToLive) + )); + } + + if ($timeToLive <= 0) { + throw new \LogicException(sprintf('TimeToLive must be positive integer but got: "%s"', $timeToLive)); + } + + $dbalMessage['time_to_live'] = time() + (int) $timeToLive / 1000; } try { $this->context->getDbalConnection()->insert($this->context->getTableName(), $dbalMessage, [ + 'id' => Type::GUID, + 'published_at' => Type::INTEGER, 'body' => Type::TEXT, 'headers' => Type::TEXT, 'properties' => Type::TEXT, 'priority' => Type::SMALLINT, 'queue' => Type::STRING, + 'time_to_live' => Type::INTEGER, 'delayed_until' => Type::INTEGER, ]); } catch (\Exception $e) { @@ -101,11 +145,9 @@ public function send(PsrDestination $destination, PsrMessage $message) */ public function setDeliveryDelay($deliveryDelay) { - if (null === $deliveryDelay) { - return; - } + $this->deliveryDelay = $deliveryDelay; - throw new \LogicException('Not implemented'); + return $this; } /** @@ -113,7 +155,7 @@ public function setDeliveryDelay($deliveryDelay) */ public function getDeliveryDelay() { - return null; + return $this->deliveryDelay; } /** @@ -139,11 +181,7 @@ public function getPriority() */ public function setTimeToLive($timeToLive) { - if (null === $timeToLive) { - return; - } - - throw new \LogicException('Not implemented'); + $this->timeToLive = $timeToLive; } /** @@ -151,6 +189,6 @@ public function setTimeToLive($timeToLive) */ public function getTimeToLive() { - return null; + return $this->timeToLive; } } diff --git a/pkg/dbal/Tests/Client/DbalDriverTest.php b/pkg/dbal/Tests/Client/DbalDriverTest.php index 232e3ceaf..6c8de2016 100644 --- a/pkg/dbal/Tests/Client/DbalDriverTest.php +++ b/pkg/dbal/Tests/Client/DbalDriverTest.php @@ -93,7 +93,7 @@ public function testShouldConvertTransportMessageToClientMessage() $transportMessage->setMessageId('MessageId'); $transportMessage->setTimestamp(1000); $transportMessage->setPriority(2); - $transportMessage->setDelay(12345); + $transportMessage->setDeliveryDelay(12345); $driver = new DbalDriver( $this->createPsrContextMock(), diff --git a/pkg/dbal/Tests/DbalConsumerTest.php b/pkg/dbal/Tests/DbalConsumerTest.php index 6fcf7fa9e..87c4233d3 100644 --- a/pkg/dbal/Tests/DbalConsumerTest.php +++ b/pkg/dbal/Tests/DbalConsumerTest.php @@ -131,304 +131,6 @@ public function testRejectShouldThrowIfMessageWasNotInserted() $consumer->reject($message, true); } - public function testShouldReceiveMessage() - { - $dbalMessage = [ - 'id' => 'id', - 'body' => 'body', - 'headers' => '{"hkey":"hvalue"}', - 'properties' => '{"pkey":"pvalue"}', - 'priority' => 5, - 'queue' => 'queue', - 'redelivered' => true, - ]; - - $statement = $this->createStatementMock(); - $statement - ->expects($this->once()) - ->method('fetch') - ->will($this->returnValue($dbalMessage)) - ; - - $queryBuilder = $this->createQueryBuilderMock(); - $queryBuilder - ->expects($this->once()) - ->method('select') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('from') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('where') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('andWhere') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->exactly(1)) - ->method('orderBy') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->exactly(1)) - ->method('addOrderBy') - ->will($this->returnSelf()) - ; - - $platform = $this->createPlatformMock(); - - $dbal = $this->createConnectionMock(); - $dbal - ->expects($this->once()) - ->method('createQueryBuilder') - ->willReturn($queryBuilder) - ; - $dbal - ->expects($this->once()) - ->method('executeQuery') - ->willReturn($statement) - ; - $dbal - ->expects($this->once()) - ->method('delete') - ->willReturn(1) - ; - $dbal - ->expects($this->once()) - ->method('commit') - ; - $dbal - ->expects($this->once()) - ->method('getDatabasePlatform') - ->willReturn($platform) - ; - - $context = $this->createContextMock(); - $context - ->expects($this->once()) - ->method('getDbalConnection') - ->will($this->returnValue($dbal)) - ; - $context - ->expects($this->atLeastOnce()) - ->method('getTableName') - ->will($this->returnValue('tableName')) - ; - $context - ->expects($this->once()) - ->method('createMessage') - ->willReturn(new DbalMessage()) - ; - - $consumer = new DbalConsumer($context, new DbalDestination('queue')); - $result = $consumer->receiveNoWait(); - - $this->assertInstanceOf(DbalMessage::class, $result); - $this->assertEquals('body', $result->getBody()); - $this->assertEquals(['hkey' => 'hvalue'], $result->getHeaders()); - $this->assertEquals(['pkey' => 'pvalue'], $result->getProperties()); - $this->assertTrue($result->isRedelivered()); - $this->assertEquals(5, $result->getPriority()); - } - - public function testShouldReturnNullIfThereIsNoNewMessage() - { - $statement = $this->createStatementMock(); - $statement - ->expects($this->once()) - ->method('fetch') - ->will($this->returnValue(null)) - ; - - $queryBuilder = $this->createQueryBuilderMock(); - $queryBuilder - ->expects($this->once()) - ->method('select') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('from') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('where') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('andWhere') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->exactly(1)) - ->method('orderBy') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->exactly(1)) - ->method('addOrderBy') - ->will($this->returnSelf()) - ; - - $platform = $this->createPlatformMock(); - - $dbal = $this->createConnectionMock(); - $dbal - ->expects($this->once()) - ->method('createQueryBuilder') - ->willReturn($queryBuilder) - ; - $dbal - ->expects($this->once()) - ->method('executeQuery') - ->willReturn($statement) - ; - $dbal - ->expects($this->never()) - ->method('delete') - ->willReturn(1) - ; - $dbal - ->expects($this->once()) - ->method('commit') - ; - $dbal - ->expects($this->once()) - ->method('getDatabasePlatform') - ->willReturn($platform) - ; - - $context = $this->createContextMock(); - $context - ->expects($this->once()) - ->method('getDbalConnection') - ->will($this->returnValue($dbal)) - ; - $context - ->expects($this->atLeastOnce()) - ->method('getTableName') - ->will($this->returnValue('tableName')) - ; - $context - ->expects($this->never()) - ->method('createMessage') - ->willReturn(new DbalMessage()) - ; - - $consumer = new DbalConsumer($context, new DbalDestination('queue')); - $consumer->setPollingInterval(1000); - $result = $consumer->receive(.000001); - - $this->assertEmpty($result); - } - - public function testShouldThrowIfMessageWasNotRemoved() - { - $statement = $this->createStatementMock(); - $statement - ->expects($this->once()) - ->method('fetch') - ->will($this->returnValue(['id' => '2134'])) - ; - - $queryBuilder = $this->createQueryBuilderMock(); - $queryBuilder - ->expects($this->once()) - ->method('select') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('from') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('where') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->once()) - ->method('andWhere') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->exactly(1)) - ->method('orderBy') - ->will($this->returnSelf()) - ; - $queryBuilder - ->expects($this->exactly(1)) - ->method('addOrderBy') - ->will($this->returnSelf()) - ; - - $platform = $this->createPlatformMock(); - - $dbal = $this->createConnectionMock(); - $dbal - ->expects($this->once()) - ->method('createQueryBuilder') - ->willReturn($queryBuilder) - ; - $dbal - ->expects($this->once()) - ->method('executeQuery') - ->willReturn($statement) - ; - $dbal - ->expects($this->once()) - ->method('delete') - ->willReturn(0) - ; - $dbal - ->expects($this->never()) - ->method('commit') - ; - $dbal - ->expects($this->once()) - ->method('rollBack') - ; - $dbal - ->expects($this->once()) - ->method('getDatabasePlatform') - ->willReturn($platform) - ; - - $context = $this->createContextMock(); - $context - ->expects($this->once()) - ->method('getDbalConnection') - ->will($this->returnValue($dbal)) - ; - $context - ->expects($this->atLeastOnce()) - ->method('getTableName') - ->will($this->returnValue('tableName')) - ; - $context - ->expects($this->never()) - ->method('createMessage') - ->willReturn(new DbalMessage()) - ; - - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('Expected record was removed but it is not. id: "2134"'); - - $consumer = new DbalConsumer($context, new DbalDestination('queue')); - $consumer->setPollingInterval(1000); - $consumer->receive(.000001); - } - /** * @return \PHPUnit_Framework_MockObject_MockObject|Connection */ diff --git a/pkg/dbal/Tests/DbalMessageTest.php b/pkg/dbal/Tests/DbalMessageTest.php index a31c37e93..c0af060d5 100644 --- a/pkg/dbal/Tests/DbalMessageTest.php +++ b/pkg/dbal/Tests/DbalMessageTest.php @@ -38,7 +38,7 @@ public function testShouldSetDelayToNullInConstructor() { $message = new DbalMessage(); - $this->assertNull($message->getDelay()); + $this->assertNull($message->getDeliveryDelay()); } public function testShouldSetCorrelationIdAsHeader() diff --git a/pkg/dbal/Tests/DbalProducerTest.php b/pkg/dbal/Tests/DbalProducerTest.php index b9ad69471..370c94a22 100644 --- a/pkg/dbal/Tests/DbalProducerTest.php +++ b/pkg/dbal/Tests/DbalProducerTest.php @@ -8,7 +8,6 @@ use Enqueue\Dbal\DbalMessage; use Enqueue\Dbal\DbalProducer; use Enqueue\Test\ClassExtensionTrait; -use Interop\Queue\Exception; use Interop\Queue\InvalidDestinationException; use Interop\Queue\InvalidMessageException; use Interop\Queue\PsrDestination; @@ -54,72 +53,6 @@ public function testShouldThrowIfDestinationOfInvalidType() $producer->send(new NotSupportedDestination1(), new DbalMessage()); } - public function testShouldThrowIfInsertMessageFailed() - { - $dbal = $this->createConnectionMock(); - $dbal - ->expects($this->once()) - ->method('insert') - ->will($this->throwException(new \Exception('error message'))) - ; - - $context = $this->createContextMock(); - $context - ->expects($this->once()) - ->method('getDbalConnection') - ->will($this->returnValue($dbal)) - ; - - $destination = new DbalDestination('queue-name'); - $message = new DbalMessage(); - - $this->expectException(Exception::class); - $this->expectExceptionMessage('The transport fails to send the message due to some internal error.'); - - $producer = new DbalProducer($context); - $producer->send($destination, $message); - } - - public function testShouldSendMessage() - { - $expectedMessage = [ - 'body' => 'body', - 'headers' => '{"hkey":"hvalue"}', - 'properties' => '{"pkey":"pvalue"}', - 'priority' => 123, - 'queue' => 'queue-name', - ]; - - $dbal = $this->createConnectionMock(); - $dbal - ->expects($this->once()) - ->method('insert') - ->with('tableName', $expectedMessage) - ; - - $context = $this->createContextMock(); - $context - ->expects($this->once()) - ->method('getDbalConnection') - ->will($this->returnValue($dbal)) - ; - $context - ->expects($this->once()) - ->method('getTableName') - ->will($this->returnValue('tableName')) - ; - - $destination = new DbalDestination('queue-name'); - $message = new DbalMessage(); - $message->setBody('body'); - $message->setHeaders(['hkey' => 'hvalue']); - $message->setProperties(['pkey' => 'pvalue']); - $message->setPriority(123); - - $producer = new DbalProducer($context); - $producer->send($destination, $message); - } - /** * @return \PHPUnit_Framework_MockObject_MockObject|DbalContext */ diff --git a/pkg/dbal/Tests/Spec/CreateDbalContextTrait.php b/pkg/dbal/Tests/Spec/CreateDbalContextTrait.php new file mode 100644 index 000000000..107dca5dd --- /dev/null +++ b/pkg/dbal/Tests/Spec/CreateDbalContextTrait.php @@ -0,0 +1,23 @@ +markTestSkipped('The DOCTRINE_DSN env is not available. Skip tests'); + } + + $factory = new DbalConnectionFactory($env); + + $context = $factory->createContext(); + $context->getDbalConnection()->getSchemaManager()->dropTable($context->getTableName()); + $context->createDataBaseTable(); + + return $context; + } +} diff --git a/pkg/dbal/Tests/Spec/DbalConnectionFactoryTest.php b/pkg/dbal/Tests/Spec/DbalConnectionFactoryTest.php new file mode 100644 index 000000000..2ed159787 --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalConnectionFactoryTest.php @@ -0,0 +1,17 @@ +createDbalContext(); + } +} diff --git a/pkg/dbal/Tests/Spec/DbalProducerTest.php b/pkg/dbal/Tests/Spec/DbalProducerTest.php new file mode 100644 index 000000000..2580d3fd3 --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalProducerTest.php @@ -0,0 +1,21 @@ +createDbalContext()->createProducer(); + } +} diff --git a/pkg/dbal/Tests/Spec/DbalQueueTest.php b/pkg/dbal/Tests/Spec/DbalQueueTest.php new file mode 100644 index 000000000..091a48046 --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalQueueTest.php @@ -0,0 +1,17 @@ +createDbalContext(); + } +} diff --git a/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php b/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php index 8ebf430f0..5ddc64509 100644 --- a/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php +++ b/pkg/dbal/Tests/Spec/DbalSendAndReceivePriorityMessagesFromQueueTest.php @@ -2,8 +2,6 @@ namespace Enqueue\Dbal\Tests\Spec; -use Enqueue\Dbal\DbalConnectionFactory; -use Enqueue\Dbal\DbalDestination; use Enqueue\Dbal\DbalMessage; use Interop\Queue\PsrContext; use Interop\Queue\Spec\SendAndReceivePriorityMessagesFromQueueSpec; @@ -13,32 +11,14 @@ */ class DbalSendAndReceivePriorityMessagesFromQueueTest extends SendAndReceivePriorityMessagesFromQueueSpec { - public function test() - { - $this->markTestSkipped('Skip for now. The dbal transport will be reworked in 0.8'); - } + use CreateDbalContextTrait; /** * @return PsrContext */ protected function createContext() { - $factory = new DbalConnectionFactory([ - 'lazy' => true, - 'connection' => [ - 'dbname' => getenv('SYMFONY__DB__NAME'), - 'user' => getenv('SYMFONY__DB__USER'), - 'password' => getenv('SYMFONY__DB__PASSWORD'), - 'host' => getenv('SYMFONY__DB__HOST'), - 'port' => getenv('SYMFONY__DB__PORT'), - 'driver' => getenv('SYMFONY__DB__DRIVER'), - ], - ]); - - $context = $factory->createContext(); - $context->createDataBaseTable(); - - return $context; + return $this->createDbalContext(); } /** @@ -54,14 +34,4 @@ protected function createMessage(PsrContext $context, $priority) return $message; } - - /** - * {@inheritdoc} - * - * @return DbalDestination - */ - protected function createQueue(PsrContext $context, $queueName) - { - return parent::createQueue($context, $queueName.time()); - } } diff --git a/pkg/dbal/Tests/Spec/DbalSendAndReceiveTimeToLiveMessagesFromQueueTest.php b/pkg/dbal/Tests/Spec/DbalSendAndReceiveTimeToLiveMessagesFromQueueTest.php new file mode 100644 index 000000000..478005030 --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalSendAndReceiveTimeToLiveMessagesFromQueueTest.php @@ -0,0 +1,21 @@ +createDbalContext(); + } +} diff --git a/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php new file mode 100644 index 000000000..8535709e1 --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php @@ -0,0 +1,21 @@ +createDbalContext(); + } +} diff --git a/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromTopicTest.php b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromTopicTest.php new file mode 100644 index 000000000..c2b6c085b --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromTopicTest.php @@ -0,0 +1,21 @@ +createDbalContext(); + } +} diff --git a/pkg/dbal/Tests/Spec/DbalSendToAndReceiveNoWaitFromQueueTest.php b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveNoWaitFromQueueTest.php new file mode 100644 index 000000000..523673d1c --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveNoWaitFromQueueTest.php @@ -0,0 +1,21 @@ +createDbalContext(); + } +} diff --git a/pkg/dbal/Tests/Spec/DbalSendToAndReceiveNoWaitFromTopicTest.php b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveNoWaitFromTopicTest.php new file mode 100644 index 000000000..e8f94bb44 --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveNoWaitFromTopicTest.php @@ -0,0 +1,21 @@ +createDbalContext(); + } +} diff --git a/pkg/dbal/Tests/Spec/DbalTopicTest.php b/pkg/dbal/Tests/Spec/DbalTopicTest.php new file mode 100644 index 000000000..91bd52fd0 --- /dev/null +++ b/pkg/dbal/Tests/Spec/DbalTopicTest.php @@ -0,0 +1,17 @@ + Date: Wed, 13 Sep 2017 15:29:56 +0300 Subject: [PATCH 0012/1581] require 0.8.x --- pkg/amqp-bunny/composer.json | 10 ++++----- pkg/amqp-ext/composer.json | 10 ++++----- pkg/amqp-lib/composer.json | 10 ++++----- pkg/amqp-tools/composer.json | 6 ++--- pkg/async-event-dispatcher/composer.json | 10 ++++----- pkg/dbal/composer.json | 8 +++---- pkg/enqueue-bundle/composer.json | 28 ++++++++++++------------ pkg/enqueue/composer.json | 20 ++++++++--------- pkg/fs/composer.json | 2 +- pkg/gearman/composer.json | 8 +++---- pkg/gps/composer.json | 6 ++--- pkg/job-queue/composer.json | 8 +++---- pkg/null/composer.json | 6 ++--- pkg/pheanstalk/composer.json | 8 +++---- pkg/rdkafka/composer.json | 8 +++---- pkg/redis/composer.json | 8 +++---- pkg/simple-client/composer.json | 12 +++++----- pkg/sqs/composer.json | 6 ++--- pkg/stomp/composer.json | 8 +++---- pkg/test/composer.json | 2 +- 20 files changed, 92 insertions(+), 92 deletions(-) diff --git a/pkg/amqp-bunny/composer.json b/pkg/amqp-bunny/composer.json index b4e4c495f..f69f26b65 100644 --- a/pkg/amqp-bunny/composer.json +++ b/pkg/amqp-bunny/composer.json @@ -9,13 +9,13 @@ "queue-interop/amqp-interop": "^0.6@dev", "bunny/bunny": "^0.2.4", - "enqueue/amqp-tools": "^0.7@dev" + "enqueue/amqp-tools": "^0.8@dev" }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -32,7 +32,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/amqp-ext/composer.json b/pkg/amqp-ext/composer.json index b26606d4a..34e18a205 100644 --- a/pkg/amqp-ext/composer.json +++ b/pkg/amqp-ext/composer.json @@ -9,13 +9,13 @@ "ext-amqp": "^1.6", "queue-interop/amqp-interop": "^0.6@dev", - "enqueue/amqp-tools": "^0.7@dev" + "enqueue/amqp-tools": "^0.8@dev" }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "empi89/php-amqp-stubs": "*@dev", "symfony/dependency-injection": "^2.8|^3", @@ -33,7 +33,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/amqp-lib/composer.json b/pkg/amqp-lib/composer.json index d530b6567..60e0cac9f 100644 --- a/pkg/amqp-lib/composer.json +++ b/pkg/amqp-lib/composer.json @@ -9,13 +9,13 @@ "php-amqplib/php-amqplib": "^2.7@dev", "queue-interop/queue-interop": "^0.6@dev", "queue-interop/amqp-interop": "^0.6@dev", - "enqueue/amqp-tools": "^0.7@dev" + "enqueue/amqp-tools": "^0.8@dev" }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -32,7 +32,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/amqp-tools/composer.json b/pkg/amqp-tools/composer.json index 85dbf2753..f4e9077c1 100644 --- a/pkg/amqp-tools/composer.json +++ b/pkg/amqp-tools/composer.json @@ -11,8 +11,8 @@ }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/null": "^0.7@dev" + "enqueue/test": "^0.8@dev", + "enqueue/null": "^0.8@dev" }, "autoload": { "psr-4": { "Enqueue\\AmqpTools\\": "" }, @@ -23,7 +23,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/async-event-dispatcher/composer.json b/pkg/async-event-dispatcher/composer.json index f34253cff..35e39f3ac 100644 --- a/pkg/async-event-dispatcher/composer.json +++ b/pkg/async-event-dispatcher/composer.json @@ -6,7 +6,7 @@ "license": "MIT", "require": { "php": ">=5.6", - "enqueue/enqueue": "^0.7@dev", + "enqueue/enqueue": "^0.8@dev", "symfony/event-dispatcher": "^2.8|^3" }, "require-dev": { @@ -15,9 +15,9 @@ "symfony/config": "^2.8|^3", "symfony/http-kernel": "^2.8|^3", "symfony/filesystem": "^2.8|^3", - "enqueue/null": "^0.7@dev", - "enqueue/fs": "^0.7@dev", - "enqueue/test": "^0.7@dev" + "enqueue/null": "^0.8@dev", + "enqueue/fs": "^0.8@dev", + "enqueue/test": "^0.8@dev" }, "suggest": { "symfony/dependency-injection": "^2.8|^3 If you'd like to use async event dispatcher container extension." @@ -30,7 +30,7 @@ }, "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/dbal/composer.json b/pkg/dbal/composer.json index 09ed4248e..a5857d800 100644 --- a/pkg/dbal/composer.json +++ b/pkg/dbal/composer.json @@ -11,9 +11,9 @@ }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -30,7 +30,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/enqueue-bundle/composer.json b/pkg/enqueue-bundle/composer.json index 742fea0af..4592a6dbc 100644 --- a/pkg/enqueue-bundle/composer.json +++ b/pkg/enqueue-bundle/composer.json @@ -7,23 +7,23 @@ "require": { "php": ">=5.6", "symfony/framework-bundle": "^2.8|^3", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", - "enqueue/async-event-dispatcher": "^0.7@dev" + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", + "enqueue/async-event-dispatcher": "^0.8@dev" }, "require-dev": { "phpunit/phpunit": "~5.5", - "enqueue/stomp": "^0.7@dev", - "enqueue/amqp-ext": "^0.7@dev", + "enqueue/stomp": "^0.8@dev", + "enqueue/amqp-ext": "^0.8@dev", "php-amqplib/php-amqplib": "^2.7@dev", - "enqueue/amqp-lib": "^0.7@dev", - "enqueue/amqp-bunny": "^0.7@dev", - "enqueue/job-queue": "^0.7@dev", - "enqueue/fs": "^0.7@dev", - "enqueue/redis": "^0.7@dev", - "enqueue/dbal": "^0.7@dev", - "enqueue/sqs": "^0.7@dev", - "enqueue/test": "^0.7@dev", + "enqueue/amqp-lib": "^0.8@dev", + "enqueue/amqp-bunny": "^0.8@dev", + "enqueue/job-queue": "^0.8@dev", + "enqueue/fs": "^0.8@dev", + "enqueue/redis": "^0.8@dev", + "enqueue/dbal": "^0.8@dev", + "enqueue/sqs": "^0.8@dev", + "enqueue/test": "^0.8@dev", "doctrine/doctrine-bundle": "~1.2", "symfony/monolog-bundle": "^2.8|^3", "symfony/browser-kit": "^2.8|^3", @@ -37,7 +37,7 @@ }, "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/enqueue/composer.json b/pkg/enqueue/composer.json index 80b65d521..a4a6f2521 100644 --- a/pkg/enqueue/composer.json +++ b/pkg/enqueue/composer.json @@ -7,7 +7,7 @@ "require": { "php": ">=5.6", "queue-interop/queue-interop": "^0.6@dev", - "enqueue/null": "^0.7@dev", + "enqueue/null": "^0.8@dev", "ramsey/uuid": "^2|^3.5", "psr/log": "^1" }, @@ -18,14 +18,14 @@ "symfony/config": "^2.8|^3", "symfony/event-dispatcher": "^2.8|^3", "symfony/http-kernel": "^2.8|^3", - "enqueue/amqp-ext": "^0.7@dev", - "enqueue/pheanstalk": "^0.7@dev", - "enqueue/gearman": "^0.7@dev", - "enqueue/rdkafka": "^0.7@dev", - "enqueue/dbal": "^0.7@dev", - "enqueue/fs": "^0.7@dev", - "enqueue/test": "^0.7@dev", - "enqueue/simple-client": "^0.7@dev", + "enqueue/amqp-ext": "^0.8@dev", + "enqueue/pheanstalk": "^0.8@dev", + "enqueue/gearman": "^0.8@dev", + "enqueue/rdkafka": "^0.8@dev", + "enqueue/dbal": "^0.8@dev", + "enqueue/fs": "^0.8@dev", + "enqueue/test": "^0.8@dev", + "enqueue/simple-client": "^0.8@dev", "empi89/php-amqp-stubs": "*@dev" }, "suggest": { @@ -49,7 +49,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/fs/composer.json b/pkg/fs/composer.json index 5494b705e..b9a94b7f1 100644 --- a/pkg/fs/composer.json +++ b/pkg/fs/composer.json @@ -29,7 +29,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/gearman/composer.json b/pkg/gearman/composer.json index a26d3f984..b3eac2020 100644 --- a/pkg/gearman/composer.json +++ b/pkg/gearman/composer.json @@ -11,9 +11,9 @@ }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -30,7 +30,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/gps/composer.json b/pkg/gps/composer.json index ae3d50aa0..6f70d8f90 100644 --- a/pkg/gps/composer.json +++ b/pkg/gps/composer.json @@ -11,8 +11,8 @@ }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -29,7 +29,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/job-queue/composer.json b/pkg/job-queue/composer.json index 1d0d57895..816c5c164 100644 --- a/pkg/job-queue/composer.json +++ b/pkg/job-queue/composer.json @@ -7,13 +7,13 @@ "require": { "php": ">=5.6", "symfony/framework-bundle": "^2.8|^3", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "doctrine/orm": "~2.4" }, "require-dev": { "phpunit/phpunit": "~5.5", - "enqueue/test": "^0.7@dev", + "enqueue/test": "^0.8@dev", "doctrine/doctrine-bundle": "~1.2", "symfony/browser-kit": "^2.8|^3", "symfony/expression-language": "^2.8|^3" @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/null/composer.json b/pkg/null/composer.json index 58bdafcb3..f74a00f8d 100644 --- a/pkg/null/composer.json +++ b/pkg/null/composer.json @@ -10,8 +10,8 @@ }, "require-dev": { "phpunit/phpunit": "~5.5", - "enqueue/enqueue": "^0.7@dev", - "enqueue/test": "^0.7@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/test": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/pheanstalk/composer.json b/pkg/pheanstalk/composer.json index 2c3f58f77..4518f3470 100644 --- a/pkg/pheanstalk/composer.json +++ b/pkg/pheanstalk/composer.json @@ -11,9 +11,9 @@ }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -30,7 +30,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/rdkafka/composer.json b/pkg/rdkafka/composer.json index a50392ed6..b02f3cc4c 100644 --- a/pkg/rdkafka/composer.json +++ b/pkg/rdkafka/composer.json @@ -11,9 +11,9 @@ }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "kwn/php-rdkafka-stubs": "^1.0.2" }, @@ -40,7 +40,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/redis/composer.json b/pkg/redis/composer.json index 97b138ad0..db13a09c2 100644 --- a/pkg/redis/composer.json +++ b/pkg/redis/composer.json @@ -11,9 +11,9 @@ "require-dev": { "phpunit/phpunit": "~5.4.0", "predis/predis": "^1.1", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -32,7 +32,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/simple-client/composer.json b/pkg/simple-client/composer.json index 38a3a8428..4f1c737ab 100644 --- a/pkg/simple-client/composer.json +++ b/pkg/simple-client/composer.json @@ -6,17 +6,17 @@ "license": "MIT", "require": { "php": ">=5.6", - "enqueue/enqueue": "^0.7@dev", + "enqueue/enqueue": "^0.8@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3", "symfony/console": "^2.8|^3" }, "require-dev": { "phpunit/phpunit": "~5.5", - "enqueue/test": "^0.7@dev", - "enqueue/amqp-ext": "^0.7@dev", - "enqueue/fs": "^0.7@dev", - "enqueue/null": "^0.7@dev" + "enqueue/test": "^0.8@dev", + "enqueue/amqp-ext": "^0.8@dev", + "enqueue/fs": "^0.8@dev", + "enqueue/null": "^0.8@dev" }, "autoload": { "psr-4": { "Enqueue\\SimpleClient\\": "" }, @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/sqs/composer.json b/pkg/sqs/composer.json index 7598022db..7a5e181e5 100644 --- a/pkg/sqs/composer.json +++ b/pkg/sqs/composer.json @@ -11,8 +11,8 @@ }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -29,7 +29,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/stomp/composer.json b/pkg/stomp/composer.json index d071535f3..a41fe0333 100644 --- a/pkg/stomp/composer.json +++ b/pkg/stomp/composer.json @@ -13,9 +13,9 @@ }, "require-dev": { "phpunit/phpunit": "~5.4.0", - "enqueue/test": "^0.7@dev", - "enqueue/enqueue": "^0.7@dev", - "enqueue/null": "^0.7@dev", + "enqueue/test": "^0.8@dev", + "enqueue/enqueue": "^0.8@dev", + "enqueue/null": "^0.8@dev", "queue-interop/queue-spec": "^0.5@dev", "symfony/dependency-injection": "^2.8|^3", "symfony/config": "^2.8|^3" @@ -32,7 +32,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } diff --git a/pkg/test/composer.json b/pkg/test/composer.json index 5c89bfd2e..8d25ea853 100644 --- a/pkg/test/composer.json +++ b/pkg/test/composer.json @@ -7,7 +7,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "0.7.x-dev" + "dev-master": "0.8.x-dev" } } } From 5850b7fd215290ed9752d85910fdb6d251b35d4c Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Wed, 13 Sep 2017 15:40:22 +0300 Subject: [PATCH 0013/1581] fix phpstan issues. --- pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php index 8535709e1..84ae52345 100644 --- a/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php +++ b/pkg/dbal/Tests/Spec/DbalSendToAndReceiveFromQueueTest.php @@ -1,8 +1,8 @@ Date: Wed, 13 Sep 2017 15:52:49 +0300 Subject: [PATCH 0014/1581] fix tests. --- pkg/dbal/Tests/Spec/CreateDbalContextTrait.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/dbal/Tests/Spec/CreateDbalContextTrait.php b/pkg/dbal/Tests/Spec/CreateDbalContextTrait.php index 107dca5dd..d4c954afb 100644 --- a/pkg/dbal/Tests/Spec/CreateDbalContextTrait.php +++ b/pkg/dbal/Tests/Spec/CreateDbalContextTrait.php @@ -15,7 +15,11 @@ protected function createDbalContext() $factory = new DbalConnectionFactory($env); $context = $factory->createContext(); - $context->getDbalConnection()->getSchemaManager()->dropTable($context->getTableName()); + + if ($context->getDbalConnection()->getSchemaManager()->tablesExist([$context->getTableName()])) { + $context->getDbalConnection()->getSchemaManager()->dropTable($context->getTableName()); + } + $context->createDataBaseTable(); return $context; From c4cf691edc33da972e8659ef6fe96c4cde266126 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Wed, 13 Sep 2017 17:05:44 +0300 Subject: [PATCH 0015/1581] allow subtree split branch which does not exist. --- bin/subtree-split | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/subtree-split b/bin/subtree-split index c8ccdb259..2c3dd8261 100755 --- a/bin/subtree-split +++ b/bin/subtree-split @@ -11,7 +11,7 @@ function split() SHA1=`./bin/splitsh-lite --prefix=$1` - git push $2 "$SHA1:$CURRENT_BRANCH" + git push $2 "$SHA1:refs/heads/$CURRENT_BRANCH" } function split_new_repo() From ac81bcae4947ed043e123f220db06a2311cc552b Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Wed, 20 Sep 2017 16:47:54 +0300 Subject: [PATCH 0016/1581] [fs] fix bugs intrdoced in #181. The #181 introduce a bug that corrupt the file structure and make it impossible to read. --- pkg/fs/FsConsumer.php | 16 ++++- pkg/fs/Tests/Functional/FsConsumerTest.php | 80 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/pkg/fs/FsConsumer.php b/pkg/fs/FsConsumer.php index 1bd36c498..c42ea4dfc 100644 --- a/pkg/fs/FsConsumer.php +++ b/pkg/fs/FsConsumer.php @@ -119,6 +119,15 @@ public function receiveNoWait() $count = $this->preFetchCount; while ($count) { $frame = $this->readFrame($file, 1); + + //guards + if ($frame && false == ('|' == $frame[0] || ' ' == $frame[0])) { + throw new \LogicException(sprintf('The frame could start from either " " or "|". The malformed frame starts with "%s".', $frame[0])); + } + if (0 !== $reminder = strlen($frame) % 64) { + throw new \LogicException(sprintf('The frame size is "%d" and it must divide exactly to 64 but it leaves a reminder "%d".', strlen($frame), $reminder)); + } + ftruncate($file, fstat($file)['size'] - strlen($frame)); rewind($file); @@ -212,7 +221,12 @@ private function readFrame($file, $frameNumber) $previousFrame = $this->readFrame($file, $frameNumber + 1); if ('|' === substr($previousFrame, -1) && '{' === $frame[0]) { - return '|'.$frame; + $matched = []; + if (false === preg_match('/\ *?\|$/', $previousFrame, $matched)) { + throw new \LogicException('Something went completely wrong.'); + } + + return $matched[0].$frame; } return $previousFrame.$frame; diff --git a/pkg/fs/Tests/Functional/FsConsumerTest.php b/pkg/fs/Tests/Functional/FsConsumerTest.php index 33e676ae4..f3a641159 100644 --- a/pkg/fs/Tests/Functional/FsConsumerTest.php +++ b/pkg/fs/Tests/Functional/FsConsumerTest.php @@ -4,6 +4,7 @@ use Enqueue\Fs\FsConnectionFactory; use Enqueue\Fs\FsContext; +use Enqueue\Fs\FsDestination; use Enqueue\Fs\FsMessage; use PHPUnit\Framework\TestCase; @@ -69,6 +70,7 @@ public function testShouldConsumeMessagesFromFileOneByOne() /** * @group bug + * @group bug170 */ public function testShouldNotFailOnSpecificMessageSize() { @@ -91,4 +93,82 @@ public function testShouldNotFailOnSpecificMessageSize() $message = $consumer->receiveNoWait(); $this->assertNull($message); } + + /** + * @group bug + * @group bug170 + */ + public function testShouldNotCorruptFrameSize() + { + $context = $this->fsContext; + $queue = $context->createQueue('fs_test_queue'); + $context->purge($queue); + + $consumer = $context->createConsumer($queue); + $producer = $context->createProducer(); + + $producer->send($queue, $context->createMessage(str_repeat('a', 23))); + $producer->send($queue, $context->createMessage(str_repeat('b', 24))); + + $message = $consumer->receiveNoWait(); + $this->assertNotNull($message); + $context->workWithFile($queue, 'a+', function (FsDestination $destination, $file) { + $this->assertSame(0, fstat($file)['size'] % 64); + }); + + $message = $consumer->receiveNoWait(); + $this->assertNotNull($message); + $context->workWithFile($queue, 'a+', function (FsDestination $destination, $file) { + $this->assertSame(0, fstat($file)['size'] % 64); + }); + + $message = $consumer->receiveNoWait(); + $this->assertNull($message); + } + + /** + * @group bug + * @group bug202 + */ + public function testShouldThrowExceptionForTheCorruptedQueueFile() + { + $context = $this->fsContext; + $queue = $context->createQueue('fs_test_queue'); + $context->purge($queue); + + $context->workWithFile($queue, 'a+', function (FsDestination $destination, $file) { + fwrite($file, '|{"body":"{\"path\":\"\\\/p\\\/r\\\/pr_swoppad_6_4910_red_1.jpg\",\"filters\":null,\"force\":false}","properties":{"enqueue.topic_name":"liip_imagine_resolve_cache"},"headers":{"content_type":"application\/json","message_id":"46fdc345-5d0c-426e-95ac-227c7e657839","timestamp":1505379216,"reply_to":null,"correlation_id":""}} |{"body":"{\"path\":\"\\\/p\\\/r\\\/pr_swoppad_6_4910_black_1.jpg\",\"filters\":null,\"force\":false}","properties":{"enqueue.topic_name":"liip_imagine_resolve_cache"},"headers":{"content_type":"application\/json","message_id":"c4d60e39-3a8c-42df-b536-c8b7c13e006d","timestamp":1505379216,"reply_to":null,"correlation_id":""}} |{"body":"{\"path\":\"\\\/p\\\/r\\\/pr_swoppad_6_4910_green_1.jpg\",\"filters\":null,\"force\":false}","properties":{"enqueue.topic_name":"liip_imagine_resolve_cache"},"headers":{"content_type":"application\/json","message_id":"3a6aa176-c879-4435-9626-c48e0643defa","timestamp":1505379216,"reply_to":null,"correlation_id":""}}'); + }); + + $consumer = $context->createConsumer($queue); + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('The frame could start from either " " or "|". The malformed frame starts with """.'); + $consumer->receiveNoWait(); + } + + /** + * @group bug + * @group bug202 + */ + public function testShouldThrowExceptionWhenFrameSizeNotDivideExactly() + { + $context = $this->fsContext; + $queue = $context->createQueue('fs_test_queue'); + $context->purge($queue); + + $context->workWithFile($queue, 'a+', function (FsDestination $destination, $file) { + $msg = '|{"body":""}'; + //guard + $this->assertNotSame(0, strlen($msg) % 64); + + fwrite($file, $msg); + }); + + $consumer = $context->createConsumer($queue); + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('The frame size is "12" and it must divide exactly to 64 but it leaves a reminder "12".'); + $consumer->receiveNoWait(); + } } From e5707243a22f7e95c9ddbd1194a89fde076c93d7 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Fri, 22 Sep 2017 15:53:17 +0300 Subject: [PATCH 0017/1581] [doc] add file paths in code examples. --- docs/elastica-bundle/populate-command-optimization.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/elastica-bundle/populate-command-optimization.md b/docs/elastica-bundle/populate-command-optimization.md index 8c5cab739..975abb3f0 100644 --- a/docs/elastica-bundle/populate-command-optimization.md +++ b/docs/elastica-bundle/populate-command-optimization.md @@ -16,6 +16,8 @@ Add bundles to `AppKernel` ```php Date: Fri, 22 Sep 2017 16:50:55 +0300 Subject: [PATCH 0018/1581] [redis] add dsn support for redis transport. --- docs/transport/redis.md | 21 ++- .../DsnToConnectionFactoryFunctionTest.php | 3 + pkg/enqueue/functions.php | 9 +- pkg/redis/RedisConnectionFactory.php | 76 ++++++++-- .../RedisConnectionFactoryConfigTest.php | 135 ++++++++++++++++++ 5 files changed, 226 insertions(+), 18 deletions(-) create mode 100644 pkg/redis/Tests/RedisConnectionFactoryConfigTest.php diff --git a/docs/transport/redis.md b/docs/transport/redis.md index 42e347f6f..3ded64a36 100644 --- a/docs/transport/redis.md +++ b/docs/transport/redis.md @@ -38,13 +38,26 @@ $ composer require enqueue/redis predis/predis:^1 'localhost', - 'port' => 6379, +// connects to localhost +$factory = new RedisConnectionFactory(); + +// same as above +$factory = new RedisConnectionFactory('redis:'); + +// same as above +$factory = new RedisConnectionFactory([]); + +// connect to Redis at example.com port 1000 using phpredis extension +$factory = new RedisConnectionFactory([ + 'host' => 'example.com', + 'port' => 1000, 'vendor' => 'phpredis', ]); -$psrContext = $connectionFactory->createContext(); +// same as above but given as DSN string +$factory = new RedisConnectionFactory('redis://example.com:1000?vendor=phpredis'); + +$psrContext = $factory->createContext(); ``` * With predis library: diff --git a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php index fd455b15d..da8ba0156 100644 --- a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php @@ -9,6 +9,7 @@ use Enqueue\Null\NullConnectionFactory; use Enqueue\Pheanstalk\PheanstalkConnectionFactory; use Enqueue\RdKafka\RdKafkaConnectionFactory; +use Enqueue\Redis\RedisConnectionFactory; use PHPUnit\Framework\TestCase; class DsnToConnectionFactoryFunctionTest extends TestCase @@ -71,5 +72,7 @@ public static function provideDSNs() // yield ['gearman://', GearmanConnectionFactory::class]; yield ['rdkafka://', RdKafkaConnectionFactory::class]; + + yield ['redis:', RedisConnectionFactory::class]; } } diff --git a/pkg/enqueue/functions.php b/pkg/enqueue/functions.php index 215899c50..754b29f6d 100644 --- a/pkg/enqueue/functions.php +++ b/pkg/enqueue/functions.php @@ -12,6 +12,7 @@ use Enqueue\Null\NullConnectionFactory; use Enqueue\Pheanstalk\PheanstalkConnectionFactory; use Enqueue\RdKafka\RdKafkaConnectionFactory; +use Enqueue\Redis\RedisConnectionFactory; use Interop\Queue\PsrConnectionFactory; use Interop\Queue\PsrContext; @@ -80,8 +81,12 @@ function dsn_to_connection_factory($dsn) $map['rdkafka'] = RdKafkaConnectionFactory::class; } - list($scheme) = explode('://', $dsn); - if (false == $scheme || false === strpos($dsn, '://')) { + if (class_exists(RedisConnectionFactory::class)) { + $map['redis'] = RedisConnectionFactory::class; + } + + list($scheme) = explode(':', $dsn, 2); + if (false == $scheme || false === strpos($dsn, ':')) { throw new \LogicException(sprintf('The scheme could not be parsed from DSN "%s"', $dsn)); } diff --git a/pkg/redis/RedisConnectionFactory.php b/pkg/redis/RedisConnectionFactory.php index 6c520fc4a..122bf0bef 100644 --- a/pkg/redis/RedisConnectionFactory.php +++ b/pkg/redis/RedisConnectionFactory.php @@ -29,20 +29,25 @@ class RedisConnectionFactory implements PsrConnectionFactory * 'lazy' => the connection will be performed as later as possible, if the option set to true * ]. * - * @param $config + * or + * + * redis: + * redis:?vendor=predis + * + * @param array|string|null $config */ - public function __construct(array $config) + public function __construct($config = 'redis:') { - $this->config = array_replace([ - 'host' => null, - 'port' => null, - 'timeout' => null, - 'reserved' => null, - 'retry_interval' => null, - 'vendor' => 'phpredis', - 'persisted' => false, - 'lazy' => true, - ], $config); + if (empty($config) || 'redis:' === $config) { + $config = []; + } elseif (is_string($config)) { + $config = $this->parseDsn($config); + } elseif (is_array($config)) { + } else { + throw new \LogicException('The config must be either an array of options, a DSN string or null'); + } + + $this->config = array_replace($this->defaultConfig(), $config); $supportedVendors = ['predis', 'phpredis']; if (false == in_array($this->config['vendor'], $supportedVendors, true)) { @@ -89,4 +94,51 @@ private function createRedis() return $this->redis; } + + /** + * @param string $dsn + * + * @return array + */ + private function parseDsn($dsn) + { + if (false === strpos($dsn, 'redis:')) { + throw new \LogicException(sprintf('The given DSN "%s" is not supported. Must start with "redis:".', $dsn)); + } + + if (false === $config = parse_url($dsn)) { + throw new \LogicException(sprintf('Failed to parse DSN "%s"', $dsn)); + } + + if ($query = parse_url($dsn, PHP_URL_QUERY)) { + $queryConfig = []; + parse_str($query, $queryConfig); + + $config = array_replace($queryConfig, $config); + } + + unset($config['query'], $config['scheme']); + + $config['lazy'] = empty($config['lazy']) ? false : true; + $config['persisted'] = empty($config['persisted']) ? false : true; + + return $config; + } + + /** + * @return array + */ + private function defaultConfig() + { + return [ + 'host' => 'localhost', + 'port' => 6379, + 'timeout' => null, + 'reserved' => null, + 'retry_interval' => null, + 'vendor' => 'phpredis', + 'persisted' => false, + 'lazy' => true, + ]; + } } diff --git a/pkg/redis/Tests/RedisConnectionFactoryConfigTest.php b/pkg/redis/Tests/RedisConnectionFactoryConfigTest.php new file mode 100644 index 000000000..f3375e0de --- /dev/null +++ b/pkg/redis/Tests/RedisConnectionFactoryConfigTest.php @@ -0,0 +1,135 @@ +expectException(\LogicException::class); + $this->expectExceptionMessage('The config must be either an array of options, a DSN string or null'); + + new RedisConnectionFactory(new \stdClass()); + } + + public function testThrowIfSchemeIsNotAmqp() + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('The given DSN "http://example.com" is not supported. Must start with "redis:".'); + + new RedisConnectionFactory('http://example.com'); + } + + public function testThrowIfDsnCouldNotBeParsed() + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Failed to parse DSN "redis://:@/"'); + + new RedisConnectionFactory('redis://:@/'); + } + + public function testThrowIfVendorIsInvalid() + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Unsupported redis vendor given. It must be either "predis", "phpredis". Got "invalidVendor"'); + + new RedisConnectionFactory(['vendor' => 'invalidVendor']); + } + + /** + * @dataProvider provideConfigs + * + * @param mixed $config + * @param mixed $expectedConfig + */ + public function testShouldParseConfigurationAsExpected($config, $expectedConfig) + { + $factory = new RedisConnectionFactory($config); + + $this->assertAttributeEquals($expectedConfig, 'config', $factory); + } + + public static function provideConfigs() + { + yield [ + null, + [ + 'host' => 'localhost', + 'port' => 6379, + 'timeout' => null, + 'reserved' => null, + 'retry_interval' => null, + 'vendor' => 'phpredis', + 'persisted' => false, + 'lazy' => true, + ], + ]; + + yield [ + 'redis:', + [ + 'host' => 'localhost', + 'port' => 6379, + 'timeout' => null, + 'reserved' => null, + 'retry_interval' => null, + 'vendor' => 'phpredis', + 'persisted' => false, + 'lazy' => true, + ], + ]; + + yield [ + [], + [ + 'host' => 'localhost', + 'port' => 6379, + 'timeout' => null, + 'reserved' => null, + 'retry_interval' => null, + 'vendor' => 'phpredis', + 'persisted' => false, + 'lazy' => true, + ], + ]; + + yield [ + 'redis://localhost:1234?foo=bar&lazy=0&persisted=true', + [ + 'host' => 'localhost', + 'port' => 1234, + 'timeout' => null, + 'reserved' => null, + 'retry_interval' => null, + 'vendor' => 'phpredis', + 'persisted' => true, + 'lazy' => false, + 'foo' => 'bar', + ], + ]; + + yield [ + ['host' => 'localhost', 'port' => 1234, 'foo' => 'bar'], + [ + 'host' => 'localhost', + 'port' => 1234, + 'timeout' => null, + 'reserved' => null, + 'retry_interval' => null, + 'vendor' => 'phpredis', + 'persisted' => false, + 'lazy' => true, + 'foo' => 'bar', + ], + ]; + } +} From 2f68d6d45cf1d165399a3b0f3cf4dde1a6e481d2 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 11:49:13 +0300 Subject: [PATCH 0019/1581] [redis] remote duplicated tests. --- .../Tests/RedisConnectionFactoryTest.php | 35 ++----------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/pkg/redis/Tests/RedisConnectionFactoryTest.php b/pkg/redis/Tests/RedisConnectionFactoryTest.php index 4f4973861..b5d7347ab 100644 --- a/pkg/redis/Tests/RedisConnectionFactoryTest.php +++ b/pkg/redis/Tests/RedisConnectionFactoryTest.php @@ -6,8 +6,9 @@ use Enqueue\Redis\RedisContext; use Enqueue\Test\ClassExtensionTrait; use Interop\Queue\PsrConnectionFactory; +use PHPUnit\Framework\TestCase; -class RedisConnectionFactoryTest extends \PHPUnit\Framework\TestCase +class RedisConnectionFactoryTest extends TestCase { use ClassExtensionTrait; @@ -16,38 +17,6 @@ public function testShouldImplementConnectionFactoryInterface() $this->assertClassImplements(PsrConnectionFactory::class, RedisConnectionFactory::class); } - public function testCouldBeConstructedWithEmptyConfiguration() - { - $factory = new RedisConnectionFactory([]); - - $this->assertAttributeEquals([ - 'host' => null, - 'port' => null, - 'timeout' => null, - 'reserved' => null, - 'retry_interval' => null, - 'persisted' => false, - 'lazy' => true, - 'vendor' => 'phpredis', - ], 'config', $factory); - } - - public function testCouldBeConstructedWithCustomConfiguration() - { - $factory = new RedisConnectionFactory(['host' => 'theCustomHost']); - - $this->assertAttributeEquals([ - 'host' => 'theCustomHost', - 'port' => null, - 'timeout' => null, - 'reserved' => null, - 'retry_interval' => null, - 'persisted' => false, - 'lazy' => true, - 'vendor' => 'phpredis', - ], 'config', $factory); - } - public function testShouldCreateLazyContext() { $factory = new RedisConnectionFactory(['lazy' => true]); From afaffc0bbc82f37a3486376727a7e617f4766326 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 12:07:17 +0300 Subject: [PATCH 0020/1581] [stomp] Add stom DSN. --- .../DsnToConnectionFactoryFunctionTest.php | 3 + .../Functions/DsnToContextFunctionTest.php | 6 + pkg/enqueue/functions.php | 5 + pkg/stomp/StompConnectionFactory.php | 90 ++++++++++-- .../StompConnectionFactoryConfigTest.php | 132 ++++++++++++++++++ .../Tests/StompConnectionFactoryTest.php | 34 ----- 6 files changed, 223 insertions(+), 47 deletions(-) create mode 100644 pkg/stomp/Tests/StompConnectionFactoryConfigTest.php diff --git a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php index da8ba0156..4ebed778d 100644 --- a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php @@ -10,6 +10,7 @@ use Enqueue\Pheanstalk\PheanstalkConnectionFactory; use Enqueue\RdKafka\RdKafkaConnectionFactory; use Enqueue\Redis\RedisConnectionFactory; +use Enqueue\Stomp\StompConnectionFactory; use PHPUnit\Framework\TestCase; class DsnToConnectionFactoryFunctionTest extends TestCase @@ -74,5 +75,7 @@ public static function provideDSNs() yield ['rdkafka://', RdKafkaConnectionFactory::class]; yield ['redis:', RedisConnectionFactory::class]; + + yield ['stomp:', StompConnectionFactory::class]; } } diff --git a/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php index 54daf8c5f..350e401aa 100644 --- a/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php @@ -5,6 +5,8 @@ use Enqueue\AmqpExt\AmqpContext; use Enqueue\Fs\FsContext; use Enqueue\Null\NullContext; +use Enqueue\Redis\RedisContext; +use Enqueue\Stomp\StompContext; use PHPUnit\Framework\TestCase; class DsnToContextFunctionTest extends TestCase @@ -57,5 +59,9 @@ public static function provideDSNs() yield ['file://'.sys_get_temp_dir(), FsContext::class]; yield ['null://', NullContext::class]; + + yield ['redis:', RedisContext::class]; + + yield ['stomp:', StompContext::class]; } } diff --git a/pkg/enqueue/functions.php b/pkg/enqueue/functions.php index 754b29f6d..7d9ef1eb7 100644 --- a/pkg/enqueue/functions.php +++ b/pkg/enqueue/functions.php @@ -13,6 +13,7 @@ use Enqueue\Pheanstalk\PheanstalkConnectionFactory; use Enqueue\RdKafka\RdKafkaConnectionFactory; use Enqueue\Redis\RedisConnectionFactory; +use Enqueue\Stomp\StompConnectionFactory; use Interop\Queue\PsrConnectionFactory; use Interop\Queue\PsrContext; @@ -85,6 +86,10 @@ function dsn_to_connection_factory($dsn) $map['redis'] = RedisConnectionFactory::class; } + if (class_exists(StompConnectionFactory::class)) { + $map['stomp'] = StompConnectionFactory::class; + } + list($scheme) = explode(':', $dsn, 2); if (false == $scheme || false === strpos($dsn, ':')) { throw new \LogicException(sprintf('The scheme could not be parsed from DSN "%s"', $dsn)); diff --git a/pkg/stomp/StompConnectionFactory.php b/pkg/stomp/StompConnectionFactory.php index 29fc35c49..ce2aae733 100644 --- a/pkg/stomp/StompConnectionFactory.php +++ b/pkg/stomp/StompConnectionFactory.php @@ -18,21 +18,37 @@ class StompConnectionFactory implements PsrConnectionFactory private $stomp; /** - * @param array $config + * $config = [ + * 'host' => null, + * 'port' => null, + * 'login' => null, + * 'password' => null, + * 'vhost' => null, + * 'buffer_size' => 1000, + * 'connection_timeout' => 1, + * 'sync' => false, + * 'lazy' => true, + * ]. + * + * or + * + * stomp: + * stomp:?buffer_size=100 + * + * @param array|string|null $config */ - public function __construct(array $config) + public function __construct($config = 'stomp:') { - $this->config = array_replace([ - 'host' => null, - 'port' => null, - 'login' => null, - 'password' => null, - 'vhost' => null, - 'buffer_size' => 1000, - 'connection_timeout' => 1, - 'sync' => false, - 'lazy' => true, - ], $config); + if (empty($config) || 'stomp:' === $config) { + $config = []; + } elseif (is_string($config)) { + $config = $this->parseDsn($config); + } elseif (is_array($config)) { + } else { + throw new \LogicException('The config must be either an array of options, a DSN string or null'); + } + + $this->config = array_replace($this->defaultConfig(), $config); } /** @@ -72,4 +88,52 @@ private function establishConnection() return $this->stomp; } + + /** + * @param string $dsn + * + * @return array + */ + private function parseDsn($dsn) + { + if (false === strpos($dsn, 'stomp:')) { + throw new \LogicException(sprintf('The given DSN "%s" is not supported. Must start with "stomp:".', $dsn)); + } + + if (false === $config = parse_url($dsn)) { + throw new \LogicException(sprintf('Failed to parse DSN "%s"', $dsn)); + } + + if ($query = parse_url($dsn, PHP_URL_QUERY)) { + $queryConfig = []; + parse_str($query, $queryConfig); + + $config = array_replace($queryConfig, $config); + } + + unset($config['query'], $config['scheme']); + + $config['sync'] = empty($config['sync']) ? false : true; + $config['lazy'] = empty($config['lazy']) ? false : true; + + return $config; + } + + /** + * @return array + */ + private function defaultConfig() + { + return [ + 'host' => 'localhost', + 'port' => 61613, + 'login' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'buffer_size' => 1000, + 'connection_timeout' => 1, + 'sync' => false, + 'lazy' => true, + ]; + } } diff --git a/pkg/stomp/Tests/StompConnectionFactoryConfigTest.php b/pkg/stomp/Tests/StompConnectionFactoryConfigTest.php new file mode 100644 index 000000000..61f8d0515 --- /dev/null +++ b/pkg/stomp/Tests/StompConnectionFactoryConfigTest.php @@ -0,0 +1,132 @@ +expectException(\LogicException::class); + $this->expectExceptionMessage('The config must be either an array of options, a DSN string or null'); + + new StompConnectionFactory(new \stdClass()); + } + + public function testThrowIfSchemeIsNotAmqp() + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('The given DSN "http://example.com" is not supported. Must start with "stomp:".'); + + new StompConnectionFactory('http://example.com'); + } + + public function testThrowIfDsnCouldNotBeParsed() + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Failed to parse DSN "stomp://:@/"'); + + new StompConnectionFactory('stomp://:@/'); + } + + /** + * @dataProvider provideConfigs + * + * @param mixed $config + * @param mixed $expectedConfig + */ + public function testShouldParseConfigurationAsExpected($config, $expectedConfig) + { + $factory = new StompConnectionFactory($config); + + $this->assertAttributeEquals($expectedConfig, 'config', $factory); + } + + public static function provideConfigs() + { + yield [ + null, + [ + 'host' => 'localhost', + 'port' => 61613, + 'login' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'buffer_size' => 1000, + 'connection_timeout' => 1, + 'sync' => false, + 'lazy' => true, + ], + ]; + + yield [ + 'stomp:', + [ + 'host' => 'localhost', + 'port' => 61613, + 'login' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'buffer_size' => 1000, + 'connection_timeout' => 1, + 'sync' => false, + 'lazy' => true, + ], + ]; + + yield [ + [], + [ + 'host' => 'localhost', + 'port' => 61613, + 'login' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'buffer_size' => 1000, + 'connection_timeout' => 1, + 'sync' => false, + 'lazy' => true, + ], + ]; + + yield [ + 'stomp://localhost:1234?foo=bar&lazy=0&sync=true', + [ + 'host' => 'localhost', + 'port' => 1234, + 'login' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'buffer_size' => 1000, + 'connection_timeout' => 1, + 'sync' => true, + 'lazy' => false, + 'foo' => 'bar', + ], + ]; + + yield [ + ['host' => 'localhost', 'port' => 1234, 'foo' => 'bar'], + [ + 'host' => 'localhost', + 'port' => 1234, + 'login' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'buffer_size' => 1000, + 'connection_timeout' => 1, + 'sync' => false, + 'lazy' => true, + 'foo' => 'bar', + ], + ]; + } +} diff --git a/pkg/stomp/Tests/StompConnectionFactoryTest.php b/pkg/stomp/Tests/StompConnectionFactoryTest.php index 9076d946d..8e57e5f57 100644 --- a/pkg/stomp/Tests/StompConnectionFactoryTest.php +++ b/pkg/stomp/Tests/StompConnectionFactoryTest.php @@ -16,40 +16,6 @@ public function testShouldImplementConnectionFactoryInterface() $this->assertClassImplements(PsrConnectionFactory::class, StompConnectionFactory::class); } - public function testCouldBeConstructedWithEmptyConfiguration() - { - $factory = new StompConnectionFactory([]); - - $this->assertAttributeEquals([ - 'host' => null, - 'port' => null, - 'login' => null, - 'password' => null, - 'vhost' => null, - 'buffer_size' => 1000, - 'connection_timeout' => 1, - 'sync' => false, - 'lazy' => true, - ], 'config', $factory); - } - - public function testCouldBeConstructedWithCustomConfiguration() - { - $factory = new StompConnectionFactory(['host' => 'theCustomHost']); - - $this->assertAttributeEquals([ - 'host' => 'theCustomHost', - 'port' => null, - 'login' => null, - 'password' => null, - 'vhost' => null, - 'buffer_size' => 1000, - 'connection_timeout' => 1, - 'sync' => false, - 'lazy' => true, - ], 'config', $factory); - } - public function testShouldCreateLazyContext() { $factory = new StompConnectionFactory(['lazy' => true]); From c81b4ca66b7728be696b8eb5c5f254a0660047bb Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 12:20:11 +0300 Subject: [PATCH 0021/1581] [sqs] Add Amazon SQS DSN. --- .../DsnToConnectionFactoryFunctionTest.php | 3 + .../Functions/DsnToContextFunctionTest.php | 3 + pkg/enqueue/functions.php | 5 + pkg/sqs/SqsConnectionFactory.php | 73 +++++++++-- .../Tests/SqsConnectionFactoryConfigTest.php | 120 ++++++++++++++++++ 5 files changed, 193 insertions(+), 11 deletions(-) create mode 100644 pkg/sqs/Tests/SqsConnectionFactoryConfigTest.php diff --git a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php index 4ebed778d..fff8abf05 100644 --- a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php @@ -10,6 +10,7 @@ use Enqueue\Pheanstalk\PheanstalkConnectionFactory; use Enqueue\RdKafka\RdKafkaConnectionFactory; use Enqueue\Redis\RedisConnectionFactory; +use Enqueue\Sqs\SqsConnectionFactory; use Enqueue\Stomp\StompConnectionFactory; use PHPUnit\Framework\TestCase; @@ -77,5 +78,7 @@ public static function provideDSNs() yield ['redis:', RedisConnectionFactory::class]; yield ['stomp:', StompConnectionFactory::class]; + + yield ['sqs:', SqsConnectionFactory::class]; } } diff --git a/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php index 350e401aa..fd1260a4f 100644 --- a/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php @@ -6,6 +6,7 @@ use Enqueue\Fs\FsContext; use Enqueue\Null\NullContext; use Enqueue\Redis\RedisContext; +use Enqueue\Sqs\SqsContext; use Enqueue\Stomp\StompContext; use PHPUnit\Framework\TestCase; @@ -63,5 +64,7 @@ public static function provideDSNs() yield ['redis:', RedisContext::class]; yield ['stomp:', StompContext::class]; + + yield ['sqs:', SqsContext::class]; } } diff --git a/pkg/enqueue/functions.php b/pkg/enqueue/functions.php index 7d9ef1eb7..c89a3b89e 100644 --- a/pkg/enqueue/functions.php +++ b/pkg/enqueue/functions.php @@ -13,6 +13,7 @@ use Enqueue\Pheanstalk\PheanstalkConnectionFactory; use Enqueue\RdKafka\RdKafkaConnectionFactory; use Enqueue\Redis\RedisConnectionFactory; +use Enqueue\Sqs\SqsConnectionFactory; use Enqueue\Stomp\StompConnectionFactory; use Interop\Queue\PsrConnectionFactory; use Interop\Queue\PsrContext; @@ -90,6 +91,10 @@ function dsn_to_connection_factory($dsn) $map['stomp'] = StompConnectionFactory::class; } + if (class_exists(SqsConnectionFactory::class)) { + $map['sqs'] = SqsConnectionFactory::class; + } + list($scheme) = explode(':', $dsn, 2); if (false == $scheme || false === strpos($dsn, ':')) { throw new \LogicException(sprintf('The scheme could not be parsed from DSN "%s"', $dsn)); diff --git a/pkg/sqs/SqsConnectionFactory.php b/pkg/sqs/SqsConnectionFactory.php index 966f746fa..8a67db7e8 100644 --- a/pkg/sqs/SqsConnectionFactory.php +++ b/pkg/sqs/SqsConnectionFactory.php @@ -28,19 +28,25 @@ class SqsConnectionFactory implements PsrConnectionFactory * 'lazy' => true, - Enable lazy connection (boolean) * ]. * - * @param $config + * or + * + * sqs: + * sqs::?key=aKey&secret=aSecret&token=aToken + * + * @param array|string|null $config */ - public function __construct(array $config = []) + public function __construct($config = 'sqs:') { - $this->config = array_replace([ - 'key' => null, - 'secret' => null, - 'token' => null, - 'region' => null, - 'retries' => 3, - 'version' => '2012-11-05', - 'lazy' => true, - ], $config); + if (empty($config) || 'sqs:' === $config) { + $config = []; + } elseif (is_string($config)) { + $config = $this->parseDsn($config); + } elseif (is_array($config)) { + } else { + throw new \LogicException('The config must be either an array of options, a DSN string or null'); + } + + $this->config = array_replace($this->defaultConfig(), $config); } /** @@ -96,4 +102,49 @@ private function establishConnection() return $this->client; } + + /** + * @param string $dsn + * + * @return array + */ + private function parseDsn($dsn) + { + if (false === strpos($dsn, 'sqs:')) { + throw new \LogicException(sprintf('The given DSN "%s" is not supported. Must start with "sqs:".', $dsn)); + } + + if (false === $config = parse_url($dsn)) { + throw new \LogicException(sprintf('Failed to parse DSN "%s"', $dsn)); + } + + if ($query = parse_url($dsn, PHP_URL_QUERY)) { + $queryConfig = []; + parse_str($query, $queryConfig); + + $config = array_replace($queryConfig, $config); + } + + unset($config['query'], $config['scheme']); + + $config['lazy'] = empty($config['lazy']) ? false : true; + + return $config; + } + + /** + * @return array + */ + private function defaultConfig() + { + return [ + 'key' => null, + 'secret' => null, + 'token' => null, + 'region' => null, + 'retries' => 3, + 'version' => '2012-11-05', + 'lazy' => true, + ]; + } } diff --git a/pkg/sqs/Tests/SqsConnectionFactoryConfigTest.php b/pkg/sqs/Tests/SqsConnectionFactoryConfigTest.php new file mode 100644 index 000000000..5f74bcf2f --- /dev/null +++ b/pkg/sqs/Tests/SqsConnectionFactoryConfigTest.php @@ -0,0 +1,120 @@ +expectException(\LogicException::class); + $this->expectExceptionMessage('The config must be either an array of options, a DSN string or null'); + + new SqsConnectionFactory(new \stdClass()); + } + + public function testThrowIfSchemeIsNotAmqp() + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('The given DSN "http://example.com" is not supported. Must start with "sqs:".'); + + new SqsConnectionFactory('http://example.com'); + } + + public function testThrowIfDsnCouldNotBeParsed() + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Failed to parse DSN "sqs://:@/"'); + + new SqsConnectionFactory('sqs://:@/'); + } + + /** + * @dataProvider provideConfigs + * + * @param mixed $config + * @param mixed $expectedConfig + */ + public function testShouldParseConfigurationAsExpected($config, $expectedConfig) + { + $factory = new SqsConnectionFactory($config); + + $this->assertAttributeEquals($expectedConfig, 'config', $factory); + } + + public static function provideConfigs() + { + yield [ + null, + [ + 'key' => null, + 'secret' => null, + 'token' => null, + 'region' => null, + 'retries' => 3, + 'version' => '2012-11-05', + 'lazy' => true, + ], + ]; + + yield [ + 'sqs:', + [ + 'key' => null, + 'secret' => null, + 'token' => null, + 'region' => null, + 'retries' => 3, + 'version' => '2012-11-05', + 'lazy' => true, + ], + ]; + + yield [ + [], + [ + 'key' => null, + 'secret' => null, + 'token' => null, + 'region' => null, + 'retries' => 3, + 'version' => '2012-11-05', + 'lazy' => true, + ], + ]; + + yield [ + 'sqs:?key=theKey&secret=theSecret&token=theToken&lazy=0', + [ + 'key' => 'theKey', + 'secret' => 'theSecret', + 'token' => 'theToken', + 'region' => null, + 'retries' => 3, + 'version' => '2012-11-05', + 'lazy' => false, + ], + ]; + + yield [ + ['key' => 'theKey', 'secret' => 'theSecret', 'token' => 'theToken', 'lazy' => false], + [ + 'key' => 'theKey', + 'secret' => 'theSecret', + 'token' => 'theToken', + 'region' => null, + 'retries' => 3, + 'version' => '2012-11-05', + 'lazy' => false, + ], + ]; + } +} From 62c0b76e41e4fd45c079bc60ccc846c2c3320802 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 12:24:04 +0300 Subject: [PATCH 0022/1581] [docs] add docs for sqs and stomp DSNs --- docs/transport/sqs.md | 9 ++++++--- docs/transport/stomp.md | 25 ++++++++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/docs/transport/sqs.md b/docs/transport/sqs.md index b799b1f21..2c35c8bc3 100644 --- a/docs/transport/sqs.md +++ b/docs/transport/sqs.md @@ -22,14 +22,17 @@ $ composer require enqueue/sqs ```php 'aKey', 'secret' => 'aSecret', 'region' => 'aRegion', ]); -$psrContext = $connectionFactory->createContext(); +// same as above but given as DSN string +$factory = new SqsConnectionFactory('sqs:?key=aKey&secret=aSecret®ion=aRegion'); + +$psrContext = $factory->createContext(); ``` ## Declare queue. diff --git a/docs/transport/stomp.md b/docs/transport/stomp.md index cb62191fd..1b40f96d1 100644 --- a/docs/transport/stomp.md +++ b/docs/transport/stomp.md @@ -18,15 +18,26 @@ $ composer require enqueue/stomp '127.0.0.1', - 'port' => 61613, - 'login' => 'guest', - 'password' => 'guest', - 'vhost' => '/', +// connects to localhost +$factory = new StompConnectionFactory(); + +// same as above +$factory = new StompConnectionFactory('stomp:'); + +// same as above +$factory = new StompConnectionFactory([]); + +// connect to stomp broker at example.com port 1000 using +$factory = new StompConnectionFactory([ + 'host' => 'example.com', + 'port' => 1000, + 'login' => 'theLogin', ]); -$psrContext = $connectionFactory->createContext(); +// same as above but given as DSN string +$factory = new StompConnectionFactory('stomp://example.com:1000?login=theLogin'); + +$psrContext = $factory->createContext(); ``` ## Send message to topic From 64a9cc13054b2dbb40d3a41d6ea82c79d098d163 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 12:58:39 +0300 Subject: [PATCH 0023/1581] [symfony] Add missing supported DSNs to default transport factory. --- pkg/amqp-bunny/AmqpConnectionFactory.php | 7 +-- .../Tests/AmqpConnectionFactoryConfigTest.php | 17 ++++++ pkg/amqp-ext/AmqpConnectionFactory.php | 7 +-- .../Tests/AmqpConnectionFactoryConfigTest.php | 19 +++++++ pkg/amqp-lib/AmqpConnectionFactory.php | 7 +-- .../Tests/AmqpConnectionFactoryConfigTest.php | 27 ++++++++++ .../Symfony/DefaultTransportFactory.php | 52 ++++++++++++++++--- .../DsnToConnectionFactoryFunctionTest.php | 3 ++ .../Functions/DsnToContextFunctionTest.php | 3 ++ .../Symfony/DefaultTransportFactoryTest.php | 14 ++++- pkg/enqueue/functions.php | 7 ++- 11 files changed, 144 insertions(+), 19 deletions(-) diff --git a/pkg/amqp-bunny/AmqpConnectionFactory.php b/pkg/amqp-bunny/AmqpConnectionFactory.php index 422650d80..48f5fe742 100644 --- a/pkg/amqp-bunny/AmqpConnectionFactory.php +++ b/pkg/amqp-bunny/AmqpConnectionFactory.php @@ -45,11 +45,12 @@ class AmqpConnectionFactory implements InteropAmqpConnectionFactory, DelayStrate */ public function __construct($config = 'amqp://') { - if (is_string($config) && 0 === strpos($config, 'amqp+bunny://')) { - $config = str_replace('amqp+bunny://', 'amqp://', $config); + if (is_string($config) && 0 === strpos($config, 'amqp+bunny:')) { + $config = str_replace('amqp+bunny:', 'amqp:', $config); } - if (empty($config) || 'amqp://' === $config) { + // third argument is deprecated will be removed in 0.8 + if (empty($config) || 'amqp:' === $config || 'amqp://' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); diff --git a/pkg/amqp-bunny/Tests/AmqpConnectionFactoryConfigTest.php b/pkg/amqp-bunny/Tests/AmqpConnectionFactoryConfigTest.php index e659cef68..4f761fd57 100644 --- a/pkg/amqp-bunny/Tests/AmqpConnectionFactoryConfigTest.php +++ b/pkg/amqp-bunny/Tests/AmqpConnectionFactoryConfigTest.php @@ -79,6 +79,23 @@ public static function provideConfigs() // some examples from Appendix A: Examples (https://www.rabbitmq.com/uri-spec.html) + yield [ + 'amqp+bunny:', + [ + 'host' => 'localhost', + 'port' => 5672, + 'vhost' => '/', + 'user' => 'guest', + 'pass' => 'guest', + 'receive_method' => 'basic_get', + 'heartbeat' => 0, + 'qos_prefetch_size' => 0, + 'qos_prefetch_count' => 1, + 'qos_global' => false, + 'lazy' => true, + ], + ]; + yield [ 'amqp+bunny://user:pass@host:10000/vhost', [ diff --git a/pkg/amqp-ext/AmqpConnectionFactory.php b/pkg/amqp-ext/AmqpConnectionFactory.php index ebf4d40df..3002ab0db 100644 --- a/pkg/amqp-ext/AmqpConnectionFactory.php +++ b/pkg/amqp-ext/AmqpConnectionFactory.php @@ -47,11 +47,12 @@ class AmqpConnectionFactory implements InteropAmqpConnectionFactory, DelayStrate */ public function __construct($config = 'amqp://') { - if (is_string($config) && 0 === strpos($config, 'amqp+ext://')) { - $config = str_replace('amqp+ext://', 'amqp://', $config); + if (is_string($config) && 0 === strpos($config, 'amqp+ext:')) { + $config = str_replace('amqp+ext:', 'amqp:', $config); } - if (empty($config) || 'amqp://' === $config) { + // third argument is deprecated will be removed in 0.8 + if (empty($config) || 'amqp:' === $config || 'amqp://' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); diff --git a/pkg/amqp-ext/Tests/AmqpConnectionFactoryConfigTest.php b/pkg/amqp-ext/Tests/AmqpConnectionFactoryConfigTest.php index ba95a5f61..99950be4a 100644 --- a/pkg/amqp-ext/Tests/AmqpConnectionFactoryConfigTest.php +++ b/pkg/amqp-ext/Tests/AmqpConnectionFactoryConfigTest.php @@ -81,6 +81,25 @@ public static function provideConfigs() // some examples from Appendix A: Examples (https://www.rabbitmq.com/uri-spec.html) + yield [ + 'amqp+ext:', + [ + 'host' => 'localhost', + 'port' => 5672, + 'vhost' => '/', + 'user' => 'guest', + 'pass' => 'guest', + 'read_timeout' => null, + 'write_timeout' => null, + 'connect_timeout' => null, + 'persisted' => false, + 'lazy' => true, + 'pre_fetch_count' => null, + 'pre_fetch_size' => null, + 'receive_method' => 'basic_get', + ], + ]; + yield [ 'amqp+ext://user:pass@host:10000/vhost', [ diff --git a/pkg/amqp-lib/AmqpConnectionFactory.php b/pkg/amqp-lib/AmqpConnectionFactory.php index c00998c6f..0ecc1e52c 100644 --- a/pkg/amqp-lib/AmqpConnectionFactory.php +++ b/pkg/amqp-lib/AmqpConnectionFactory.php @@ -50,11 +50,12 @@ class AmqpConnectionFactory implements InteropAmqpConnectionFactory, DelayStrate */ public function __construct($config = 'amqp://') { - if (is_string($config) && 0 === strpos($config, 'amqp+lib://')) { - $config = str_replace('amqp+lib://', 'amqp://', $config); + if (is_string($config) && 0 === strpos($config, 'amqp+lib:')) { + $config = str_replace('amqp+lib:', 'amqp:', $config); } - if (empty($config) || 'amqp://' === $config) { + // third argument is deprecated will be removed in 0.8 + if (empty($config) || 'amqp:' === $config || 'amqp://' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); diff --git a/pkg/amqp-lib/Tests/AmqpConnectionFactoryConfigTest.php b/pkg/amqp-lib/Tests/AmqpConnectionFactoryConfigTest.php index 71597c9a7..50dcc12cc 100644 --- a/pkg/amqp-lib/Tests/AmqpConnectionFactoryConfigTest.php +++ b/pkg/amqp-lib/Tests/AmqpConnectionFactoryConfigTest.php @@ -89,6 +89,33 @@ public static function provideConfigs() // some examples from Appendix A: Examples (https://www.rabbitmq.com/uri-spec.html) + yield [ + 'amqp+lib:', + [ + 'host' => 'localhost', + 'port' => 5672, + 'vhost' => '/', + 'user' => 'guest', + 'pass' => 'guest', + 'read_timeout' => 3, + 'write_timeout' => 3, + 'lazy' => true, + 'receive_method' => 'basic_get', + 'stream' => true, + 'insist' => false, + 'login_method' => 'AMQPLAIN', + 'login_response' => null, + 'locale' => 'en_US', + 'keepalive' => false, + 'heartbeat' => 0, + 'connection_timeout' => 3.0, + 'read_write_timeout' => 3.0, + 'qos_prefetch_size' => 0, + 'qos_prefetch_count' => 1, + 'qos_global' => false, + ], + ]; + yield [ 'amqp+lib://user:pass@host:10000/vhost', [ diff --git a/pkg/enqueue/Symfony/DefaultTransportFactory.php b/pkg/enqueue/Symfony/DefaultTransportFactory.php index 146197098..b79499c9c 100644 --- a/pkg/enqueue/Symfony/DefaultTransportFactory.php +++ b/pkg/enqueue/Symfony/DefaultTransportFactory.php @@ -2,14 +2,26 @@ namespace Enqueue\Symfony; -use Enqueue\AmqpExt\AmqpConnectionFactory; +use Enqueue\AmqpBunny\AmqpConnectionFactory as AmqpBunnyConnectionFactory; +use Enqueue\AmqpBunny\Symfony\AmqpBunnyTransportFactory; +use Enqueue\AmqpExt\AmqpConnectionFactory as AmqpExtConnectionFactory; use Enqueue\AmqpExt\Symfony\AmqpTransportFactory; +use Enqueue\AmqpLib\AmqpConnectionFactory as AmqpLibConnectionFactory; +use Enqueue\AmqpLib\Symfony\AmqpLibTransportFactory; use Enqueue\Dbal\DbalConnectionFactory; use Enqueue\Dbal\Symfony\DbalTransportFactory; use Enqueue\Fs\FsConnectionFactory; use Enqueue\Fs\Symfony\FsTransportFactory; +use Enqueue\Gps\GpsConnectionFactory; +use Enqueue\Gps\Symfony\GpsTransportFactory; use Enqueue\Null\NullConnectionFactory; use Enqueue\Null\Symfony\NullTransportFactory; +use Enqueue\Redis\RedisConnectionFactory; +use Enqueue\Redis\Symfony\RedisTransportFactory; +use Enqueue\Sqs\SqsConnectionFactory; +use Enqueue\Sqs\Symfony\SqsTransportFactory; +use Enqueue\Stomp\StompConnectionFactory; +use Enqueue\Stomp\Symfony\StompTransportFactory; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use function Enqueue\dsn_to_connection_factory; @@ -167,27 +179,51 @@ private function resolveDSN(ContainerBuilder $container, $dsn) */ private function findFactory($dsn) { - $connectionFactory = dsn_to_connection_factory($dsn); + $factory = dsn_to_connection_factory($dsn); - if ($connectionFactory instanceof AmqpConnectionFactory) { - return new AmqpTransportFactory('default_amqp'); + if ($factory instanceof AmqpExtConnectionFactory) { + return new AmqpTransportFactory('default_amqp_ext'); } - if ($connectionFactory instanceof FsConnectionFactory) { + if ($factory instanceof AmqpLibConnectionFactory) { + return new AmqpLibTransportFactory('default_amqp_lib'); + } + + if ($factory instanceof AmqpBunnyConnectionFactory) { + return new AmqpBunnyTransportFactory('default_amqp_bunny'); + } + + if ($factory instanceof FsConnectionFactory) { return new FsTransportFactory('default_fs'); } - if ($connectionFactory instanceof DbalConnectionFactory) { + if ($factory instanceof DbalConnectionFactory) { return new DbalTransportFactory('default_dbal'); } - if ($connectionFactory instanceof NullConnectionFactory) { + if ($factory instanceof NullConnectionFactory) { return new NullTransportFactory('default_null'); } + if ($factory instanceof GpsConnectionFactory) { + return new GpsTransportFactory('default_gps'); + } + + if ($factory instanceof RedisConnectionFactory) { + return new RedisTransportFactory('default_redis'); + } + + if ($factory instanceof SqsConnectionFactory) { + return new SqsTransportFactory('default_sqs'); + } + + if ($factory instanceof StompConnectionFactory) { + return new StompTransportFactory('default_stomp'); + } + throw new \LogicException(sprintf( 'There is no supported transport factory for the connection factory "%s" created from DSN "%s"', - get_class($connectionFactory), + get_class($factory), $dsn )); } diff --git a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php index fff8abf05..4b7df3852 100644 --- a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php @@ -6,6 +6,7 @@ use Enqueue\Dbal\DbalConnectionFactory; use Enqueue\Fs\FsConnectionFactory; use Enqueue\Gearman\GearmanConnectionFactory; +use Enqueue\Gps\GpsConnectionFactory; use Enqueue\Null\NullConnectionFactory; use Enqueue\Pheanstalk\PheanstalkConnectionFactory; use Enqueue\RdKafka\RdKafkaConnectionFactory; @@ -80,5 +81,7 @@ public static function provideDSNs() yield ['stomp:', StompConnectionFactory::class]; yield ['sqs:', SqsConnectionFactory::class]; + + yield ['gps:', GpsConnectionFactory::class]; } } diff --git a/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php index fd1260a4f..4e8b4c601 100644 --- a/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php @@ -4,6 +4,7 @@ use Enqueue\AmqpExt\AmqpContext; use Enqueue\Fs\FsContext; +use Enqueue\Gps\GpsContext; use Enqueue\Null\NullContext; use Enqueue\Redis\RedisContext; use Enqueue\Sqs\SqsContext; @@ -66,5 +67,7 @@ public static function provideDSNs() yield ['stomp:', StompContext::class]; yield ['sqs:', SqsContext::class]; + + yield ['gps:', GpsContext::class]; } } diff --git a/pkg/enqueue/Tests/Symfony/DefaultTransportFactoryTest.php b/pkg/enqueue/Tests/Symfony/DefaultTransportFactoryTest.php index 953145988..5ee18c211 100644 --- a/pkg/enqueue/Tests/Symfony/DefaultTransportFactoryTest.php +++ b/pkg/enqueue/Tests/Symfony/DefaultTransportFactoryTest.php @@ -250,7 +250,11 @@ public function testShouldCreateDriverFromDsn($dsn, $expectedName) public static function provideDSNs() { - yield ['amqp://', 'default_amqp']; + yield ['amqp+ext://', 'default_amqp_ext']; + + yield ['amqp+lib:', 'default_amqp_lib']; + + yield ['amqp+bunny://', 'default_amqp_bunny']; yield ['null://', 'default_null']; @@ -259,5 +263,13 @@ public static function provideDSNs() yield ['mysql://', 'default_dbal']; yield ['pgsql://', 'default_dbal']; + + yield ['gps:', 'default_gps']; + + yield ['sqs:', 'default_sqs']; + + yield ['redis:', 'default_redis']; + + yield ['stomp:', 'default_stomp']; } } diff --git a/pkg/enqueue/functions.php b/pkg/enqueue/functions.php index c89a3b89e..fef445f25 100644 --- a/pkg/enqueue/functions.php +++ b/pkg/enqueue/functions.php @@ -9,6 +9,7 @@ use Enqueue\Dbal\DbalConnectionFactory; use Enqueue\Fs\FsConnectionFactory; use Enqueue\Gearman\GearmanConnectionFactory; +use Enqueue\Gps\GpsConnectionFactory; use Enqueue\Null\NullConnectionFactory; use Enqueue\Pheanstalk\PheanstalkConnectionFactory; use Enqueue\RdKafka\RdKafkaConnectionFactory; @@ -35,7 +36,7 @@ function dsn_to_connection_factory($dsn) $map['amqp+ext'] = AmqpExtConnectionFactory::class; } if (class_exists(AmqpBunnyConnectionFactory::class)) { - $map['amqp+lib'] = AmqpBunnyConnectionFactory::class; + $map['amqp+lib'] = AmqpLibConnectionFactory::class; } if (class_exists(AmqpLibConnectionFactory::class)) { $map['amqp+bunny'] = AmqpBunnyConnectionFactory::class; @@ -95,6 +96,10 @@ function dsn_to_connection_factory($dsn) $map['sqs'] = SqsConnectionFactory::class; } + if (class_exists(GpsConnectionFactory::class)) { + $map['gps'] = GpsConnectionFactory::class; + } + list($scheme) = explode(':', $dsn, 2); if (false == $scheme || false === strpos($dsn, ':')) { throw new \LogicException(sprintf('The scheme could not be parsed from DSN "%s"', $dsn)); From 1762822401d991f0515bfe19410f7eb624c787ab Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 14:39:09 +0300 Subject: [PATCH 0024/1581] Release 0.7.15 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbb9f45ca..8a69dc5c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Change Log +## [0.7.15](https://github.com/php-enqueue/enqueue-dev/tree/0.7.15) (2017-09-25) +[Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.14...0.7.15) + +- \[FS\]\[RFC\] Change to FIFO queue [\#171](https://github.com/php-enqueue/enqueue-dev/issues/171) +- Transports must support configuration via DSN string [\#87](https://github.com/php-enqueue/enqueue-dev/issues/87) +- Add support of async message processing to transport interfaces. Like Java JMS. [\#27](https://github.com/php-enqueue/enqueue-dev/issues/27) +- \[redis\] add dsn support for redis transport. [\#204](https://github.com/php-enqueue/enqueue-dev/pull/204) ([makasim](https://github.com/makasim)) +- \[dbal\]\[bc break\] Performance improvements and new features. [\#199](https://github.com/php-enqueue/enqueue-dev/pull/199) ([makasim](https://github.com/makasim)) + +- \[FS\] Cannot decode json message [\#202](https://github.com/php-enqueue/enqueue-dev/issues/202) +- \[fs\] fix bugs introduced in \#181. [\#203](https://github.com/php-enqueue/enqueue-dev/pull/203) ([makasim](https://github.com/makasim)) + +- \[FS\] Cannot decode json message [\#201](https://github.com/php-enqueue/enqueue-dev/issues/201) +- \[FS\] Cannot decode json message [\#200](https://github.com/php-enqueue/enqueue-dev/issues/200) + +## [0.7.14](https://github.com/php-enqueue/enqueue-dev/tree/0.7.14) (2017-09-13) +[Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.13...0.7.14) + ## [0.7.13](https://github.com/php-enqueue/enqueue-dev/tree/0.7.13) (2017-09-13) [Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.12...0.7.13) From 59bbc53727200f2465f8526bf10bdae56a8d4a15 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 15:04:26 +0300 Subject: [PATCH 0025/1581] fix enqueue tests. --- pkg/enqueue/composer.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/enqueue/composer.json b/pkg/enqueue/composer.json index 80b65d521..334980577 100644 --- a/pkg/enqueue/composer.json +++ b/pkg/enqueue/composer.json @@ -19,11 +19,17 @@ "symfony/event-dispatcher": "^2.8|^3", "symfony/http-kernel": "^2.8|^3", "enqueue/amqp-ext": "^0.7@dev", + "enqueue/amqp-lib": "^0.7@dev", + "enqueue/amqp-bunny": "^0.7@dev", "enqueue/pheanstalk": "^0.7@dev", "enqueue/gearman": "^0.7@dev", "enqueue/rdkafka": "^0.7@dev", "enqueue/dbal": "^0.7@dev", "enqueue/fs": "^0.7@dev", + "enqueue/gps": "^0.7@dev", + "enqueue/redis": "^0.7@dev", + "enqueue/sqs": "^0.7@dev", + "enqueue/stomp": "^0.7@dev", "enqueue/test": "^0.7@dev", "enqueue/simple-client": "^0.7@dev", "empi89/php-amqp-stubs": "*@dev" From 9cb59d62bd5c6f00fda87ae6279aa50ef3056d8c Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 15:41:34 +0300 Subject: [PATCH 0026/1581] [dsn] replace xxx:// to xxx: --- docs/transport/kafka.md | 2 +- pkg/amqp-bunny/AmqpConnectionFactory.php | 5 ++--- pkg/amqp-ext/AmqpConnectionFactory.php | 5 ++--- pkg/amqp-lib/AmqpConnectionFactory.php | 5 ++--- pkg/dbal/DbalConnectionFactory.php | 15 +++++++++------ .../Tests/DbalConnectionFactoryConfigTest.php | 6 +++--- .../DsnToConnectionFactoryFunctionTest.php | 16 ++++++++-------- pkg/fs/FsConnectionFactory.php | 9 +++++---- pkg/gearman/GearmanConnectionFactory.php | 4 ++-- pkg/pheanstalk/PheanstalkConnectionFactory.php | 5 +++-- pkg/rdkafka/RdKafkaConnectionFactory.php | 10 +++++----- .../Tests/RdKafkaConnectionFactoryTest.php | 10 +++++----- 12 files changed, 47 insertions(+), 45 deletions(-) diff --git a/docs/transport/kafka.md b/docs/transport/kafka.md index 915f1b08b..951fb2591 100644 --- a/docs/transport/kafka.md +++ b/docs/transport/kafka.md @@ -25,7 +25,7 @@ use Enqueue\RdKafka\RdKafkaConnectionFactory; $connectionFactory = new RdKafkaConnectionFactory(); // same as above -$connectionFactory = new RdKafkaConnectionFactory('rdkafka://'); +$connectionFactory = new RdKafkaConnectionFactory('rdkafka:'); // same as above $connectionFactory = new RdKafkaConnectionFactory([]); diff --git a/pkg/amqp-bunny/AmqpConnectionFactory.php b/pkg/amqp-bunny/AmqpConnectionFactory.php index 48f5fe742..8bf7c6028 100644 --- a/pkg/amqp-bunny/AmqpConnectionFactory.php +++ b/pkg/amqp-bunny/AmqpConnectionFactory.php @@ -43,14 +43,13 @@ class AmqpConnectionFactory implements InteropAmqpConnectionFactory, DelayStrate * * @param array|string $config */ - public function __construct($config = 'amqp://') + public function __construct($config = 'amqp:') { if (is_string($config) && 0 === strpos($config, 'amqp+bunny:')) { $config = str_replace('amqp+bunny:', 'amqp:', $config); } - // third argument is deprecated will be removed in 0.8 - if (empty($config) || 'amqp:' === $config || 'amqp://' === $config) { + if (empty($config) || 'amqp:' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); diff --git a/pkg/amqp-ext/AmqpConnectionFactory.php b/pkg/amqp-ext/AmqpConnectionFactory.php index 3002ab0db..824856df5 100644 --- a/pkg/amqp-ext/AmqpConnectionFactory.php +++ b/pkg/amqp-ext/AmqpConnectionFactory.php @@ -45,14 +45,13 @@ class AmqpConnectionFactory implements InteropAmqpConnectionFactory, DelayStrate * * @param array|string $config */ - public function __construct($config = 'amqp://') + public function __construct($config = 'amqp:') { if (is_string($config) && 0 === strpos($config, 'amqp+ext:')) { $config = str_replace('amqp+ext:', 'amqp:', $config); } - // third argument is deprecated will be removed in 0.8 - if (empty($config) || 'amqp:' === $config || 'amqp://' === $config) { + if (empty($config) || 'amqp:' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); diff --git a/pkg/amqp-lib/AmqpConnectionFactory.php b/pkg/amqp-lib/AmqpConnectionFactory.php index 0ecc1e52c..3c90dd473 100644 --- a/pkg/amqp-lib/AmqpConnectionFactory.php +++ b/pkg/amqp-lib/AmqpConnectionFactory.php @@ -48,14 +48,13 @@ class AmqpConnectionFactory implements InteropAmqpConnectionFactory, DelayStrate * * @param array|string $config */ - public function __construct($config = 'amqp://') + public function __construct($config = 'amqp:') { if (is_string($config) && 0 === strpos($config, 'amqp+lib:')) { $config = str_replace('amqp+lib:', 'amqp:', $config); } - // third argument is deprecated will be removed in 0.8 - if (empty($config) || 'amqp:' === $config || 'amqp://' === $config) { + if (empty($config) || 'amqp:' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); diff --git a/pkg/dbal/DbalConnectionFactory.php b/pkg/dbal/DbalConnectionFactory.php index f7d034849..55164213c 100644 --- a/pkg/dbal/DbalConnectionFactory.php +++ b/pkg/dbal/DbalConnectionFactory.php @@ -34,10 +34,10 @@ class DbalConnectionFactory implements PsrConnectionFactory * * @param array|string|null $config */ - public function __construct($config = 'mysql://') + public function __construct($config = 'mysql:') { if (empty($config)) { - $config = $this->parseDsn('mysql://'); + $config = $this->parseDsn('mysql:'); } elseif (is_string($config)) { $config = $this->parseDsn($config); } elseif (is_array($config)) { @@ -94,11 +94,14 @@ private function establishConnection() */ private function parseDsn($dsn) { - if (false === strpos($dsn, '://')) { - throw new \LogicException(sprintf('The given DSN "%s" is not valid. Must contain "://".', $dsn)); + if (false === parse_url($dsn)) { + throw new \LogicException(sprintf('Failed to parse DSN "%s"', $dsn)); } - list($schema, $rest) = explode('://', $dsn, 2); + $schema = parse_url($dsn, PHP_URL_SCHEME); + if (empty($schema)) { + throw new \LogicException('Schema is empty'); + } $supported = [ 'db2' => true, @@ -128,7 +131,7 @@ private function parseDsn($dsn) return [ 'lazy' => true, 'connection' => [ - 'url' => empty($rest) ? $schema.'://root@localhost' : $dsn, + 'url' => $schema.':' === $dsn ? $schema.'://root@localhost' : $dsn, ], ]; } diff --git a/pkg/dbal/Tests/DbalConnectionFactoryConfigTest.php b/pkg/dbal/Tests/DbalConnectionFactoryConfigTest.php index 39a29563d..eeaf31c34 100644 --- a/pkg/dbal/Tests/DbalConnectionFactoryConfigTest.php +++ b/pkg/dbal/Tests/DbalConnectionFactoryConfigTest.php @@ -32,7 +32,7 @@ public function testThrowIfSchemeIsNotSupported() public function testThrowIfDsnCouldNotBeParsed() { $this->expectException(\LogicException::class); - $this->expectExceptionMessage('The given DSN "invalidDSN" is not valid. Must contain "://".'); + $this->expectExceptionMessage('Schema is empty'); new DbalConnectionFactory('invalidDSN'); } @@ -63,7 +63,7 @@ public static function provideConfigs() ]; yield [ - 'mysql://', + 'mysql:', [ 'lazy' => true, 'connection' => [ @@ -73,7 +73,7 @@ public static function provideConfigs() ]; yield [ - 'pgsql://', + 'pgsql:', [ 'lazy' => true, 'connection' => [ diff --git a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php index 4b7df3852..59c5333b6 100644 --- a/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToConnectionFactoryFunctionTest.php @@ -56,25 +56,25 @@ public function testReturnsExpectedFactoryInstance($dsn, $expectedFactoryClass) public static function provideDSNs() { - yield ['amqp://', AmqpConnectionFactory::class]; + yield ['amqp:', AmqpConnectionFactory::class]; yield ['amqp://user:pass@foo/vhost', AmqpConnectionFactory::class]; - yield ['file://', FsConnectionFactory::class]; + yield ['file:', FsConnectionFactory::class]; yield ['file:///foo/bar/baz', FsConnectionFactory::class]; - yield ['null://', NullConnectionFactory::class]; + yield ['null:', NullConnectionFactory::class]; - yield ['mysql://', DbalConnectionFactory::class]; + yield ['mysql:', DbalConnectionFactory::class]; - yield ['pgsql://', DbalConnectionFactory::class]; + yield ['pgsql:', DbalConnectionFactory::class]; - yield ['beanstalk://', PheanstalkConnectionFactory::class]; + yield ['beanstalk:', PheanstalkConnectionFactory::class]; - // yield ['gearman://', GearmanConnectionFactory::class]; + // yield ['gearman:', GearmanConnectionFactory::class]; - yield ['rdkafka://', RdKafkaConnectionFactory::class]; + yield ['kafka:', RdKafkaConnectionFactory::class]; yield ['redis:', RedisConnectionFactory::class]; diff --git a/pkg/fs/FsConnectionFactory.php b/pkg/fs/FsConnectionFactory.php index f155c9df9..8627edb95 100644 --- a/pkg/fs/FsConnectionFactory.php +++ b/pkg/fs/FsConnectionFactory.php @@ -23,14 +23,15 @@ class FsConnectionFactory implements PsrConnectionFactory * * or * + * file: - create queue files in tmp dir. * file://home/foo/enqueue * file://home/foo/enqueue?pre_fetch_count=20&chmod=0777 * * @param array|string|null $config */ - public function __construct($config = 'file://') + public function __construct($config = 'file:') { - if (empty($config) || 'file://' === $config) { + if (empty($config) || 'file:' === $config) { $config = ['path' => sys_get_temp_dir().'/enqueue']; } elseif (is_string($config)) { $config = $this->parseDsn($config); @@ -68,8 +69,8 @@ private function parseDsn($dsn) return ['path' => $dsn]; } - if (false === strpos($dsn, 'file://')) { - throw new \LogicException(sprintf('The given DSN "%s" is not supported. Must start with "file://".', $dsn)); + if (false === strpos($dsn, 'file:')) { + throw new \LogicException(sprintf('The given DSN "%s" is not supported. Must start with "file:".', $dsn)); } $dsn = substr($dsn, 7); diff --git a/pkg/gearman/GearmanConnectionFactory.php b/pkg/gearman/GearmanConnectionFactory.php index dd91dccaa..77f8dfd96 100644 --- a/pkg/gearman/GearmanConnectionFactory.php +++ b/pkg/gearman/GearmanConnectionFactory.php @@ -25,9 +25,9 @@ class GearmanConnectionFactory implements PsrConnectionFactory * * @param array|string $config */ - public function __construct($config = 'gearman://') + public function __construct($config = 'gearman:') { - if (empty($config) || 'gearman://' === $config) { + if (empty($config) || 'gearman:' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); diff --git a/pkg/pheanstalk/PheanstalkConnectionFactory.php b/pkg/pheanstalk/PheanstalkConnectionFactory.php index c2d629769..40999ccef 100644 --- a/pkg/pheanstalk/PheanstalkConnectionFactory.php +++ b/pkg/pheanstalk/PheanstalkConnectionFactory.php @@ -29,13 +29,14 @@ class PheanstalkConnectionFactory implements PsrConnectionFactory * * or * + * beanstalk: - connects to localhost:11300 * beanstalk://host:port * * @param array|string $config */ - public function __construct($config = 'beanstalk://') + public function __construct($config = 'beanstalk:') { - if (empty($config) || 'beanstalk://' === $config) { + if (empty($config) || 'beanstalk:' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); diff --git a/pkg/rdkafka/RdKafkaConnectionFactory.php b/pkg/rdkafka/RdKafkaConnectionFactory.php index 4db818686..a3fdbc13e 100644 --- a/pkg/rdkafka/RdKafkaConnectionFactory.php +++ b/pkg/rdkafka/RdKafkaConnectionFactory.php @@ -29,13 +29,13 @@ class RdKafkaConnectionFactory implements PsrConnectionFactory * * or * - * rdkafka://host:port + * kafka://host:port * * @param array|string $config */ - public function __construct($config = 'rdkafka://') + public function __construct($config = 'kafka:') { - if (empty($config) || 'rdkafka://' === $config) { + if (empty($config) || 'kafka:' === $config) { $config = []; } elseif (is_string($config)) { $config = $this->parseDsn($config); @@ -79,8 +79,8 @@ private function parseDsn($dsn) 'query' => null, ], $dsnConfig); - if ('rdkafka' !== $dsnConfig['scheme']) { - throw new \LogicException(sprintf('The given DSN scheme "%s" is not supported. Could be "rdkafka" only.', $dsnConfig['scheme'])); + if ('kafka' !== $dsnConfig['scheme']) { + throw new \LogicException(sprintf('The given DSN scheme "%s" is not supported. Could be "kafka" only.', $dsnConfig['scheme'])); } $config = []; diff --git a/pkg/rdkafka/Tests/RdKafkaConnectionFactoryTest.php b/pkg/rdkafka/Tests/RdKafkaConnectionFactoryTest.php index 1b765679c..3422499b6 100644 --- a/pkg/rdkafka/Tests/RdKafkaConnectionFactoryTest.php +++ b/pkg/rdkafka/Tests/RdKafkaConnectionFactoryTest.php @@ -18,7 +18,7 @@ public function testThrowNeitherArrayStringNorNullGivenAsConfig() public function testThrowIfSchemeIsNotBeanstalkAmqp() { $this->expectException(\LogicException::class); - $this->expectExceptionMessage('The given DSN scheme "http" is not supported. Could be "rdkafka" only.'); + $this->expectExceptionMessage('The given DSN scheme "http" is not supported. Could be "kafka" only.'); new RdKafkaConnectionFactory('http://example.com'); } @@ -26,9 +26,9 @@ public function testThrowIfSchemeIsNotBeanstalkAmqp() public function testThrowIfDsnCouldNotBeParsed() { $this->expectException(\LogicException::class); - $this->expectExceptionMessage('Failed to parse DSN "rdkafka://:@/"'); + $this->expectExceptionMessage('Failed to parse DSN "kafka://:@/"'); - new RdKafkaConnectionFactory('rdkafka://:@/'); + new RdKafkaConnectionFactory('kafka://:@/'); } public function testShouldBeExpectedDefaultConfig() @@ -50,7 +50,7 @@ public function testShouldBeExpectedDefaultConfig() public function testShouldBeExpectedDefaultDsnConfig() { - $factory = new RdKafkaConnectionFactory('rdkafka://'); + $factory = new RdKafkaConnectionFactory('kafka:'); $config = $this->getObjectAttribute($factory, 'config'); @@ -81,7 +81,7 @@ public function testShouldParseConfigurationAsExpected($config, $expectedConfig) public static function provideConfigs() { yield [ - 'rdkafka://theHost:1234?global%5Bgroup.id%5D=group-id', + 'kafka://theHost:1234?global%5Bgroup.id%5D=group-id', [ 'global' => [ 'metadata.broker.list' => 'theHost:1234', From 26735040fb9eb8b6a90a7bcf41c851661ff55381 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 15:46:17 +0300 Subject: [PATCH 0027/1581] upd docs. --- docs/transport/amqp.md | 11 ++++++----- docs/transport/amqp_bunny.md | 13 +++++++------ docs/transport/amqp_lib.md | 13 +++++++------ docs/transport/dbal.md | 3 +++ docs/transport/filesystem.md | 2 +- docs/transport/gearman.md | 2 +- docs/transport/gps.md | 3 +++ docs/transport/kafka.md | 2 +- docs/transport/pheanstalk.md | 2 +- 9 files changed, 30 insertions(+), 21 deletions(-) diff --git a/docs/transport/amqp.md b/docs/transport/amqp.md index 8fd374521..065f307af 100644 --- a/docs/transport/amqp.md +++ b/docs/transport/amqp.md @@ -32,13 +32,14 @@ use Enqueue\AmqpExt\AmqpConnectionFactory; $connectionFactory = new AmqpConnectionFactory(); // same as above -$connectionFactory = new AmqpConnectionFactory('amqp://'); +$factory = new AmqpConnectionFactory('amqp:'); +$factory = new AmqpConnectionFactory('amqp+ext:'); // same as above -$connectionFactory = new AmqpConnectionFactory([]); +$factory = new AmqpConnectionFactory([]); // connect to AMQP broker at example.com -$connectionFactory = new AmqpConnectionFactory([ +$factory = new AmqpConnectionFactory([ 'host' => 'example.com', 'port' => 1000, 'vhost' => '/', @@ -48,9 +49,9 @@ $connectionFactory = new AmqpConnectionFactory([ ]); // same as above but given as DSN string -$connectionFactory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); +$factory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); -$psrContext = $connectionFactory->createContext(); +$psrContext = $factory->createContext(); ``` ## Declare topic. diff --git a/docs/transport/amqp_bunny.md b/docs/transport/amqp_bunny.md index 28c78c8cc..37d7b26a9 100644 --- a/docs/transport/amqp_bunny.md +++ b/docs/transport/amqp_bunny.md @@ -29,16 +29,17 @@ $ composer require enqueue/amqp-bunny use Enqueue\AmqpBunny\AmqpConnectionFactory; // connects to localhost -$connectionFactory = new AmqpConnectionFactory(); +$factory = new AmqpConnectionFactory(); // same as above -$connectionFactory = new AmqpConnectionFactory('amqp://'); +$factory = new AmqpConnectionFactory('amqp:'); +$factory = new AmqpConnectionFactory('amqp+bunny:'); // same as above -$connectionFactory = new AmqpConnectionFactory([]); +$factory = new AmqpConnectionFactory([]); // connect to AMQP broker at example.com -$connectionFactory = new AmqpConnectionFactory([ +$factory = new AmqpConnectionFactory([ 'host' => 'example.com', 'port' => 1000, 'vhost' => '/', @@ -48,9 +49,9 @@ $connectionFactory = new AmqpConnectionFactory([ ]); // same as above but given as DSN string -$connectionFactory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); +$factory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); -$psrContext = $connectionFactory->createContext(); +$psrContext = $factory->createContext(); ``` ## Declare topic. diff --git a/docs/transport/amqp_lib.md b/docs/transport/amqp_lib.md index 59061352d..34e297222 100644 --- a/docs/transport/amqp_lib.md +++ b/docs/transport/amqp_lib.md @@ -29,16 +29,17 @@ $ composer require enqueue/amqp-lib use Enqueue\AmqpLib\AmqpConnectionFactory; // connects to localhost -$connectionFactory = new AmqpConnectionFactory(); +$factory = new AmqpConnectionFactory(); // same as above -$connectionFactory = new AmqpConnectionFactory('amqp://'); +$factory = new AmqpConnectionFactory('amqp:'); +$factory = new AmqpConnectionFactory('amqp+lib:'); // same as above -$connectionFactory = new AmqpConnectionFactory([]); +$factory = new AmqpConnectionFactory([]); // connect to AMQP broker at example.com -$connectionFactory = new AmqpConnectionFactory([ +$factory = new AmqpConnectionFactory([ 'host' => 'example.com', 'port' => 1000, 'vhost' => '/', @@ -48,9 +49,9 @@ $connectionFactory = new AmqpConnectionFactory([ ]); // same as above but given as DSN string -$connectionFactory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); +$factory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); -$psrContext = $connectionFactory->createContext(); +$psrContext = $factory->createContext(); ``` ## Declare topic. diff --git a/docs/transport/dbal.md b/docs/transport/dbal.md index 9f39bc729..d4ff3f219 100644 --- a/docs/transport/dbal.md +++ b/docs/transport/dbal.md @@ -28,6 +28,9 @@ use Enqueue\Dbal\DbalConnectionFactory; $factory = new DbalConnectionFactory('mysql://user:pass@localhost:3306/mqdev'); +// connects to localhost +$factory = new DbalConnectionFactory('mysql:'); + $psrContext = $factory->createContext(); ``` diff --git a/docs/transport/filesystem.md b/docs/transport/filesystem.md index 3b529eadc..1eddedceb 100644 --- a/docs/transport/filesystem.md +++ b/docs/transport/filesystem.md @@ -29,7 +29,7 @@ use Enqueue\Fs\FsConnectionFactory; $connectionFactory = new FsConnectionFactory(); // same as above -$connectionFactory = new FsConnectionFactory('file://'); +$connectionFactory = new FsConnectionFactory('file:'); // stores in custom folder $connectionFactory = new FsConnectionFactory('/path/to/queue/dir'); diff --git a/docs/transport/gearman.md b/docs/transport/gearman.md index a9dc0dc24..412e0beca 100644 --- a/docs/transport/gearman.md +++ b/docs/transport/gearman.md @@ -26,7 +26,7 @@ use Enqueue\Gearman\GearmanConnectionFactory; $factory = new GearmanConnectionFactory(); // same as above -$factory = new GearmanConnectionFactory('gearman://'); +$factory = new GearmanConnectionFactory('gearman:'); // connects to example host and port 5555 $factory = new GearmanConnectionFactory('gearman://example:5555'); diff --git a/docs/transport/gps.md b/docs/transport/gps.md index f124feb9b..2a7496ab0 100644 --- a/docs/transport/gps.md +++ b/docs/transport/gps.md @@ -27,6 +27,9 @@ putenv('PUBSUB_EMULATOR_HOST=http://localhost:8900'); $connectionFactory = new GpsConnectionFactory(); +// save as above +$connectionFactory = new GpsConnectionFactory('gps:'); + $psrContext = $connectionFactory->createContext(); ``` diff --git a/docs/transport/kafka.md b/docs/transport/kafka.md index 951fb2591..aac6bbca0 100644 --- a/docs/transport/kafka.md +++ b/docs/transport/kafka.md @@ -25,7 +25,7 @@ use Enqueue\RdKafka\RdKafkaConnectionFactory; $connectionFactory = new RdKafkaConnectionFactory(); // same as above -$connectionFactory = new RdKafkaConnectionFactory('rdkafka:'); +$connectionFactory = new RdKafkaConnectionFactory('kafka:'); // same as above $connectionFactory = new RdKafkaConnectionFactory([]); diff --git a/docs/transport/pheanstalk.md b/docs/transport/pheanstalk.md index 559517c00..d1c2b0400 100644 --- a/docs/transport/pheanstalk.md +++ b/docs/transport/pheanstalk.md @@ -26,7 +26,7 @@ use Enqueue\Pheanstalk\PheanstalkConnectionFactory; $factory = new PheanstalkConnectionFactory(); // same as above -$factory = new PheanstalkConnectionFactory('beanstalk://'); +$factory = new PheanstalkConnectionFactory('beanstalk:'); // connects to example host and port 5555 $factory = new PheanstalkConnectionFactory('beanstalk://example:5555'); From 387b1da1dd49d647549c49fdc87b7056055cb157 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 16:01:51 +0300 Subject: [PATCH 0028/1581] [doc] add dsn_to_context usage example --- docs/transport/amqp.md | 5 ++++- docs/transport/amqp_bunny.md | 5 ++++- docs/transport/amqp_lib.md | 5 ++++- docs/transport/dbal.md | 3 +++ docs/transport/filesystem.md | 3 +++ docs/transport/gearman.md | 5 +++++ docs/transport/gps.md | 3 +++ docs/transport/kafka.md | 3 +++ docs/transport/pheanstalk.md | 5 +++++ docs/transport/redis.md | 3 +++ docs/transport/sqs.md | 3 +++ docs/transport/stomp.md | 3 +++ 12 files changed, 43 insertions(+), 3 deletions(-) diff --git a/docs/transport/amqp.md b/docs/transport/amqp.md index 065f307af..fcfdd1436 100644 --- a/docs/transport/amqp.md +++ b/docs/transport/amqp.md @@ -33,7 +33,6 @@ $connectionFactory = new AmqpConnectionFactory(); // same as above $factory = new AmqpConnectionFactory('amqp:'); -$factory = new AmqpConnectionFactory('amqp+ext:'); // same as above $factory = new AmqpConnectionFactory([]); @@ -52,6 +51,10 @@ $factory = new AmqpConnectionFactory([ $factory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); $psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('amqp:'); +$psrContext = \Enqueue\dsn_to_context('amqp+ext:'); ``` ## Declare topic. diff --git a/docs/transport/amqp_bunny.md b/docs/transport/amqp_bunny.md index 37d7b26a9..09b59336e 100644 --- a/docs/transport/amqp_bunny.md +++ b/docs/transport/amqp_bunny.md @@ -33,7 +33,6 @@ $factory = new AmqpConnectionFactory(); // same as above $factory = new AmqpConnectionFactory('amqp:'); -$factory = new AmqpConnectionFactory('amqp+bunny:'); // same as above $factory = new AmqpConnectionFactory([]); @@ -52,6 +51,10 @@ $factory = new AmqpConnectionFactory([ $factory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); $psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('amqp:'); +$psrContext = \Enqueue\dsn_to_context('amqp+bunny:'); ``` ## Declare topic. diff --git a/docs/transport/amqp_lib.md b/docs/transport/amqp_lib.md index 34e297222..8ce661433 100644 --- a/docs/transport/amqp_lib.md +++ b/docs/transport/amqp_lib.md @@ -33,7 +33,6 @@ $factory = new AmqpConnectionFactory(); // same as above $factory = new AmqpConnectionFactory('amqp:'); -$factory = new AmqpConnectionFactory('amqp+lib:'); // same as above $factory = new AmqpConnectionFactory([]); @@ -52,6 +51,10 @@ $factory = new AmqpConnectionFactory([ $factory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f'); $psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('amqp:'); +$psrContext = \Enqueue\dsn_to_context('amqp+lib:'); ``` ## Declare topic. diff --git a/docs/transport/dbal.md b/docs/transport/dbal.md index d4ff3f219..2d84782e1 100644 --- a/docs/transport/dbal.md +++ b/docs/transport/dbal.md @@ -48,6 +48,9 @@ $factory = new ManagerRegistryConnectionFactory($registry, [ ]); $psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('mysql:'); ``` ## Init database diff --git a/docs/transport/filesystem.md b/docs/transport/filesystem.md index 1eddedceb..825b7b5a2 100644 --- a/docs/transport/filesystem.md +++ b/docs/transport/filesystem.md @@ -47,6 +47,9 @@ $connectionFactory = new FsConnectionFactory([ ]); $psrContext = $connectionFactory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('file:'); ``` ## Send message to topic diff --git a/docs/transport/gearman.md b/docs/transport/gearman.md index 412e0beca..0161048d5 100644 --- a/docs/transport/gearman.md +++ b/docs/transport/gearman.md @@ -36,6 +36,11 @@ $factory = new GearmanConnectionFactory([ 'host' => 'example', 'port' => 5555 ]); + +$psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('gearman:'); ``` ## Send message to topic diff --git a/docs/transport/gps.md b/docs/transport/gps.md index 2a7496ab0..7d0197f23 100644 --- a/docs/transport/gps.md +++ b/docs/transport/gps.md @@ -31,6 +31,9 @@ $connectionFactory = new GpsConnectionFactory(); $connectionFactory = new GpsConnectionFactory('gps:'); $psrContext = $connectionFactory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('gps:'); ``` ## Send message to topic diff --git a/docs/transport/kafka.md b/docs/transport/kafka.md index aac6bbca0..efc564fa2 100644 --- a/docs/transport/kafka.md +++ b/docs/transport/kafka.md @@ -43,6 +43,9 @@ $connectionFactory = new RdKafkaConnectionFactory([ ]); $psrContext = $connectionFactory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('kafka:'); ``` ## Send message to topic diff --git a/docs/transport/pheanstalk.md b/docs/transport/pheanstalk.md index d1c2b0400..4371c2966 100644 --- a/docs/transport/pheanstalk.md +++ b/docs/transport/pheanstalk.md @@ -36,6 +36,11 @@ $factory = new PheanstalkConnectionFactory([ 'host' => 'example', 'port' => 5555 ]); + +$psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('beanstalk:'); ``` ## Send message to topic diff --git a/docs/transport/redis.md b/docs/transport/redis.md index 3ded64a36..0b362217a 100644 --- a/docs/transport/redis.md +++ b/docs/transport/redis.md @@ -58,6 +58,9 @@ $factory = new RedisConnectionFactory([ $factory = new RedisConnectionFactory('redis://example.com:1000?vendor=phpredis'); $psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('redis:'); ``` * With predis library: diff --git a/docs/transport/sqs.md b/docs/transport/sqs.md index 2c35c8bc3..03da0ebeb 100644 --- a/docs/transport/sqs.md +++ b/docs/transport/sqs.md @@ -33,6 +33,9 @@ $factory = new SqsConnectionFactory([ $factory = new SqsConnectionFactory('sqs:?key=aKey&secret=aSecret®ion=aRegion'); $psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('sqs:'); ``` ## Declare queue. diff --git a/docs/transport/stomp.md b/docs/transport/stomp.md index 1b40f96d1..fb9ea7694 100644 --- a/docs/transport/stomp.md +++ b/docs/transport/stomp.md @@ -38,6 +38,9 @@ $factory = new StompConnectionFactory([ $factory = new StompConnectionFactory('stomp://example.com:1000?login=theLogin'); $psrContext = $factory->createContext(); + +// if you have enqueue/enqueue library installed you can use a function from there to create the context +$psrContext = \Enqueue\dsn_to_context('stomp:'); ``` ## Send message to topic From 69674da46304534aeae3f7ab863229930b34358e Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 16:26:40 +0300 Subject: [PATCH 0029/1581] [dsn] fix tests. clean up docs. --- docs/bundle/quick_tour.md | 4 +- docs/client/quick_tour.md | 2 +- docs/client/rpc_call.md | 101 +++++++++--------- docs/laravel/queues.md | 2 +- docs/quick_tour.md | 6 +- .../Tests/AmqpConnectionFactoryConfigTest.php | 2 +- .../Tests/AmqpConnectionFactoryConfigTest.php | 2 +- .../Tests/AmqpConnectionFactoryConfigTest.php | 2 +- .../Symfony/DefaultTransportFactory.php | 2 +- .../Functions/DsnToContextFunctionTest.php | 6 +- .../Symfony/DefaultTransportFactoryTest.php | 16 +-- pkg/simple-client/SimpleClient.php | 4 +- 12 files changed, 75 insertions(+), 74 deletions(-) diff --git a/docs/bundle/quick_tour.md b/docs/bundle/quick_tour.md index 9bd5e4b0d..cb9b0dcdf 100644 --- a/docs/bundle/quick_tour.md +++ b/docs/bundle/quick_tour.md @@ -6,7 +6,7 @@ It adds easy to use [configuration layer](config_reference.md), register service ## Install ```bash -$ composer require enqueue/enqueue-bundle enqueue/amqp-ext +$ composer require enqueue/enqueue-bundle enqueue/amqp-ext # or enqueue/amqp-bunny, enqueue/amqp-lib ``` _**Note**: You could use not only AMQP transport but other available: STOMP, Amazon SQS, Redis, Filesystem, Doctrine DBAL and others._ @@ -47,7 +47,7 @@ First, you have to configure a transport layer and set one to be default. enqueue: transport: - default: "amqp://" + default: "amqp:" client: ~ ``` diff --git a/docs/client/quick_tour.md b/docs/client/quick_tour.md index a5a4a3ed3..35e59537f 100644 --- a/docs/client/quick_tour.md +++ b/docs/client/quick_tour.md @@ -22,7 +22,7 @@ use Enqueue\SimpleClient\SimpleClient; include __DIR__.'/vendor/autoload.php'; -$client = new SimpleClient('amqp://'); +$client = new SimpleClient('amqp:'); ``` ## Produce message diff --git a/docs/client/rpc_call.md b/docs/client/rpc_call.md index 94a964d30..4afb1e722 100644 --- a/docs/client/rpc_call.md +++ b/docs/client/rpc_call.md @@ -1,55 +1,14 @@ # Client. RPC call The client's [quick tour](quick_tour.md) describes how to get the client object. -Here we'll use `Enqueue\SimpleClient\SimpleClient` though it is not required. -You can get all that stuff from manually built client or get objects from a container (Symfony). +Here we'll show you how to use Enqueue Client to perform a [RPC call](https://en.wikipedia.org/wiki/Remote_procedure_call). +You can do it by defining a command which returns something. -The simple client could be created like this: +## The consumer side -## The client side +On the consumer side we have to register a command processor which computes the result and send it back to the sender. +Pay attention that you have to add reply extension. It wont work without it. -There is a handy class RpcClient shipped with the client component. -It allows you to easily perform [RPC calls](https://en.wikipedia.org/wiki/Remote_procedure_call). -It send a message and wait for a reply. - -```php -getProducer(), $context); - -$replyMessage = $rpcClient->call('greeting_topic', 'Hi Thomas!', 5); -``` - -You can perform several requests asynchronously with `callAsync` and request replays later. - -```php -getProducer(), $context); - -$promises = []; -$promises[] = $rpcClient->callAsync('greeting_topic', 'Hi Thomas!', 5); -$promises[] = $rpcClient->callAsync('greeting_topic', 'Hi Thomas!', 5); -$promises[] = $rpcClient->callAsync('greeting_topic', 'Hi Thomas!', 5); -$promises[] = $rpcClient->callAsync('greeting_topic', 'Hi Thomas!', 5); - -$replyMessages = []; -foreach ($promises as $promise) { - $replyMessages[] = $promise->receive(); -} -``` - -## The server side - -On the server side you may register a processor which returns a result object with a reply message set. Of course it is possible to implement rpc server side based on transport classes only. That would require a bit more work to do. ```php @@ -60,19 +19,61 @@ use Interop\Queue\PsrContext; use Enqueue\Consumption\Result; use Enqueue\Consumption\ChainExtension; use Enqueue\Consumption\Extension\ReplyExtension; +use Enqueue\Client\Config; use Enqueue\SimpleClient\SimpleClient; /** @var \Interop\Queue\PsrContext $context */ -$client = new SimpleClient('amqp://'); +// composer require enqueue/amqp-ext # or enqueue/amqp-bunny, enqueue/amqp-lib +$client = new SimpleClient('amqp:'); -$client->bind('greeting_topic', 'greeting_processor', function (PsrMessage $message, PsrContext $context) use (&$requestMessage) { - echo $message->getBody(); +$client->bind(Config::COMMAND_TOPIC, 'square', function (PsrMessage $message, PsrContext $context) use (&$requestMessage) { + $number = (int) $message->getBody(); - return Result::reply($context->createMessage('Hi there! I am John.')); + return Result::reply($context->createMessage($number ^ 2)); }); $client->consume(new ChainExtension([new ReplyExtension()])); ``` [back to index](../index.md) + +## The sender side + +On the sender's side we need a client which send a command and wait for reply messages. + +```php +sendCommand('square', 5, true)->receive(5000 /* 5 sec */)->getBody(); +``` + +You can perform several requests asynchronously with `sendCommand` and ask for replays later. + +```php +sendCommand('square', 5, true); +$promises[] = $client->sendCommand('square', 10, true); +$promises[] = $client->sendCommand('square', 7, true); +$promises[] = $client->sendCommand('square', 12, true); + +$replyMessages = []; +while ($promises) { + foreach ($promises as $index => $promise) { + if ($replyMessage = $promise->receiveNoWait()) { + $replyMessages[$index] = $replyMessage; + + unset($promises[$index]); + } + } +} +``` \ No newline at end of file diff --git a/docs/laravel/queues.md b/docs/laravel/queues.md index a49b7832c..ed9dd9574 100644 --- a/docs/laravel/queues.md +++ b/docs/laravel/queues.md @@ -70,7 +70,7 @@ return [ 'connection_factory_class' => \Enqueue\AmqpBunny\AmqpConnectionFactory::class, // connects to localhost - 'dsn' => 'amqp://', + 'dsn' => 'amqp:', // could be "rabbitmq_dlx", "rabbitmq_delay_plugin", instance of DelayStrategy interface or null // 'delay_strategy' => 'rabbitmq_dlx' diff --git a/docs/quick_tour.md b/docs/quick_tour.md index 0be831500..9a5eb4fa9 100644 --- a/docs/quick_tour.md +++ b/docs/quick_tour.md @@ -171,7 +171,7 @@ use Enqueue\SimpleClient\SimpleClient; use Interop\Queue\PsrMessage; // composer require enqueue/amqp-ext -$client = new SimpleClient('amqp://'); +$client = new SimpleClient('amqp:'); // composer require enqueue/fs $client = new SimpleClient('file://foo/bar'); @@ -197,8 +197,8 @@ use Enqueue\Client\Config; use Enqueue\Consumption\Extension\ReplyExtension; use Enqueue\Consumption\Result; -// composer require enqueue/amqp-ext -$client = new SimpleClient('amqp://'); +// composer require enqueue/amqp-ext # or enqueue/amqp-bunny or enqueue/amqp-lib +$client = new SimpleClient('amqp:'); // composer require enqueue/fs $client = new SimpleClient('file://foo/bar'); diff --git a/pkg/amqp-bunny/Tests/AmqpConnectionFactoryConfigTest.php b/pkg/amqp-bunny/Tests/AmqpConnectionFactoryConfigTest.php index 4f761fd57..376ca33c4 100644 --- a/pkg/amqp-bunny/Tests/AmqpConnectionFactoryConfigTest.php +++ b/pkg/amqp-bunny/Tests/AmqpConnectionFactoryConfigTest.php @@ -148,7 +148,7 @@ public static function provideConfigs() ]; yield [ - 'amqp://', + 'amqp:', [ 'host' => 'localhost', 'port' => 5672, diff --git a/pkg/amqp-ext/Tests/AmqpConnectionFactoryConfigTest.php b/pkg/amqp-ext/Tests/AmqpConnectionFactoryConfigTest.php index 99950be4a..2cbbc2022 100644 --- a/pkg/amqp-ext/Tests/AmqpConnectionFactoryConfigTest.php +++ b/pkg/amqp-ext/Tests/AmqpConnectionFactoryConfigTest.php @@ -158,7 +158,7 @@ public static function provideConfigs() ]; yield [ - 'amqp://', + 'amqp:', [ 'host' => 'localhost', 'port' => 5672, diff --git a/pkg/amqp-lib/Tests/AmqpConnectionFactoryConfigTest.php b/pkg/amqp-lib/Tests/AmqpConnectionFactoryConfigTest.php index 50dcc12cc..48eb0d424 100644 --- a/pkg/amqp-lib/Tests/AmqpConnectionFactoryConfigTest.php +++ b/pkg/amqp-lib/Tests/AmqpConnectionFactoryConfigTest.php @@ -198,7 +198,7 @@ public static function provideConfigs() ]; yield [ - 'amqp://', + 'amqp:', [ 'host' => 'localhost', 'port' => 5672, diff --git a/pkg/enqueue/Symfony/DefaultTransportFactory.php b/pkg/enqueue/Symfony/DefaultTransportFactory.php index b79499c9c..2e3344488 100644 --- a/pkg/enqueue/Symfony/DefaultTransportFactory.php +++ b/pkg/enqueue/Symfony/DefaultTransportFactory.php @@ -58,7 +58,7 @@ public function addConfiguration(ArrayNodeDefinition $builder) } if (empty($v)) { - return ['dsn' => 'null://']; + return ['dsn' => 'null:']; } if (is_string($v)) { diff --git a/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php b/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php index 4e8b4c601..2a8bc83bc 100644 --- a/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php +++ b/pkg/enqueue/Tests/Functions/DsnToContextFunctionTest.php @@ -52,15 +52,15 @@ public function testReturnsExpectedFactoryInstance($dsn, $expectedFactoryClass) public static function provideDSNs() { - yield ['amqp://', AmqpContext::class]; + yield ['amqp:', AmqpContext::class]; yield ['amqp://user:pass@foo/vhost', AmqpContext::class]; - yield ['file://', FsContext::class]; + yield ['file:', FsContext::class]; yield ['file://'.sys_get_temp_dir(), FsContext::class]; - yield ['null://', NullContext::class]; + yield ['null:', NullContext::class]; yield ['redis:', RedisContext::class]; diff --git a/pkg/enqueue/Tests/Symfony/DefaultTransportFactoryTest.php b/pkg/enqueue/Tests/Symfony/DefaultTransportFactoryTest.php index 5ee18c211..1c7b0bd5c 100644 --- a/pkg/enqueue/Tests/Symfony/DefaultTransportFactoryTest.php +++ b/pkg/enqueue/Tests/Symfony/DefaultTransportFactoryTest.php @@ -82,10 +82,10 @@ public function testShouldSetNullTransportByDefault() $processor = new Processor(); $config = $processor->process($tb->buildTree(), [null]); - $this->assertEquals(['dsn' => 'null://'], $config); + $this->assertEquals(['dsn' => 'null:'], $config); $config = $processor->process($tb->buildTree(), ['']); - $this->assertEquals(['dsn' => 'null://'], $config); + $this->assertEquals(['dsn' => 'null:'], $config); } public function testThrowIfNeitherDsnNorAliasConfigured() @@ -250,19 +250,19 @@ public function testShouldCreateDriverFromDsn($dsn, $expectedName) public static function provideDSNs() { - yield ['amqp+ext://', 'default_amqp_ext']; + yield ['amqp+ext:', 'default_amqp_ext']; yield ['amqp+lib:', 'default_amqp_lib']; - yield ['amqp+bunny://', 'default_amqp_bunny']; + yield ['amqp+bunny:', 'default_amqp_bunny']; - yield ['null://', 'default_null']; + yield ['null:', 'default_null']; - yield ['file://', 'default_fs']; + yield ['file:', 'default_fs']; - yield ['mysql://', 'default_dbal']; + yield ['mysql:', 'default_dbal']; - yield ['pgsql://', 'default_dbal']; + yield ['pgsql:', 'default_dbal']; yield ['gps:', 'default_gps']; diff --git a/pkg/simple-client/SimpleClient.php b/pkg/simple-client/SimpleClient.php index cd7dc0793..14afa8e54 100644 --- a/pkg/simple-client/SimpleClient.php +++ b/pkg/simple-client/SimpleClient.php @@ -37,10 +37,10 @@ final class SimpleClient /** * The config could be a transport DSN (string) or an array, here's an example of a few DSNs:. * - * amqp:// + * amqp: * amqp://guest:guest@localhost:5672/%2f?lazy=1&persisted=1 * file://foo/bar/ - * null:// + * null: * * or an array, the most simple: * From 240f932acaa815f050b2a5d2bda0ec5452e6fb9b Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Mon, 25 Sep 2017 16:33:02 +0300 Subject: [PATCH 0030/1581] fix tests. --- pkg/fs/Tests/FsConnectionFactoryConfigTest.php | 4 ++-- pkg/gearman/Tests/GearmanConnectionFactoryConfigTest.php | 2 +- .../Tests/PheanstalkConnectionFactoryConfigTest.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/fs/Tests/FsConnectionFactoryConfigTest.php b/pkg/fs/Tests/FsConnectionFactoryConfigTest.php index a42ede8c6..c79581c51 100644 --- a/pkg/fs/Tests/FsConnectionFactoryConfigTest.php +++ b/pkg/fs/Tests/FsConnectionFactoryConfigTest.php @@ -24,7 +24,7 @@ public function testThrowNeitherArrayStringNorNullGivenAsConfig() public function testThrowIfSchemeIsNotAmqp() { $this->expectException(\LogicException::class); - $this->expectExceptionMessage('The given DSN "http://example.com" is not supported. Must start with "file://'); + $this->expectExceptionMessage('The given DSN "http://example.com" is not supported. Must start with "file:'); new FsConnectionFactory('http://example.com'); } @@ -83,7 +83,7 @@ public static function provideConfigs() ]; yield [ - 'file://', + 'file:', [ 'path' => sys_get_temp_dir().'/enqueue', 'pre_fetch_count' => 1, diff --git a/pkg/gearman/Tests/GearmanConnectionFactoryConfigTest.php b/pkg/gearman/Tests/GearmanConnectionFactoryConfigTest.php index 75c61591e..bb8ab7ad6 100644 --- a/pkg/gearman/Tests/GearmanConnectionFactoryConfigTest.php +++ b/pkg/gearman/Tests/GearmanConnectionFactoryConfigTest.php @@ -62,7 +62,7 @@ public static function provideConfigs() ]; yield [ - 'gearman://', + 'gearman:', [ 'host' => 'localhost', 'port' => 4730, diff --git a/pkg/pheanstalk/Tests/PheanstalkConnectionFactoryConfigTest.php b/pkg/pheanstalk/Tests/PheanstalkConnectionFactoryConfigTest.php index 239dae68f..231ec0d77 100644 --- a/pkg/pheanstalk/Tests/PheanstalkConnectionFactoryConfigTest.php +++ b/pkg/pheanstalk/Tests/PheanstalkConnectionFactoryConfigTest.php @@ -63,7 +63,7 @@ public static function provideConfigs() ]; yield [ - 'beanstalk://', + 'beanstalk:', [ 'host' => 'localhost', 'port' => 11300, From 2286dc22241f36a5cdb72721a42b2027d938c01e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Parmentier?= Date: Wed, 27 Sep 2017 17:52:28 +0200 Subject: [PATCH 0031/1581] Fixes the notation for Twig template names in the data collector --- pkg/enqueue-bundle/Resources/config/client.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/enqueue-bundle/Resources/config/client.yml b/pkg/enqueue-bundle/Resources/config/client.yml index f8a2b0c83..8fb6ab607 100644 --- a/pkg/enqueue-bundle/Resources/config/client.yml +++ b/pkg/enqueue-bundle/Resources/config/client.yml @@ -136,7 +136,7 @@ services: tags: - name: 'data_collector' - template: 'EnqueueBundle:Profiler:panel.html.twig' + template: '@Enqueue/Profiler/panel.html.twig' id: 'enqueue.message_queue' enqueue.flush_spool_producer_listener: From c6d5197b663bf596ec14fc78862aad891d1374d6 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Thu, 28 Sep 2017 14:47:36 +0300 Subject: [PATCH 0032/1581] Release 0.7.16 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a69dc5c2..5e47d3af3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## [0.7.16](https://github.com/php-enqueue/enqueue-dev/tree/0.7.16) (2017-09-28) +[Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.15...0.7.16) + +- Fixes the notation for Twig template names in the data collector [\#207](https://github.com/php-enqueue/enqueue-dev/pull/207) ([Lctrs](https://github.com/Lctrs)) + +- \[BC Break\]\[dsn\] replace xxx:// to xxx: [\#205](https://github.com/php-enqueue/enqueue-dev/pull/205) ([makasim](https://github.com/makasim)) + ## [0.7.15](https://github.com/php-enqueue/enqueue-dev/tree/0.7.15) (2017-09-25) [Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.7.14...0.7.15) From 620ddd24d44ed1fd9181c80390b04f7d520f1969 Mon Sep 17 00:00:00 2001 From: Maksim Kotlyar Date: Tue, 3 Oct 2017 11:23:50 +0300 Subject: [PATCH 0033/1581] [bundle][profiler] Fix array to string conversion notice. --- .../Profiler/MessageQueueCollector.php | 13 ++++--------- .../Resources/views/Profiler/panel.html.twig | 5 ++++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php b/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php index de5fa59bc..b3e2b5f0f 100644 --- a/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php +++ b/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php @@ -5,6 +5,7 @@ use Enqueue\Client\MessagePriority; use Enqueue\Client\ProducerInterface; use Enqueue\Client\TraceableProducer; +use Enqueue\Util\JSON; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollector; @@ -65,19 +66,13 @@ public function prettyPrintPriority($priority) } /** - * @param string $message + * @param mixed $body * * @return string */ - public function prettyPrintMessage($message) + public function ensureString($body) { - if (is_scalar($message)) { - return htmlspecialchars($message); - } - - return htmlspecialchars( - json_encode($message, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) - ); + return is_string($body) ? $body : JSON::encode($body); } /** diff --git a/pkg/enqueue-bundle/Resources/views/Profiler/panel.html.twig b/pkg/enqueue-bundle/Resources/views/Profiler/panel.html.twig index a8f783dfc..635a540d7 100644 --- a/pkg/enqueue-bundle/Resources/views/Profiler/panel.html.twig +++ b/pkg/enqueue-bundle/Resources/views/Profiler/panel.html.twig @@ -44,7 +44,10 @@ {{ sentMessage.topic }}