diff --git a/README.md b/README.md
index e5221a2..c2ef725 100644
--- a/README.md
+++ b/README.md
@@ -95,7 +95,10 @@ Is possible to configure the ACL for each action in the grid and the module conf
Two steps are necessary to configure the retry for a queue:
1. Configure the dead letter exchange
-2. Enable the message queue retry and declare the retry limit configuration
+1. Declare the retry limit xml configuration
+1. Enable the message queue retry admin configuration
+
+#### 1. Configuring the dead letter exchange
Let's imagine a scenario that the `erp_order_export` queue already exists in your project and to simplify the example the topic name, exchange name and queue name are the same: `erp_order_export`.
@@ -172,13 +175,29 @@ We added the `erp_order_export_delay` exchange and binding, it points to the ori
The `erp_order_export_delay` queue does not have a consumer, it will be used only to hold(delay) messages according with the period defined in the `x-message-ttl` argument.
-Now you have to define toggle the activation for the retry queue module and declare the retry limit for the queue:
+#### 2. Declaring the retry limit xml configuration
+
+Create the `Vendor_ModuleName/etc/queue_retry.xml` file with the content:
+
+```xml
+
+
+
+
+```
+
+#### 3. Enabling the message queue retry admin configuration
+
+Now you have to toggle the activation for the retry queue module:
System > Configuration > RUN-AS-ROOT > Message Queue Retry
-![img.png](docs/configuration.png)
+![img.png](docs/module-configuration.png)
-**Important note:** Make sure to configure the retry limit of your queue in the module configuration. If you configure the dead letter exchange and do not set the retry limit in the configuration(System > Configuration > RUN-AS-ROOT > Message Queue Retry), the message will be in a retry loop, that is, execute until the consumer process the message without throwing an exception. This is the default behavior for the RabbitMQ dead letter exchange and will work this way even if this module is not installed.
+**Important note:** Make sure to configure the retry limit of your queue with the `queue_retry.xml` file and enable the message queue retry configuration.
+If you configure the dead letter exchange and do not do the steps mentioned, the message will be in a retry loop. In other words, it will execute until the consumer processes the message without throwing an exception.
+This is the default behavior for the RabbitMQ dead letter exchange and will work this way even if this module is not installed.
For more information of how to configure message queues in Magento 2, you can take a look [here](https://developer.adobe.com/commerce/php/development/components/message-queues/configuration/).
diff --git a/docs/configuration.png b/docs/configuration.png
deleted file mode 100644
index 14d7258..0000000
Binary files a/docs/configuration.png and /dev/null differ
diff --git a/docs/module-configuration.png b/docs/module-configuration.png
new file mode 100644
index 0000000..52d6e84
Binary files /dev/null and b/docs/module-configuration.png differ
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index c887a21..98a6ce2 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -5,8 +5,6 @@ parameters:
excludePaths:
analyseAndScan:
- src/Test
- ignoreErrors:
- - '#Method .*construct\(\) has parameter \$data with no value type specified in iterable type array#'
includes:
- vendor/bitexpert/phpstan-magento/extension.neon
diff --git a/src/Block/Adminhtml/QueuesConfig.php b/src/Block/Adminhtml/QueuesConfig.php
deleted file mode 100644
index f4688cf..0000000
--- a/src/Block/Adminhtml/QueuesConfig.php
+++ /dev/null
@@ -1,27 +0,0 @@
-addColumn(
- MessageQueueRetryConfig::MAIN_TOPIC_NAME,
- [ 'label' => __('Main Topic Name'), 'class' => 'required-entry' ]
- );
-
- $this->addColumn(
- MessageQueueRetryConfig::RETRY_LIMIT,
- [ 'label' => __('Retry Limit'), 'class' => 'required-entry validate-zero-or-greater' ]
- );
-
- $this->_addAfter = false;
- $this->_addButtonLabel = 'Add';
- }
-}
diff --git a/src/Config/QueueRetryConfigInterface.php b/src/Config/QueueRetryConfigInterface.php
new file mode 100644
index 0000000..11337d4
--- /dev/null
+++ b/src/Config/QueueRetryConfigInterface.php
@@ -0,0 +1,15 @@
+>>
+ */
+ public function convert($source): array
+ {
+ $topics = [];
+
+ foreach ($source->getElementsByTagName('topic') as $topicNode) {
+ $topicAttributes = $topicNode->attributes;
+ $topicName = $topicAttributes->getNamedItem('name')?->nodeValue;
+ $retryLimit = (int)$topicAttributes->getNamedItem('retryLimit')?->nodeValue;
+
+ $topics[$topicName] = [
+ QueueRetryConfigInterface::TOPIC_NAME => $topicName,
+ QueueRetryConfigInterface::RETRY_LIMIT => $retryLimit,
+ ];
+ }
+
+ return [ QueueRetryConfigInterface::CONFIG_KEY_NAME => $topics ];
+ }
+}
diff --git a/src/Model/Config/Backend/QueuesConfig.php b/src/Model/Config/Backend/QueuesConfig.php
deleted file mode 100644
index f76b703..0000000
--- a/src/Model/Config/Backend/QueuesConfig.php
+++ /dev/null
@@ -1,59 +0,0 @@
- $value */
- $value = $this->getValue();
-
- if (!is_array($value)) {
- return parent::beforeSave();
- }
-
- $this->queueConfigurationValidator->validate($value);
-
- return parent::beforeSave();
- }
-}
diff --git a/src/Repository/Query/FindQueueRetryLimitByTopicNameQuery.php b/src/Repository/Query/FindQueueRetryLimitByTopicNameQuery.php
new file mode 100644
index 0000000..48b05d3
--- /dev/null
+++ b/src/Repository/Query/FindQueueRetryLimitByTopicNameQuery.php
@@ -0,0 +1,28 @@
+configStorage->get($configKey);
+
+ if (!$queueRetryTopic) {
+ return null;
+ }
+
+ $retryLimitKey = QueueRetryConfigInterface::RETRY_LIMIT;
+ return isset($queueRetryTopic[$retryLimitKey]) ? (int)$queueRetryTopic[$retryLimitKey] : null;
+ }
+}
diff --git a/src/SchemaLocator/QueueRetrySchemaLocator.php b/src/SchemaLocator/QueueRetrySchemaLocator.php
new file mode 100644
index 0000000..06c5d0f
--- /dev/null
+++ b/src/SchemaLocator/QueueRetrySchemaLocator.php
@@ -0,0 +1,26 @@
+urnResolver->getRealPath(QueueRetryConfigInterface::XSD_FILE_URN);
+ }
+
+ public function getPerFileSchema(): ?string
+ {
+ return $this->urnResolver->getRealPath(QueueRetryConfigInterface::XSD_FILE_URN);
+ }
+}
diff --git a/src/Service/IsMessageShouldBeSavedForRetryService.php b/src/Service/IsMessageShouldBeSavedForRetryService.php
index e53fc5c..edfe657 100644
--- a/src/Service/IsMessageShouldBeSavedForRetryService.php
+++ b/src/Service/IsMessageShouldBeSavedForRetryService.php
@@ -4,21 +4,19 @@
namespace RunAsRoot\MessageQueueRetry\Service;
-use JsonException;
use Magento\Framework\MessageQueue\EnvelopeInterface;
+use RunAsRoot\MessageQueueRetry\Repository\Query\FindQueueRetryLimitByTopicNameQuery;
use RunAsRoot\MessageQueueRetry\System\Config\MessageQueueRetryConfig;
class IsMessageShouldBeSavedForRetryService
{
public function __construct(
private MessageQueueRetryConfig $messageQueueRetryConfig,
- private GetMessageRetriesCountService $getMessageRetriesCountService
+ private GetMessageRetriesCountService $getMessageRetriesCountService,
+ private FindQueueRetryLimitByTopicNameQuery $findQueueRetryLimitByTopicNameQuery
) {
}
- /**
- * @throws JsonException
- */
public function execute(EnvelopeInterface $message): bool
{
if (!$this->messageQueueRetryConfig->isDelayQueueEnabled()) {
@@ -38,24 +36,12 @@ public function execute(EnvelopeInterface $message): bool
return false;
}
- $queueConfiguration = $this->getQueueConfiguration($topicName);
+ $retryLimit = $this->findQueueRetryLimitByTopicNameQuery->execute($topicName);
- if (!$queueConfiguration) {
+ if ($retryLimit === null) {
return false;
}
- $retryLimit = $queueConfiguration[MessageQueueRetryConfig::RETRY_LIMIT] ?? 0;
-
return $totalRetries >= $retryLimit;
}
-
- /**
- * @throws JsonException
- * @return array|null
- */
- private function getQueueConfiguration(string $topicName): ?array
- {
- $delayQueueConfiguration = $this->messageQueueRetryConfig->getDelayQueues();
- return $delayQueueConfiguration[$topicName] ?? null;
- }
}
diff --git a/src/System/Config/MessageQueueRetryConfig.php b/src/System/Config/MessageQueueRetryConfig.php
index 9d9bff6..651a02e 100644
--- a/src/System/Config/MessageQueueRetryConfig.php
+++ b/src/System/Config/MessageQueueRetryConfig.php
@@ -4,15 +4,10 @@
namespace RunAsRoot\MessageQueueRetry\System\Config;
-use JsonException;
use Magento\Framework\App\Config\ScopeConfigInterface;
class MessageQueueRetryConfig
{
- public const MAIN_TOPIC_NAME = 'main_topic_name';
- public const DELAY_TOPIC_NAME = 'delay_topic_name';
- public const RETRY_LIMIT = 'retry_limit';
- private const XML_PATH_DELAY_QUEUES = 'message_queue_retry/general/delay_queues';
private const XML_PATH_ENABLE_DELAY_QUEUE = 'message_queue_retry/general/enable_delay_queue';
public function __construct(private ScopeConfigInterface $scopeConfig)
@@ -23,33 +18,4 @@ public function isDelayQueueEnabled(): bool
{
return $this->scopeConfig->isSetFlag(self::XML_PATH_ENABLE_DELAY_QUEUE);
}
-
- /**
- * @return array>
- * @throws JsonException
- */
- public function getDelayQueues(): array
- {
- $configValues = $this->scopeConfig->getValue(self::XML_PATH_DELAY_QUEUES);
-
- if (!$configValues) {
- return [];
- }
-
- $configValues = json_decode($configValues, true, 512, JSON_THROW_ON_ERROR);
-
- $result = [];
-
- foreach ($configValues as $configValue) {
- $mainTopicName = $configValue[self::MAIN_TOPIC_NAME] ?? null;
- $retryLimit = isset($configValue[self::RETRY_LIMIT]) ? (int)$configValue[self::RETRY_LIMIT] : null;
- $result[$mainTopicName] = [
- self::MAIN_TOPIC_NAME => $mainTopicName,
- self::DELAY_TOPIC_NAME => $configValue[self::DELAY_TOPIC_NAME] ?? null,
- self::RETRY_LIMIT => $retryLimit,
- ];
- }
-
- return $result;
- }
}
diff --git a/src/Test/Unit/Converter/QueueRetryXmlToArrayConverterTest.php b/src/Test/Unit/Converter/QueueRetryXmlToArrayConverterTest.php
new file mode 100644
index 0000000..5d5a2ae
--- /dev/null
+++ b/src/Test/Unit/Converter/QueueRetryXmlToArrayConverterTest.php
@@ -0,0 +1,44 @@
+sut = new QueueRetryXmlToArrayConverter();
+ }
+
+ public function testConvert(): void
+ {
+ $doc = new \DOMDocument();
+ $doc->loadXML($this->getQueueRetryXmlFile());
+
+ $result = $this->sut->convert($doc);
+
+ $expected = [
+ 'queue_retry_topics' => [
+ 'sample_topic' => [
+ 'topic_name' => 'sample_topic',
+ 'retry_limit' => 3,
+ ],
+ 'another_topic' => [
+ 'topic_name' => 'another_topic',
+ 'retry_limit' => 10,
+ ],
+ ],
+ ];
+
+ $this->assertEquals($expected, $result);
+ }
+
+ public function getQueueRetryXmlFile(): string
+ {
+ return file_get_contents(__DIR__ . '/_files/queue_retry.xml');
+ }
+}
diff --git a/src/Test/Unit/Converter/_files/queue_retry.xml b/src/Test/Unit/Converter/_files/queue_retry.xml
new file mode 100644
index 0000000..17246ed
--- /dev/null
+++ b/src/Test/Unit/Converter/_files/queue_retry.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/src/Test/Unit/Model/Config/Backend/QueuesConfigTest.php b/src/Test/Unit/Model/Config/Backend/QueuesConfigTest.php
deleted file mode 100644
index 1a1d3e9..0000000
--- a/src/Test/Unit/Model/Config/Backend/QueuesConfigTest.php
+++ /dev/null
@@ -1,54 +0,0 @@
-createMock(Context::class);
- $eventManagerMock = $this->createMock(ManagerInterface::class);
- $contextMock->expects($this->once())->method('getEventDispatcher')->willReturn($eventManagerMock);
- $registryMock = $this->createMock(Registry::class);
- $configMock = $this->createMock(ScopeConfigInterface::class);
- $cacheTypeListMock = $this->createMock(TypeListInterface::class);
- $abstractResourceMock = $this->createMock(AbstractResource::class);
- $abstractDbMock = $this->createMock(AbstractDb::class);
- $this->queueConfigurationValidatorMock = $this->createMock(QueueConfigurationValidator::class);
- $this->sut = new QueuesConfig(
- $contextMock,
- $registryMock,
- $configMock,
- $cacheTypeListMock,
- $this->queueConfigurationValidatorMock,
- $abstractResourceMock,
- $abstractDbMock
- );
- }
-
- public function testBeforeSave(): void
- {
- $this->sut->setValue([]);
-
- $this->queueConfigurationValidatorMock->expects($this->once())->method('validate')->with([]);
-
- $this->sut->beforeSave();
- }
-}
diff --git a/src/Test/Unit/Repository/Query/FindQueueRetryLimitByTopicNameQueryTest.php b/src/Test/Unit/Repository/Query/FindQueueRetryLimitByTopicNameQueryTest.php
new file mode 100644
index 0000000..99b3e59
--- /dev/null
+++ b/src/Test/Unit/Repository/Query/FindQueueRetryLimitByTopicNameQueryTest.php
@@ -0,0 +1,43 @@
+configStorageMock = $this->createMock(DataInterface::class);
+ $this->sut = new FindQueueRetryLimitByTopicNameQuery($this->configStorageMock);
+ }
+
+ /**
+ * @dataProvider dataProvider
+ */
+ public function testExecute($expected, $topicName, $config): void
+ {
+ $configKey = QueueRetryConfigInterface::CONFIG_KEY_NAME . '/' . $topicName;
+ $this->configStorageMock->expects($this->once())->method('get')->with($configKey)->willReturn($config);
+
+ $result = $this->sut->execute($topicName);
+
+ $this->assertEquals($expected, $result);
+ }
+
+ public function dataProvider(): array
+ {
+ return [
+ [3, 'sample_topic', ['retry_limit' => '3']],
+ [null, 'sample_topic', ['some_key' => '3']],
+ [null, 'sample_topic', null],
+ ];
+ }
+}
diff --git a/src/Test/Unit/SchemaLocator/QueueRetrySchemaLocatorTest.php b/src/Test/Unit/SchemaLocator/QueueRetrySchemaLocatorTest.php
new file mode 100644
index 0000000..076fcc4
--- /dev/null
+++ b/src/Test/Unit/SchemaLocator/QueueRetrySchemaLocatorTest.php
@@ -0,0 +1,43 @@
+urnResolverMock = $this->createMock(UrnResolver::class);
+ $this->sut = new QueueRetrySchemaLocator($this->urnResolverMock);
+ }
+
+ public function testGetSchema(): void
+ {
+ $urn = QueueRetryConfigInterface::XSD_FILE_URN;
+ $realPath = 'some-path';
+ $this->urnResolverMock->expects($this->once())->method('getRealPath')->with($urn)->willReturn($realPath);
+
+ $result = $this->sut->getSchema();
+
+ $this->assertEquals($realPath, $result);
+ }
+
+ public function testGetPerFileSchema(): void
+ {
+ $urn = QueueRetryConfigInterface::XSD_FILE_URN;
+ $realPath = 'some-path';
+ $this->urnResolverMock->expects($this->once())->method('getRealPath')->with($urn)->willReturn($realPath);
+
+ $result = $this->sut->getPerFileSchema();
+
+ $this->assertEquals($realPath, $result);
+ }
+}
diff --git a/src/Test/Unit/Service/GetMessageRetriesCountServiceTest.php b/src/Test/Unit/Service/GetMessageRetriesCountServiceTest.php
index 9024f51..a430222 100644
--- a/src/Test/Unit/Service/GetMessageRetriesCountServiceTest.php
+++ b/src/Test/Unit/Service/GetMessageRetriesCountServiceTest.php
@@ -11,6 +11,13 @@
final class GetMessageRetriesCountServiceTest extends TestCase
{
+ private GetMessageRetriesCountService $sut;
+
+ protected function setUp(): void
+ {
+ $this->sut = new GetMessageRetriesCountService();
+ }
+
public function testItGetsMessageRetriesCount(): void
{
$testRetriesCount = 3;
@@ -21,10 +28,9 @@ public function testItGetsMessageRetriesCount(): void
$messageProperties = ['application_headers' => $applicationHeaders, 'topic_name' => $topicName];
$messageMock->expects($this->once())->method('getProperties')->willReturn($messageProperties);
- $sut = new GetMessageRetriesCountService();
- $retriesCount = $sut->execute($messageMock);
+ $retriesCount = $this->sut->execute($messageMock);
- self::assertEquals($testRetriesCount, $retriesCount);
+ $this->assertEquals($testRetriesCount, $retriesCount);
}
public function testItReturnsZeroAfterFirstProcessingBecauseItIsNotRetry(): void
@@ -33,9 +39,21 @@ public function testItReturnsZeroAfterFirstProcessingBecauseItIsNotRetry(): void
$messageProperties = [ ];
$messageMock->expects($this->once())->method('getProperties')->willReturn($messageProperties);
- $sut = new GetMessageRetriesCountService();
- $retriesCount = $sut->execute($messageMock);
+ $retriesCount = $this->sut->execute($messageMock);
+
+ $this->assertEquals(0, $retriesCount);
+ }
+
+ public function testItReturnsZeroAsFallback(): void
+ {
+ $messageMock = $this->createMock(Envelope::class);
+ $applicationHeaders = new AMQPTable(['x-death' => [['count' => null]]]);
+ $topicName = 'sample_topic';
+ $messageProperties = ['application_headers' => $applicationHeaders, 'topic_name' => $topicName];
+ $messageMock->expects($this->once())->method('getProperties')->willReturn($messageProperties);
+
+ $retriesCount = $this->sut->execute($messageMock);
- self::assertEquals(0, $retriesCount);
+ $this->assertEquals(0, $retriesCount);
}
}
diff --git a/src/Test/Unit/Service/IsMessageShouldBeSavedForRetryServiceTest.php b/src/Test/Unit/Service/IsMessageShouldBeSavedForRetryServiceTest.php
index e14dcbd..d39c752 100644
--- a/src/Test/Unit/Service/IsMessageShouldBeSavedForRetryServiceTest.php
+++ b/src/Test/Unit/Service/IsMessageShouldBeSavedForRetryServiceTest.php
@@ -7,36 +7,39 @@
use Magento\Framework\MessageQueue\Envelope;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
+use RunAsRoot\MessageQueueRetry\Repository\Query\FindQueueRetryLimitByTopicNameQuery;
use RunAsRoot\MessageQueueRetry\Service\GetMessageRetriesCountService;
use RunAsRoot\MessageQueueRetry\Service\IsMessageShouldBeSavedForRetryService;
use RunAsRoot\MessageQueueRetry\System\Config\MessageQueueRetryConfig;
final class IsMessageShouldBeSavedForRetryServiceTest extends TestCase
{
+ private IsMessageShouldBeSavedForRetryService $sut;
private MessageQueueRetryConfig|MockObject $messageQueueRetryConfigMock;
private GetMessageRetriesCountService|MockObject $getMessageRetriesCountServiceMock;
- private IsMessageShouldBeSavedForRetryService $sut;
+ private FindQueueRetryLimitByTopicNameQuery|MockObject $findQueueRetryLimitByTopicNameQueryMock;
protected function setUp(): void
{
$this->messageQueueRetryConfigMock = $this->createMock(MessageQueueRetryConfig::class);
$this->getMessageRetriesCountServiceMock = $this->createMock(GetMessageRetriesCountService::class);
-
- $this->messageQueueRetryConfigMock->method('isDelayQueueEnabled')->willReturn(true);
+ $this->findQueueRetryLimitByTopicNameQueryMock = $this->createMock(FindQueueRetryLimitByTopicNameQuery::class);
$this->sut = new IsMessageShouldBeSavedForRetryService(
$this->messageQueueRetryConfigMock,
- $this->getMessageRetriesCountServiceMock
+ $this->getMessageRetriesCountServiceMock,
+ $this->findQueueRetryLimitByTopicNameQueryMock
);
}
public function testItReturnsTrueIfRetryLimitIsReached(): void
{
$testMessageProperties = ['topic_name' => 'sample_topic'];
- $testQueueConfiguration = ['sample_topic' => ['retry_limit' => 2]];
+ $this->messageQueueRetryConfigMock->method('isDelayQueueEnabled')->willReturn(true);
$this->getMessageRetriesCountServiceMock->expects($this->once())->method('execute')->willReturn(2);
- $this->messageQueueRetryConfigMock->expects($this->once())->method('getDelayQueues')->willReturn($testQueueConfiguration);
+ $this->findQueueRetryLimitByTopicNameQueryMock->expects($this->once())->method('execute')
+ ->with('sample_topic')->willReturn(2);
$result = $this->sut->execute(new Envelope('', $testMessageProperties));
$this->assertTrue($result);
@@ -45,10 +48,11 @@ public function testItReturnsTrueIfRetryLimitIsReached(): void
public function testItReturnsFalseIfRetryLimitIsNotReached(): void
{
$testMessageProperties = ['topic_name' => 'sample_topic'];
- $testQueueConfiguration = ['sample_topic' => ['retry_limit' => 2]];
+ $this->messageQueueRetryConfigMock->method('isDelayQueueEnabled')->willReturn(true);
$this->getMessageRetriesCountServiceMock->expects($this->once())->method('execute')->willReturn(1);
- $this->messageQueueRetryConfigMock->expects($this->once())->method('getDelayQueues')->willReturn($testQueueConfiguration);
+ $this->findQueueRetryLimitByTopicNameQueryMock->expects($this->once())->method('execute')
+ ->with('sample_topic')->willReturn(2);
$result = $this->sut->execute(new Envelope('', $testMessageProperties));
$this->assertFalse($result);
@@ -57,22 +61,11 @@ public function testItReturnsFalseIfRetryLimitIsNotReached(): void
public function testItReturnsFalseIfQueueConfigHasNoRetryLimit(): void
{
$testMessageProperties = ['topic_name' => 'sample_topic'];
- $testQueueConfiguration = ['sample_topic' => []];
-
- $this->getMessageRetriesCountServiceMock->expects($this->once())->method('execute')->willReturn(1);
- $this->messageQueueRetryConfigMock->expects($this->once())->method('getDelayQueues')->willReturn($testQueueConfiguration);
-
- $result = $this->sut->execute(new Envelope('', $testMessageProperties));
- $this->assertFalse($result);
- }
-
- public function testItReturnsFalseIfQueueIsNotConfigured(): void
- {
- $testMessageProperties = ['topic_name' => 'sample_topic'];
- $testQueueConfiguration = ['another_topic' => ['retry_limit' => 1]];
+ $this->messageQueueRetryConfigMock->method('isDelayQueueEnabled')->willReturn(true);
$this->getMessageRetriesCountServiceMock->expects($this->once())->method('execute')->willReturn(1);
- $this->messageQueueRetryConfigMock->expects($this->once())->method('getDelayQueues')->willReturn($testQueueConfiguration);
+ $this->findQueueRetryLimitByTopicNameQueryMock->expects($this->once())->method('execute')
+ ->with('sample_topic')->willReturn(null);
$result = $this->sut->execute(new Envelope('', $testMessageProperties));
$this->assertFalse($result);
@@ -80,6 +73,7 @@ public function testItReturnsFalseIfQueueIsNotConfigured(): void
public function testItReturnsFalseIfMessageHasNoTopicName(): void
{
+ $this->messageQueueRetryConfigMock->method('isDelayQueueEnabled')->willReturn(true);
$this->getMessageRetriesCountServiceMock->expects($this->once())->method('execute')->willReturn(1);
$result = $this->sut->execute(new Envelope('', []));
@@ -88,6 +82,7 @@ public function testItReturnsFalseIfMessageHasNoTopicName(): void
public function testItReturnsFalseIfItIsFirstTimeConsuming(): void
{
+ $this->messageQueueRetryConfigMock->method('isDelayQueueEnabled')->willReturn(true);
$this->getMessageRetriesCountServiceMock->expects($this->once())->method('execute')->willReturn(0);
$result = $this->sut->execute(new Envelope('', []));
@@ -96,9 +91,7 @@ public function testItReturnsFalseIfItIsFirstTimeConsuming(): void
public function testItReturnsFalseIfConfigDisabled(): void
{
- $this->messageQueueRetryConfigMock->expects($this->once())
- ->method('isDelayQueueEnabled')
- ->willReturn(false);
+ $this->messageQueueRetryConfigMock->expects($this->once())->method('isDelayQueueEnabled')->willReturn(false);
$result = $this->sut->execute(new Envelope('', []));
$this->assertFalse($result);
diff --git a/src/Test/Unit/System/Config/MessageQueueRetryConfigTest.php b/src/Test/Unit/System/Config/MessageQueueRetryConfigTest.php
index 803825c..d55c348 100644
--- a/src/Test/Unit/System/Config/MessageQueueRetryConfigTest.php
+++ b/src/Test/Unit/System/Config/MessageQueueRetryConfigTest.php
@@ -24,28 +24,4 @@ public function testIsDelayQueueEnabled(): void
$this->scopeConfigMock->expects($this->once())->method('isSetFlag')->with($configPath)->willReturn(true);
$this->assertTrue($this->sut->isDelayQueueEnabled());
}
-
- public function testGetDelayQueues(): void
- {
- $configPath = 'message_queue_retry/general/delay_queues';
- $configValues = $this->getDelayQueuesJson();
- $this->scopeConfigMock->expects($this->once())->method('getValue')->with($configPath)->willReturn($configValues);
-
- $result = $this->sut->getDelayQueues();
-
- $expected = [
- 'sample_topic' => [
- 'main_topic_name' => 'sample_topic',
- 'delay_topic_name' => 'sample_topic_delay',
- 'retry_limit' => 3,
- ],
- ];
-
- $this->assertEquals($expected, $result);
- }
-
- private function getDelayQueuesJson(): string
- {
- return trim(file_get_contents(__DIR__ . '/_files/delay_queues_config.json'));
- }
}
diff --git a/src/Test/Unit/System/Config/_files/delay_queues_config.json b/src/Test/Unit/System/Config/_files/delay_queues_config.json
deleted file mode 100644
index 506c03f..0000000
--- a/src/Test/Unit/System/Config/_files/delay_queues_config.json
+++ /dev/null
@@ -1 +0,0 @@
-{"_1677026917539_539":{"main_topic_name":"sample_topic","delay_topic_name":"sample_topic_delay","retry_limit":"3"}}
diff --git a/src/Test/Unit/Validator/QueueConfigurationValidatorTest.php b/src/Test/Unit/Validator/QueueConfigurationValidatorTest.php
deleted file mode 100644
index e517cee..0000000
--- a/src/Test/Unit/Validator/QueueConfigurationValidatorTest.php
+++ /dev/null
@@ -1,100 +0,0 @@
-sut = new QueueConfigurationValidator();
- }
-
- /**
- * @dataProvider validConfigDataProvider
- */
- public function testValidConfig(array $configValues): void
- {
- $this->assertTrue($this->sut->validate($configValues));
- }
-
- /**
- * @dataProvider invalidConfigDataProvider
- */
- public function testInvalidConfig(array $configValues): void
- {
- $this->expectException(InvalidQueueConfigurationException::class);
-
- $this->sut->validate($configValues);
- }
-
- public function validConfigDataProvider(): array
- {
- return [
- [
- [
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => 'topic1',
- ConfigFieldNames::DELAY_TOPIC_NAME => 'topic2',
- ],
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => 'topic3',
- ConfigFieldNames::DELAY_TOPIC_NAME => null,
- ],
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => null,
- ConfigFieldNames::DELAY_TOPIC_NAME => 'topic4',
- ],
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => null,
- ConfigFieldNames::DELAY_TOPIC_NAME => null,
- ],
- ],
- ],
- ];
- }
-
- public function invalidConfigDataProvider(): array
- {
- return [
- [
- [
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => 'topic1',
- ConfigFieldNames::DELAY_TOPIC_NAME => 'topic2',
- ],
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => 'topic1',
- ConfigFieldNames::DELAY_TOPIC_NAME => 'topic3',
- ],
- ]
- ],
- [
- [
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => 'topic1',
- ConfigFieldNames::DELAY_TOPIC_NAME => 'topic2',
- ],
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => 'topic3',
- ConfigFieldNames::DELAY_TOPIC_NAME => 'topic2',
- ],
- ]
- ],
- [
- [
- [
- ConfigFieldNames::MAIN_TOPIC_NAME => 'topic1',
- ConfigFieldNames::DELAY_TOPIC_NAME => 'topic1',
- ],
- ]
- ],
- ];
- }
-}
diff --git a/src/Validator/QueueConfigurationValidator.php b/src/Validator/QueueConfigurationValidator.php
deleted file mode 100644
index d543bd7..0000000
--- a/src/Validator/QueueConfigurationValidator.php
+++ /dev/null
@@ -1,68 +0,0 @@
- $configValues
- * @throws InvalidQueueConfigurationException
- */
- public function validate(array $configValues): bool
- {
- $this->performUniqueValidation($configValues, ConfigFieldNames::MAIN_TOPIC_NAME, 'Main');
- $this->performUniqueValidation($configValues, ConfigFieldNames::DELAY_TOPIC_NAME, 'Delay');
-
- foreach ($configValues as $configValue) {
- $mainTopicName = $configValue[ConfigFieldNames::MAIN_TOPIC_NAME] ?? null;
- $delayTopicName = $configValue[ConfigFieldNames::DELAY_TOPIC_NAME] ?? null;
-
- if ($mainTopicName === null && $delayTopicName === null) {
- continue;
- }
-
- if ($mainTopicName === $delayTopicName) {
- throw new InvalidQueueConfigurationException(
- new Phrase(
- 'The main topic name "%1" and delay topic name "%2" cannot be the same.',
- [ $mainTopicName, $delayTopicName ]
- )
- );
- }
- }
-
- return true;
- }
-
- /**
- * @param array $configValues
- * @throws InvalidQueueConfigurationException
- */
- private function performUniqueValidation(array $configValues, string $field, string $name): void
- {
- $topicNames = [];
-
- foreach ($configValues as $configValue) {
- if (!isset($configValue[$field])) {
- continue;
- }
-
- if (in_array($configValue[$field], $topicNames)) {
- throw new InvalidQueueConfigurationException(
- new Phrase(
- '%1 topic name "%2" is already used.',
- [ $name, $configValue[$field] ]
- )
- );
- }
-
- $topicNames[] = $configValue[$field];
- }
- }
-}
diff --git a/src/etc/adminhtml/system.xml b/src/etc/adminhtml/system.xml
index 77c4fa1..5715d31 100644
--- a/src/etc/adminhtml/system.xml
+++ b/src/etc/adminhtml/system.xml
@@ -22,16 +22,6 @@
default Magento behavior will run instead.
-
-
- RunAsRoot\MessageQueueRetry\Block\Adminhtml\QueuesConfig
- RunAsRoot\MessageQueueRetry\Model\Config\Backend\QueuesConfig
-
- Please, provide the topic name of the queue that is within the communication.xml file.
- After the retry limit is reached the message will be sent to the failed messages grid.
-
-
diff --git a/src/etc/di.xml b/src/etc/di.xml
index f0bc341..c1e979c 100644
--- a/src/etc/di.xml
+++ b/src/etc/di.xml
@@ -2,7 +2,8 @@
-
+
@@ -24,4 +25,30 @@
+
+
+ RunAsRootQueueRetryDataStorage
+
+
+
+
+ RunAsRootQueueRetryReader
+
+ RunAsRoot\MessageQueueRetry\Config\QueueRetryConfigInterface::CACHE_KEY
+
+
+
+
+
+
+ RunAsRoot\MessageQueueRetry\Config\QueueRetryConfigInterface::FILE_NAME
+
+
+ RunAsRoot\MessageQueueRetry\Converter\QueueRetryXmlToArrayConverter
+
+
+ RunAsRoot\MessageQueueRetry\SchemaLocator\QueueRetrySchemaLocator
+
+
+
diff --git a/src/etc/queue_retry.xsd b/src/etc/queue_retry.xsd
new file mode 100644
index 0000000..7c3a769
--- /dev/null
+++ b/src/etc/queue_retry.xsd
@@ -0,0 +1,33 @@
+
+
+
+
+ retryLimit must contain value greater than or equal to 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Topic name must be unique.
+
+
+
+
+
+
+