diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8ead19a..994d639bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change Log +## [0.10.13](https://github.com/php-enqueue/enqueue-dev/tree/0.10.13) (2021-08-25) +[Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.10.12...0.10.13) + +**Merged pull requests:** + +- \[SNSQS\] added possibility to send message attributes using snsqs transport [\#1195](https://github.com/php-enqueue/enqueue-dev/pull/1195) ([onatskyy](https://github.com/onatskyy)) +- Add in missing arg [\#1194](https://github.com/php-enqueue/enqueue-dev/pull/1194) ([gdsmith](https://github.com/gdsmith)) +- \#1190 add index on delivery\_id to prevent slow queries [\#1191](https://github.com/php-enqueue/enqueue-dev/pull/1191) ([commercewerft](https://github.com/commercewerft)) +- Add setTopicArn methods to SnsContext and SnsQsContext [\#1189](https://github.com/php-enqueue/enqueue-dev/pull/1189) ([gdsmith](https://github.com/gdsmith)) + ## [0.10.11](https://github.com/php-enqueue/enqueue-dev/tree/0.10.11) (2021-04-28) [Full Changelog](https://github.com/php-enqueue/enqueue-dev/compare/0.10.10...0.10.11) diff --git a/pkg/dbal/DbalContext.php b/pkg/dbal/DbalContext.php index 314db5dde..fc1f4a27a 100644 --- a/pkg/dbal/DbalContext.php +++ b/pkg/dbal/DbalContext.php @@ -238,6 +238,7 @@ public function createDataBaseTable(): void $table->addIndex(['redeliver_after', 'delivery_id']); $table->addIndex(['time_to_live', 'delivery_id']); + $table->addIndex(['delivery_id']); $sm->createTable($table); } diff --git a/pkg/sns/SnsContext.php b/pkg/sns/SnsContext.php index 454a5ddb5..a2de3f949 100644 --- a/pkg/sns/SnsContext.php +++ b/pkg/sns/SnsContext.php @@ -76,6 +76,11 @@ public function declareTopic(SnsDestination $destination): void $this->topicArns[$destination->getTopicName()] = (string) $result->get('TopicArn'); } + public function setTopicArn(SnsDestination $destination, string $arn): void + { + $this->topicArns[$destination->getTopicName()] = $arn; + } + public function deleteTopic(SnsDestination $destination): void { $this->client->deleteTopic($this->getTopicArn($destination)); diff --git a/pkg/snsqs/SnsQsContext.php b/pkg/snsqs/SnsQsContext.php index d520cdb10..14dbc5acd 100644 --- a/pkg/snsqs/SnsQsContext.php +++ b/pkg/snsqs/SnsQsContext.php @@ -53,11 +53,7 @@ public function __construct($snsContext, $sqsContext) } elseif (is_callable($snsContext)) { $this->snsContextFactory = $snsContext; } else { - throw new \InvalidArgumentException(sprintf( - 'The $snsContext argument must be either %s or callable that returns %s once called.', - SnsContext::class, - SnsContext::class - )); + throw new \InvalidArgumentException(sprintf('The $snsContext argument must be either %s or callable that returns %s once called.', SnsContext::class, SnsContext::class)); } if ($sqsContext instanceof SqsContext) { @@ -65,11 +61,7 @@ public function __construct($snsContext, $sqsContext) } elseif (is_callable($sqsContext)) { $this->sqsContextFactory = $sqsContext; } else { - throw new \InvalidArgumentException(sprintf( - 'The $sqsContext argument must be either %s or callable that returns %s once called.', - SqsContext::class, - SqsContext::class - )); + throw new \InvalidArgumentException(sprintf('The $sqsContext argument must be either %s or callable that returns %s once called.', SqsContext::class, SqsContext::class)); } } @@ -137,6 +129,11 @@ public function declareTopic(SnsQsTopic $topic): void $this->getSnsContext()->declareTopic($topic); } + public function setTopicArn(SnsQsTopic $topic, string $arn): void + { + $this->getSnsContext()->setTopicArn($topic, $arn); + } + public function deleteTopic(SnsQsTopic $topic): void { $this->getSnsContext()->deleteTopic($topic); @@ -181,11 +178,7 @@ private function getSnsContext(): SnsContext if (null === $this->snsContext) { $context = call_user_func($this->snsContextFactory); if (false == $context instanceof SnsContext) { - throw new \LogicException(sprintf( - 'The factory must return instance of %s. It returned %s', - SnsContext::class, - is_object($context) ? get_class($context) : gettype($context) - )); + throw new \LogicException(sprintf('The factory must return instance of %s. It returned %s', SnsContext::class, is_object($context) ? get_class($context) : gettype($context))); } $this->snsContext = $context; @@ -199,11 +192,7 @@ private function getSqsContext(): SqsContext if (null === $this->sqsContext) { $context = call_user_func($this->sqsContextFactory); if (false == $context instanceof SqsContext) { - throw new \LogicException(sprintf( - 'The factory must return instance of %s. It returned %s', - SqsContext::class, - is_object($context) ? get_class($context) : gettype($context) - )); + throw new \LogicException(sprintf('The factory must return instance of %s. It returned %s', SqsContext::class, is_object($context) ? get_class($context) : gettype($context))); } $this->sqsContext = $context; diff --git a/pkg/snsqs/SnsQsMessage.php b/pkg/snsqs/SnsQsMessage.php index e34a103ff..63a5c1d72 100644 --- a/pkg/snsqs/SnsQsMessage.php +++ b/pkg/snsqs/SnsQsMessage.php @@ -17,12 +17,27 @@ class SnsQsMessage implements Message */ private $sqsMessage; - public function __construct(string $body = '', array $properties = [], array $headers = []) - { + /** + * @var array|null + */ + private $messageAttributes; + + /** + * See AWS documentation for message attribute structure. + * + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#shape-messageattributevalue + */ + public function __construct( + string $body = '', + array $properties = [], + array $headers = [], + array $messageAttributes = null + ) { $this->body = $body; $this->properties = $properties; $this->headers = $headers; $this->redelivered = false; + $this->messageAttributes = $messageAttributes; } public function setSqsMessage(SqsMessage $message): void @@ -34,4 +49,14 @@ public function getSqsMessage(): SqsMessage { return $this->sqsMessage; } + + public function getMessageAttributes(): ?array + { + return $this->messageAttributes; + } + + public function setMessageAttributes(?array $messageAttributes): void + { + $this->messageAttributes = $messageAttributes; + } } diff --git a/pkg/snsqs/SnsQsProducer.php b/pkg/snsqs/SnsQsProducer.php index bdce7f895..99054286f 100644 --- a/pkg/snsqs/SnsQsProducer.php +++ b/pkg/snsqs/SnsQsProducer.php @@ -51,11 +51,7 @@ public function send(Destination $destination, Message $message): void InvalidMessageException::assertMessageInstanceOf($message, SnsQsMessage::class); if (false == $destination instanceof SnsQsTopic && false == $destination instanceof SnsQsQueue) { - throw new InvalidDestinationException(sprintf( - 'The destination must be an instance of [%s|%s] but got %s.', - SnsQsTopic::class, SnsQsQueue::class, - is_object($destination) ? get_class($destination) : gettype($destination) - )); + throw new InvalidDestinationException(sprintf('The destination must be an instance of [%s|%s] but got %s.', SnsQsTopic::class, SnsQsQueue::class, is_object($destination) ? get_class($destination) : gettype($destination))); } if ($destination instanceof SnsQsTopic) { @@ -64,6 +60,7 @@ public function send(Destination $destination, Message $message): void $message->getProperties(), $message->getHeaders() ); + $snsMessage->setMessageAttributes($message->getMessageAttributes()); $this->getSnsProducer()->send($destination, $snsMessage); } else { @@ -79,10 +76,6 @@ public function send(Destination $destination, Message $message): void /** * Delivery delay is supported by SQSProducer. - * - * @param int|null $deliveryDelay - * - * @return Producer */ public function setDeliveryDelay(int $deliveryDelay = null): Producer { @@ -93,8 +86,6 @@ public function setDeliveryDelay(int $deliveryDelay = null): Producer /** * Delivery delay is supported by SQSProducer. - * - * @return int|null */ public function getDeliveryDelay(): ?int { diff --git a/pkg/snsqs/Tests/SnsQsProducerTest.php b/pkg/snsqs/Tests/SnsQsProducerTest.php index d0925d15e..4444c888b 100644 --- a/pkg/snsqs/Tests/SnsQsProducerTest.php +++ b/pkg/snsqs/Tests/SnsQsProducerTest.php @@ -3,6 +3,7 @@ namespace Enqueue\SnsQs\Tests; use Enqueue\Sns\SnsContext; +use Enqueue\Sns\SnsMessage; use Enqueue\Sns\SnsProducer; use Enqueue\SnsQs\SnsQsMessage; use Enqueue\SnsQs\SnsQsProducer; @@ -91,6 +92,7 @@ public function testShouldGetDeliveryDelayFromSQSProducer() public function testShouldSendSnsTopicMessageToSnsProducer() { $snsMock = $this->createSnsContextMock(); + $snsMock->method('createMessage')->willReturn(new SnsMessage()); $destination = new SnsQsTopic(''); $snsProducerStub = $this->prophesize(SnsProducer::class); @@ -102,6 +104,26 @@ public function testShouldSendSnsTopicMessageToSnsProducer() $producer->send($destination, new SnsQsMessage()); } + public function testShouldSendSnsTopicMessageWithAttributesToSnsProducer() + { + $snsMock = $this->createSnsContextMock(); + $snsMock->method('createMessage')->willReturn(new SnsMessage()); + $destination = new SnsQsTopic(''); + + $snsProducerStub = $this->prophesize(SnsProducer::class); + $snsProducerStub->send( + $destination, + Argument::that(function (SnsMessage $snsMessage) { + return $snsMessage->getMessageAttributes() === ['foo' => 'bar']; + }) + )->shouldBeCalledOnce(); + + $snsMock->method('createProducer')->willReturn($snsProducerStub->reveal()); + + $producer = new SnsQsProducer($snsMock, $this->createSqsContextMock()); + $producer->send($destination, new SnsQsMessage('', [], [], ['foo' => 'bar'])); + } + public function testShouldSendSqsMessageToSqsProducer() { $sqsMock = $this->createSqsContextMock();