diff --git a/app/code/Magento/Ui/etc/di.xml b/app/code/Magento/Ui/etc/di.xml index b0cef3b90d431..643f6503d1454 100644 --- a/app/code/Magento/Ui/etc/di.xml +++ b/app/code/Magento/Ui/etc/di.xml @@ -256,6 +256,7 @@ arrayArgumentInterpreterProxy Magento\Framework\Data\Argument\Interpreter\Boolean Magento\Framework\Data\Argument\Interpreter\Number + Magento\Framework\Data\Argument\Interpreter\Integer Magento\Framework\Data\Argument\Interpreter\StringUtils Magento\Framework\Data\Argument\Interpreter\NullType Magento\Ui\Config\Argument\Parser\Url diff --git a/app/etc/di.xml b/app/etc/di.xml index 585c88f68ff6f..bc8e5255704c3 100644 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -479,6 +479,7 @@ layoutArrayArgumentReaderInterpreterProxy Magento\Framework\Data\Argument\Interpreter\Boolean Magento\Framework\Data\Argument\Interpreter\Number + Magento\Framework\Data\Argument\Interpreter\Integer Magento\Framework\Data\Argument\Interpreter\StringUtils Magento\Framework\Data\Argument\Interpreter\NullType Magento\Framework\View\Layout\Argument\Interpreter\Passthrough diff --git a/lib/internal/Magento/Framework/App/ObjectManagerFactory.php b/lib/internal/Magento/Framework/App/ObjectManagerFactory.php index 0c468a767ded2..c109750d83385 100644 --- a/lib/internal/Magento/Framework/App/ObjectManagerFactory.php +++ b/lib/internal/Magento/Framework/App/ObjectManagerFactory.php @@ -231,6 +231,7 @@ protected function createArgumentInterpreter( 'boolean' => new \Magento\Framework\Data\Argument\Interpreter\Boolean($booleanUtils), 'string' => new \Magento\Framework\Data\Argument\Interpreter\BaseStringUtils($booleanUtils), 'number' => new \Magento\Framework\Data\Argument\Interpreter\Number(), + 'int' => new \Magento\Framework\Data\Argument\Interpreter\Integer(), 'null' => new \Magento\Framework\Data\Argument\Interpreter\NullType(), 'object' => new \Magento\Framework\Data\Argument\Interpreter\DataObject($booleanUtils), 'const' => $constInterpreter, diff --git a/lib/internal/Magento/Framework/Data/Argument/Interpreter/Integer.php b/lib/internal/Magento/Framework/Data/Argument/Interpreter/Integer.php new file mode 100644 index 0000000000000..a87096cedaecf --- /dev/null +++ b/lib/internal/Magento/Framework/Data/Argument/Interpreter/Integer.php @@ -0,0 +1,28 @@ + + + + + + + diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Data.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Data.php index 6711428f06654..5e05597918717 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Data.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Data.php @@ -23,4 +23,20 @@ public function __construct( ) { parent::__construct($reader, $cache, $cacheId, $serializer); } + + public function getQueues(): array { + return array_filter($this->get(),function($item){ + if($item['type'] == 'queue'){ + return $item; + } + }); + } + + public function getExchanges(): array { + return array_filter($this->get(),function($item){ + if($item['type'] != 'queue'){ + return $item; + } + }); + } } diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem.php index b767a516833af..6c966ef444fd7 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem.php @@ -7,6 +7,8 @@ use Magento\Framework\MessageQueue\Topology\Config\ExchangeConfigItem\BindingInterface; use Magento\Framework\MessageQueue\Topology\Config\ExchangeConfigItem\Binding\IteratorFactory; +use Magento\Framework\MessageQueue\Topology\Config\ExchangeConfigItem\Binding\Iterator; +use Magento\Framework\MessageQueue\Topology\Config\ExchangeConfigItem\BindingFactory; /** * {@inheritdoc} @@ -37,7 +39,7 @@ class ExchangeConfigItem implements ExchangeConfigItemInterface /** * Exchange bindings. * - * @var BindingInterface[] + * @var Iterator */ private $bindings; @@ -69,6 +71,11 @@ class ExchangeConfigItem implements ExchangeConfigItemInterface */ private $isInternal; + /** + * @var BindingFactory + */ + public $bindingFactory; + /** * Initialize dependencies. * @@ -158,6 +165,11 @@ public function setData(array $data) $this->isDurable = $data['durable']; $this->isAutoDelete = $data['autoDelete']; $this->arguments = $data['arguments']; - $this->bindings->setData($data['bindings']); + if( $this->type != 'queue'){ + $this->bindings->setData($data['bindings']); + } + else{ + $this->bindings->setData([]); + } } } diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem/Iterator.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem/Iterator.php index 85dad637191fe..29f922d87bb85 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem/Iterator.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem/Iterator.php @@ -36,7 +36,7 @@ class Iterator implements \Iterator, \ArrayAccess */ public function __construct(Data $configData, ExchangeConfigItemFactory $itemFactory) { - $this->data = $configData->get(); + $this->data = $configData->getExchanges(); $this->object = $itemFactory->create(); $this->rewind(); } diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/QueueConfigItem/DataMapper.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/QueueConfigItem/DataMapper.php index 7e8d35fb0940f..0c351596927b3 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/QueueConfigItem/DataMapper.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/QueueConfigItem/DataMapper.php @@ -1,8 +1,10 @@ mappedData) { $this->mappedData = []; - foreach ($this->configData->get() as $exchange) { + + $queues = $this->createQueueItemsFromQueues($this->configData->getQueues()); + foreach ($queues as $key => $value) { + $this->mappedData[$key] = $value; + } + foreach ($this->configData->getExchanges() as $exchange) { $connection = $exchange['connection']; foreach ($exchange['bindings'] as $binding) { - if ($binding['destinationType'] === 'queue') { + if ($binding['destinationType'] === 'queue' && !array_key_exists($binding['destination'] . '--' . $connection, $this->mappedData)) { $queueItems = $this->createQueueItems($binding['destination'], $binding['topic'], $connection); $this->mappedData = array_merge($this->mappedData, $queueItems); } } } } + return $this->mappedData; } @@ -83,13 +91,54 @@ public function getMappedData() * @param string $name * @param string $topic * @param string $connection + * @deprecated * @return array */ private function createQueueItems($name, $topic, $connection) + { + return $this->createQueueItemsFromTopic($name, $topic, $connection); + } + + private function createQueueItemsFromQueues(array $queues) { $output = []; - $synchronousTopics = []; + foreach ($queues as $queue) { + $output[$queue['name'] . '--' . $queue['connection']] = + $this->createQueue( + $queue['name'], + $queue['connection'], + $queue['arguments'], + $queue['durable'], + $queue['autoDelete'] + ); + } + return $output; + } + private function createQueue($name, $connection, $arguments = [], $durable = true, $autoDelete = false) + { + return [ + 'name' => $name, + 'connection' => $connection, + 'durable' => isset($durable) ? $durable : true, + 'autoDelete' => isset($autoDelete) ? $autoDelete : false, + 'arguments' => isset($arguments) ? $arguments : [], + ]; + } + + /** + * Create queue config item. + * + * @param string $name + * @param string $topic + * @param string $connection + * @return array + */ + private function createQueueItemsFromTopic($name, $topic, $connection) + { + $output = []; + $synchronousTopics = []; + if (strpos($topic, '*') !== false || strpos($topic, '#') !== false) { $synchronousTopics = $this->matchSynchronousTopics($topic); } elseif ($this->isSynchronousTopic($topic)) { diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/DependentFields.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/DependentFields.php index fcf10053e4148..cf65b30050bc8 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/DependentFields.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/DependentFields.php @@ -1,8 +1,10 @@ $data) { - foreach ((array)$data['bindings'] as $binding) { - if (isset($data['type']) && $data['type'] == 'topic' && !isset($binding['topic'])) { - $errors[] = 'Topic name is required for topic based exchange: ' . $name; + if ($data['type'] != 'queue') { + foreach ((array)$data['bindings'] as $binding) { + if (isset($data['type']) && $data['type'] == 'topic' && !isset($binding['topic'])) { + $errors[] = 'Topic name is required for topic based exchange: ' . $name; + } } } } diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/FieldsTypes.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/FieldsTypes.php index 2e1cf52ee4cbe..ecd3565cf30e0 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/FieldsTypes.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/FieldsTypes.php @@ -18,7 +18,8 @@ class FieldsTypes implements ValidatorInterface public function validate($configData) { foreach ($configData as $exchangeName => $exchangeConfig) { - $this->validateFieldsTypes($exchangeName, $exchangeConfig); + $exchangeConfig['type'] != 'queue' ? + $this->validateFieldsTypes($exchangeName, $exchangeConfig) : $this->validateQueueTypes($exchangeName, $exchangeConfig); } } @@ -128,4 +129,16 @@ private function validateBindings($exchangeName, $exchangeConfig, $bindingFields } } } + + /** + * Make sure types of all fields in the queue item config are correct. + * + * @param string $queueName + * @param array $queueConfig + * @return void + * @throws \LogicException + */ + private function validateQueueTypes($queueName, $queueConfig) + { + } } diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/Format.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/Format.php index 50acb6cbd5fc3..c8725a5c6289e 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/Format.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Validator/Format.php @@ -1,8 +1,10 @@ $data) { - $diff = array_diff($requiredFields, array_keys($data)); - foreach ($diff as $field) { - $errors[] = sprintf('Missing [%s] field for exchange %s.', $field, $name); - } + if ($data['type'] != 'queue') { + $diff = array_diff($requiredExchangeFields, array_keys($data)); + foreach ($diff as $field) { + $errors[] = sprintf('Missing [%s] field for exchange %s.', $field, $name); + } - if (!array_key_exists('bindings', $data) || !is_array($data['bindings'])) { - $errors[] = sprintf('Invalid bindings format for exchange %s.', $name); - continue; - } + if (!array_key_exists('bindings', $data) || !is_array($data['bindings'])) { + $errors[] = sprintf('Invalid bindings format for exchange %s.', $name); + continue; + } - foreach ($data['bindings'] as $bindingConfig) { - $diff = array_diff($requiredBindingFields, array_keys($bindingConfig)); + foreach ($data['bindings'] as $bindingConfig) { + $diff = array_diff($requiredBindingFields, array_keys($bindingConfig)); + foreach ($diff as $field) { + $errors[] = sprintf('Missing [%s] field for binding %s in exchange config.', $field, $name); + } + } + } + else{ + $diff = array_diff($requiredQueueFields, array_keys($data)); foreach ($diff as $field) { - $errors[] = sprintf('Missing [%s] field for binding %s in exchange config.', $field, $name); + $errors[] = sprintf('Missing [%s] field for queue %s.', $field, $name); } } } diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Xml/Converter.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Xml/Converter.php index 516a4f080973f..e67dae9d25e54 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Xml/Converter.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Xml/Converter.php @@ -99,6 +99,41 @@ public function convert($source) 'arguments' => $exchangeArguments, ]; } + + foreach ($source->getElementsByTagName('queue') as $queue) { + $name = $this->getAttributeValue($queue, 'name'); + $connection = $this->getAttributeValue($queue, 'connection'); + + $bindings = []; + $queueArguments = []; + /** @var \DOMNode $node */ + foreach ($queue->childNodes as $node) { + if (!in_array($node->nodeName, ['binding', 'arguments']) || $node->nodeType != XML_ELEMENT_NODE) { + continue; + } + switch ($node->nodeName) { + case 'binding': + $bindings = $this->processBindings($node, $bindings); + break; + + case 'arguments': + $queueArguments = $this->processArguments($node); + break; + } + } + + $autoDelete = $this->getAttributeValue($queue, 'autoDelete', false); + $result[$name . '--' . $connection] = [ + 'name' => $name, + 'type' => $this->getAttributeValue($queue, 'type'), + 'connection' => $connection, + 'durable' => $this->booleanUtils->toBoolean($this->getAttributeValue($queue, 'durable', true)), + 'autoDelete' => $this->booleanUtils->toBoolean($autoDelete), + 'internal' => $this->booleanUtils->toBoolean($this->getAttributeValue($queue, 'internal', false)), + 'arguments' => $queueArguments, + ]; + } + return $result; } diff --git a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Xml/Reader.php b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Xml/Reader.php index 6dbdf78d1f084..758fec15c0be2 100644 --- a/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Xml/Reader.php +++ b/lib/internal/Magento/Framework/MessageQueue/Topology/Config/Xml/Reader.php @@ -22,6 +22,9 @@ class Reader extends \Magento\Framework\Config\Reader\Filesystem implements Read '/config/exchange/binding' => 'id', '/config/exchange/binding/arguments/argument' => 'name', '/config/exchange/binding/arguments/argument(/item)+' => 'name', + '/config/queue' => ['name', 'connection'], + '/config/queue/arguments/argument' => 'name', + '/config/queue/arguments/argument(/item)+' => 'name' ]; /** diff --git a/lib/internal/Magento/Framework/MessageQueue/etc/topology.xsd b/lib/internal/Magento/Framework/MessageQueue/etc/topology.xsd index 39862007b1d12..0ac62a8ce47c6 100644 --- a/lib/internal/Magento/Framework/MessageQueue/etc/topology.xsd +++ b/lib/internal/Magento/Framework/MessageQueue/etc/topology.xsd @@ -42,6 +42,12 @@ + + + + + + @@ -56,7 +62,7 @@ - + @@ -68,7 +74,8 @@ - + + @@ -106,6 +113,18 @@ + + + + + + + + + + + + @@ -117,4 +136,10 @@ + + + + + + diff --git a/lib/internal/Magento/Framework/MessageQueue/etc/topology_merged.xsd b/lib/internal/Magento/Framework/MessageQueue/etc/topology_merged.xsd index e2b90343110f1..58c4787c9f196 100644 --- a/lib/internal/Magento/Framework/MessageQueue/etc/topology_merged.xsd +++ b/lib/internal/Magento/Framework/MessageQueue/etc/topology_merged.xsd @@ -23,6 +23,24 @@ + + + + + + + + + + + + + + + + + +