From d58622bb75ac48dc28ec6b48282b6846499327a9 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Fri, 9 Nov 2018 14:31:59 +0200 Subject: [PATCH 01/18] multi client configuration --- .../DependencyInjection/Configuration.php | 122 +++++++++++------- .../DependencyInjection/EnqueueExtension.php | 74 ++++++++--- .../Resources/config/client.yml | 8 -- .../DependencyInjection/ClientFactory.php | 25 +++- .../DependencyInjection/TransportFactory.php | 12 +- pkg/monitoring/GenericStatsStorageFactory.php | 66 ++++++++-- pkg/monitoring/Resources.php | 51 ++++++++ pkg/monitoring/StatsStorageFactory.php | 2 +- .../DependencyInjection/MonitoringFactory.php | 102 +++++++++++++++ .../Tests/GenericStatsStorageFactoryTest.php | 2 +- 10 files changed, 366 insertions(+), 98 deletions(-) create mode 100644 pkg/monitoring/Resources.php create mode 100644 pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php diff --git a/pkg/enqueue-bundle/DependencyInjection/Configuration.php b/pkg/enqueue-bundle/DependencyInjection/Configuration.php index 42c8715ca..3bc669077 100644 --- a/pkg/enqueue-bundle/DependencyInjection/Configuration.php +++ b/pkg/enqueue-bundle/DependencyInjection/Configuration.php @@ -2,6 +2,7 @@ namespace Enqueue\Bundle\DependencyInjection; +use Enqueue\Monitoring\Symfony\DependencyInjection\MonitoringFactory; use Enqueue\Symfony\Client\DependencyInjection\ClientFactory; use Enqueue\Symfony\DependencyInjection\TransportFactory; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; @@ -26,8 +27,8 @@ public function getConfigTreeBuilder(): TreeBuilder ->always(function ($value) { if (empty($value)) { return [ - 'transport' => [ - 'default' => [ + 'default' => [ + 'transport' => [ 'dsn' => 'null:', ], ], @@ -36,8 +37,8 @@ public function getConfigTreeBuilder(): TreeBuilder if (is_string($value)) { return [ - 'transport' => [ - 'default' => [ + 'default' => [ + 'transport' => [ 'dsn' => $value, ], ], @@ -50,57 +51,82 @@ public function getConfigTreeBuilder(): TreeBuilder $transportFactory = new TransportFactory('default'); - /** @var ArrayNodeDefinition $transportNode */ - $transportNode = $rootNode->children()->arrayNode('transport'); - $transportNode - ->beforeNormalization() - ->always(function ($value) { - if (empty($value)) { - return ['default' => ['dsn' => 'null:']]; - } - if (is_string($value)) { - return ['default' => ['dsn' => $value]]; - } - - if (is_array($value) && array_key_exists('dsn', $value)) { - return ['default' => $value]; - } - - return $value; - }); - $transportPrototypeNode = $transportNode - ->requiresAtLeastOneElement() - ->useAttributeAsKey('key') - ->prototype('array') - ; + $transportConfig = $transportFactory->getConfiguration('transport'); + $transportConfig->isRequired(); - $transportFactory->addTransportConfiguration($transportPrototypeNode); + $consumerConfig = $transportFactory->getQueueConsumerConfiguration('consumption'); - $consumptionNode = $rootNode->children()->arrayNode('consumption'); - $transportFactory->addQueueConsumerConfiguration($consumptionNode); + $clientConfig = (new ClientFactory('default'))->getConfiguration('client', $this->debug); - $clientFactory = new ClientFactory('default'); - $clientNode = $rootNode->children()->arrayNode('client'); - $clientFactory->addClientConfiguration($clientNode, $this->debug); + $monitoringConfig = (new MonitoringFactory('default'))->getConfiguration('monitoring'); - $rootNode->children() - ->booleanNode('job')->defaultFalse()->end() - ->arrayNode('async_events') - ->addDefaultsIfNotSet() - ->canBeEnabled() - ->end() - ->arrayNode('async_commands') - ->addDefaultsIfNotSet() - ->canBeEnabled() + $rootNode + ->requiresAtLeastOneElement() + ->useAttributeAsKey('key') + ->arrayPrototype() + ->children() + ->append($transportConfig) + ->append($consumerConfig) + ->append($clientConfig) + ->append($monitoringConfig) + ->end() ->end() - ->arrayNode('extensions')->addDefaultsIfNotSet()->children() - ->booleanNode('doctrine_ping_connection_extension')->defaultFalse()->end() - ->booleanNode('doctrine_clear_identity_map_extension')->defaultFalse()->end() - ->booleanNode('signal_extension')->defaultValue(function_exists('pcntl_signal_dispatch'))->end() - ->booleanNode('reply_extension')->defaultTrue()->end() - ->end()->end() ; + +// $transportFactory = new TransportFactory('default'); +// +// /** @var ArrayNodeDefinition $transportNode */ +// $transportNode = $rootNode->children()->arrayNode('transport'); +// $transportNode +// ->beforeNormalization() +// ->always(function ($value) { +// if (empty($value)) { +// return ['default' => ['dsn' => 'null:']]; +// } +// if (is_string($value)) { +// return ['default' => ['dsn' => $value]]; +// } +// +// if (is_array($value) && array_key_exists('dsn', $value)) { +// return ['default' => $value]; +// } +// +// return $value; +// }); +// $transportPrototypeNode = $transportNode +// ->requiresAtLeastOneElement() +// ->useAttributeAsKey('key') +// ->prototype('array') +// ; +// +// $transportFactory->addTransportConfiguration($transportPrototypeNode); +// +// $consumptionNode = $rootNode->children()->arrayNode('consumption'); +// $transportFactory->addQueueConsumerConfiguration($consumptionNode); +// +// $clientFactory = new ClientFactory('default'); +// $clientNode = $rootNode->children()->arrayNode('client'); +// $clientFactory->addClientConfiguration($clientNode, $this->debug); +// +// $rootNode->children() +// ->booleanNode('job')->defaultFalse()->end() +// ->arrayNode('async_events') +// ->addDefaultsIfNotSet() +// ->canBeEnabled() +// ->end() +// ->arrayNode('async_commands') +// ->addDefaultsIfNotSet() +// ->canBeEnabled() +// ->end() +// ->arrayNode('extensions')->addDefaultsIfNotSet()->children() +// ->booleanNode('doctrine_ping_connection_extension')->defaultFalse()->end() +// ->booleanNode('doctrine_clear_identity_map_extension')->defaultFalse()->end() +// ->booleanNode('signal_extension')->defaultValue(function_exists('pcntl_signal_dispatch'))->end() +// ->booleanNode('reply_extension')->defaultTrue()->end() +// ->end()->end() +// ; +// return $tb; } } diff --git a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php index bcb2f7018..72c02b5c0 100644 --- a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php +++ b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php @@ -25,33 +25,60 @@ public function load(array $configs, ContainerBuilder $container): void $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.yml'); - foreach ($config['transport'] as $name => $transportConfig) { + // find default configuration + $defaultName = null; + foreach ($config as $name => $configs) { + // set first as default + if (null === $defaultName) { + $defaultName = $name; + } + + // or with name 'default' + if ('default' === $name) { + $defaultName = $name; + } + } + + $transportNames = []; + $clientNames = []; + foreach ($config as $name => $configs) { + // transport & consumption + $transportNames[] = $name; + $transportFactory = (new TransportFactory($name)); - $transportFactory->buildConnectionFactory($container, $transportConfig); + $transportFactory->buildConnectionFactory($container, $config['transport']); $transportFactory->buildContext($container, []); $transportFactory->buildQueueConsumer($container, $config['consumption']); $transportFactory->buildRpcClient($container, []); - } - $container->setParameter('enqueue.transports', array_keys($config['transport'])); + // client + if (isset($configs['client'])) { + $clientNames[] = $name; - if (isset($config['client'])) { - $container->setParameter('enqueue.clients', ['default']); + $clientConfig = $config['client']; + // todo + $clientConfig['transport'] = $config['transport']; + $clientConfig['consumption'] = $config['consumption']; - $this->setupAutowiringForProcessors($container); - - $loader->load('client.yml'); + $clientFactory = new ClientFactory($name); + $clientFactory->build($container, $clientConfig, $defaultName === $name); + $clientFactory->createDriver($container, $config['transport']); + $clientFactory->createFlushSpoolProducerListener($container); + } + } - $clientConfig = $config['client']; - // todo - $clientConfig['transport'] = $config['transport']['default']; - $clientConfig['consumption'] = $config['consumption']; + $container->setParameter('enqueue.transports', $transportNames); + $container->setParameter('enqueue.clients', $clientNames); - $clientFactory = new ClientFactory('default'); - $clientFactory->build($container, $clientConfig); - $clientFactory->createDriver($container, $config['transport']['default']); + if ($clientNames) { + $this->setupAutowiringForProcessors($container, $clientNames); } + // @todo register MessageQueueCollector + + return; + + // if ($config['job']) { if (!class_exists(Job::class)) { throw new \LogicException('Seems "enqueue/job-queue" is not installed. Please fix this issue.'); @@ -145,14 +172,19 @@ private function registerJobQueueDoctrineEntityMapping(ContainerBuilder $contain } } - private function setupAutowiringForProcessors(ContainerBuilder $container) + private function setupAutowiringForProcessors(ContainerBuilder $container, array $clientNames) { - $container->registerForAutoconfiguration(TopicSubscriberInterface::class) + $topicSubscriber = $container->registerForAutoconfiguration(TopicSubscriberInterface::class) ->setPublic(true) - ->addTag('enqueue.topic_subscriber', ['client' => 'default']); + ; - $container->registerForAutoconfiguration(CommandSubscriberInterface::class) + $commandSubscriber = $container->registerForAutoconfiguration(CommandSubscriberInterface::class) ->setPublic(true) - ->addTag('enqueue.command_subscriber', ['client' => 'default']); + ; + + foreach ($clientNames as $clientName) { + $topicSubscriber->addTag('enqueue.topic_subscriber', ['client' => $clientName]); + $commandSubscriber->addTag('enqueue.command_subscriber', ['client' => $clientName]); + } } } diff --git a/pkg/enqueue-bundle/Resources/config/client.yml b/pkg/enqueue-bundle/Resources/config/client.yml index b1821a167..a7b9a1b80 100644 --- a/pkg/enqueue-bundle/Resources/config/client.yml +++ b/pkg/enqueue-bundle/Resources/config/client.yml @@ -6,11 +6,3 @@ services: - '@enqueue.client.default.producer' tags: - { name: 'data_collector', template: '@Enqueue/Profiler/panel.html.twig', id: 'enqueue.message_queue' } - - # todo - enqueue.client.default.flush_spool_producer_listener: - class: 'Enqueue\Symfony\Client\FlushSpoolProducerListener' - arguments: - - '@enqueue.client.default.spool_producer' - tags: - - { name: 'kernel.event_subscriber' } diff --git a/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php b/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php index f78c1abbb..9873b6c6c 100644 --- a/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php +++ b/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php @@ -20,9 +20,11 @@ use Enqueue\Consumption\ChainExtension as ConsumptionChainExtension; use Enqueue\Consumption\QueueConsumer; use Enqueue\Rpc\RpcFactory; +use Enqueue\Symfony\Client\FlushSpoolProducerListener; use Enqueue\Symfony\ContainerProcessorRegistry; use Interop\Queue\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; @@ -48,22 +50,26 @@ public function __construct(string $name) $this->name = $name; } - public function addClientConfiguration(ArrayNodeDefinition $builder, bool $debug): void + public function getConfiguration(string $name, bool $debug): NodeDefinition { + $builder = new ArrayNodeDefinition($name); + $builder->children() ->booleanNode('traceable_producer')->defaultValue($debug)->end() ->scalarNode('prefix')->defaultValue('enqueue')->end() ->scalarNode('app_name')->defaultValue('app')->end() ->scalarNode('router_topic')->defaultValue('default')->cannotBeEmpty()->end() ->scalarNode('router_queue')->defaultValue('default')->cannotBeEmpty()->end() - ->scalarNode('router_processor')->defaultValue($this->format('router_processor'))->end() + ->scalarNode('router_processor')->defaultNull()->end() ->scalarNode('default_processor_queue')->defaultValue('default')->cannotBeEmpty()->end() ->integerNode('redelivered_delay_time')->min(0)->defaultValue(0)->end() ->end()->end() ; + + return $builder; } - public function build(ContainerBuilder $container, array $config): void + public function build(ContainerBuilder $container, array $config, bool $default = false): void { $container->register($this->format('context'), Context::class) ->setFactory([$this->reference('driver'), 'getContext']) @@ -81,7 +87,7 @@ public function build(ContainerBuilder $container, array $config): void $config['router_topic'], $config['router_queue'], $config['default_processor_queue'], - $config['router_processor'], + isset($config['router_processor']) ? $config['router_processor'] : $this->format('router_processor'), // @todo should be driver options. $config['transport'], ]); @@ -180,9 +186,8 @@ public function build(ContainerBuilder $container, array $config): void ])); } - if ('default' === $this->name) { + if ($default) { $container->setAlias(ProducerInterface::class, $this->format('producer')); - $container->setAlias(SpoolProducer::class, $this->format('spool_producer')); } } @@ -203,6 +208,14 @@ public function createDriver(ContainerBuilder $container, array $config): string return $driverId; } + public function createFlushSpoolProducerListener(ContainerBuilder $container): void + { + $container->register($this->format('flush_spool_producer_listener'), FlushSpoolProducerListener::class) + ->addArgument($this->reference('spool_producer')) + ->addTag('kernel.event_subscriber') + ; + } + public function getName(): string { return $this->name; diff --git a/pkg/enqueue/Symfony/DependencyInjection/TransportFactory.php b/pkg/enqueue/Symfony/DependencyInjection/TransportFactory.php index da360d711..70b2a84ed 100644 --- a/pkg/enqueue/Symfony/DependencyInjection/TransportFactory.php +++ b/pkg/enqueue/Symfony/DependencyInjection/TransportFactory.php @@ -15,6 +15,7 @@ use Interop\Queue\ConnectionFactory; use Interop\Queue\Context; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; @@ -40,11 +41,12 @@ public function __construct(string $name) $this->name = $name; } - public function addTransportConfiguration(ArrayNodeDefinition $builder): void + public function getConfiguration(string $name): NodeDefinition { $knownSchemes = array_keys(Resources::getKnownSchemes()); $availableSchemes = array_keys(Resources::getAvailableSchemes()); + $builder = new ArrayNodeDefinition($name); $builder ->info('The transport option could accept a string DSN, an array with DSN key, or null. It accept extra options. To find out what option you can set, look at connection factory constructor docblock.') ->beforeNormalization() @@ -94,10 +96,14 @@ public function addTransportConfiguration(ArrayNodeDefinition $builder): void ->end() ->end() ; + + return $builder; } - public function addQueueConsumerConfiguration(ArrayNodeDefinition $builder): void + public function getQueueConsumerConfiguration(string $name): ArrayNodeDefinition { + $builder = new ArrayNodeDefinition($name); + $builder ->addDefaultsIfNotSet()->children() ->integerNode('receive_timeout') @@ -106,6 +112,8 @@ public function addQueueConsumerConfiguration(ArrayNodeDefinition $builder): voi ->info('the time in milliseconds queue consumer waits for a message (100 ms by default)') ->end() ; + + return $builder; } public function getName(): string diff --git a/pkg/monitoring/GenericStatsStorageFactory.php b/pkg/monitoring/GenericStatsStorageFactory.php index 0057c9f32..32b3beb8c 100644 --- a/pkg/monitoring/GenericStatsStorageFactory.php +++ b/pkg/monitoring/GenericStatsStorageFactory.php @@ -8,18 +8,62 @@ class GenericStatsStorageFactory implements StatsStorageFactory { - public function create(string $dsn): StatsStorage + public function create($config): StatsStorage { - $schema = (new Dsn($dsn))->getScheme(); - - switch ($schema) { - case 'influxdb': - return new InfluxDbStorage($dsn); - case 'wamp': - case 'ws': - return new WampStorage($dsn); - default: - throw new \LogicException(sprintf('Unsupported stats storage: "%s"', $dsn)); + if (is_string($config)) { + $config = ['dsn' => $config]; } + + if (false == is_array($config)) { + throw new \InvalidArgumentException('The config must be either array or DSN string.'); + } + + if (false == array_key_exists('dsn', $config)) { + throw new \InvalidArgumentException('The config must have dsn key set.'); + } + + $dsn = new Dsn($config['dsn']); + + if ($storageClass = $this->findStorageClass($dsn, Resources::getKnownStorages())) { + return new $storageClass(1 === count($config) ? $config['dsn'] : $config); + } + + throw new \LogicException(sprintf( + 'A given scheme "%s" is not supported.', + $dsn->getScheme(), + Resources::class + )); + } + + private function findStorageClass(Dsn $dsn, array $factories): ?string + { + $protocol = $dsn->getSchemeProtocol(); + + if ($dsn->getSchemeExtensions()) { + foreach ($factories as $storageClass => $info) { + if (empty($info['supportedSchemeExtensions'])) { + continue; + } + + if (false == in_array($protocol, $info['schemes'], true)) { + continue; + } + + $diff = array_diff($info['supportedSchemeExtensions'], $dsn->getSchemeExtensions()); + if (empty($diff)) { + return $storageClass; + } + } + } + + foreach ($factories as $storageClass => $info) { + if (false == in_array($protocol, $info['schemes'], true)) { + continue; + } + + return $storageClass; + } + + return null; } } diff --git a/pkg/monitoring/Resources.php b/pkg/monitoring/Resources.php new file mode 100644 index 000000000..86419a0e5 --- /dev/null +++ b/pkg/monitoring/Resources.php @@ -0,0 +1,51 @@ + $item) { + foreach ($item['schemes'] as $scheme) { + $schemes[$scheme] = $storageClass; + } + } + + return $schemes; + } + + public static function getKnownStorages(): array + { + if (null === self::$knownStorages) { + $map = []; + + $map[WampStorage::class] = [ + 'schemes' => ['wamp', 'ws'], + 'supportedSchemeExtensions' => [], + ]; + + $map[InfluxDbStorage::class] = [ + 'schemes' => ['influxdb'], + 'supportedSchemeExtensions' => [], + ]; + + self::$knownStorages = $map; + } + + return self::$knownStorages; + } +} diff --git a/pkg/monitoring/StatsStorageFactory.php b/pkg/monitoring/StatsStorageFactory.php index 82c8e6e1a..cfd53381f 100644 --- a/pkg/monitoring/StatsStorageFactory.php +++ b/pkg/monitoring/StatsStorageFactory.php @@ -6,5 +6,5 @@ interface StatsStorageFactory { - public function create(string $dsn): StatsStorage; + public function create($config): StatsStorage; } diff --git a/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php b/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php new file mode 100644 index 000000000..975ece8b1 --- /dev/null +++ b/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php @@ -0,0 +1,102 @@ +name = $name; + } + + public function getConfiguration(string $name): ArrayNodeDefinition + { + $builder = new ArrayNodeDefinition($name); + + $builder + ->info(sprintf('The "%s" option could accept a string DSN, an array with DSN key, or null. It accept extra options. To find out what option you can set, look at stats storage constructor doc block.', $name)) + ->beforeNormalization() + ->always(function ($v) { + if (is_array($v)) { + if (isset($v['storage_factory_class']) && isset($v['storage_factory_service'])) { + throw new \LogicException('Both options storage_factory_class and storage_factory_service are set. Please choose one.'); + } + + return $v; + } + + if (is_string($v)) { + return ['dsn' => $v]; + } + + return $v; + }) + ->end() + ->ignoreExtraKeys(false) + ->children() + ->scalarNode('dsn') + ->cannotBeEmpty() + ->isRequired() + ->info(sprintf('The stats storage DSN. These schemes are supported: "%s".', implode('", "', array_keys(Resources::getKnownSchemes())))) + ->end() + ->scalarNode('storage_factory_service') + ->info(sprintf('The factory class should implement "%s" interface', StatsStorageFactory::class)) + ->end() + ->scalarNode('storage_factory_class') + ->info(sprintf('The factory service should be a class that implements "%s" interface', StatsStorageFactory::class)) + ->end() + ->end() + ; + + return $builder; + } + + public function getName(): string + { + return $this->name; + } + + public function buildStorage(ContainerBuilder $container, array $config): void + { + $storageId = $this->format('storage'); + $storageFactoryId = $this->format('storage.factory'); + + if (isset($config['storage_factory_service'])) { + $container->setAlias($storageFactoryId, $config['storage_factory_service']); + } elseif (isset($config['storage_factory_class'])) { + $container->register($storageFactoryId, $config['storage_factory_class']); + } else { + $container->register($storageFactoryId, GenericStatsStorageFactory::class); + } + + unset($config['storage_factory_service'], $config['storage_factory_class']); + + $container->register($storageId, StatsStorage::class) + ->setFactory([new Reference($storageFactoryId), 'create']) + ->addArgument($config) + ; + } +} diff --git a/pkg/monitoring/Tests/GenericStatsStorageFactoryTest.php b/pkg/monitoring/Tests/GenericStatsStorageFactoryTest.php index 51b0d7c5f..5fd606d5a 100644 --- a/pkg/monitoring/Tests/GenericStatsStorageFactoryTest.php +++ b/pkg/monitoring/Tests/GenericStatsStorageFactoryTest.php @@ -35,7 +35,7 @@ public function testShouldCreateWampStorage() public function testShouldThrowIfStorageIsNotSupported() { $this->expectException(\LogicException::class); - $this->expectExceptionMessage('Unsupported stats storage: "unsupported:"'); + $this->expectExceptionMessage('A given scheme "unsupported" is not supported.'); (new GenericStatsStorageFactory())->create('unsupported:'); } From b32210179c9a577b7ffe20ec5673dd2f05dd1eb8 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Mon, 12 Nov 2018 13:50:57 +0200 Subject: [PATCH 02/18] multi client configuration --- .../AsyncCommandExtension.php | 9 + .../DependencyInjection/Configuration.php | 59 +---- .../DependencyInjection/EnqueueExtension.php | 208 +++++++++++++----- .../doctrine_clear_identity_map_extension.yml | 9 - .../doctrine_ping_connection_extension.yml | 8 - .../config/extensions/reply_extension.yml | 6 - .../config/extensions/signal_extension.yml | 6 - .../Tests/Functional/App/config/config.yml | 21 +- .../Functional/Events/AsyncListenerTest.php | 2 + pkg/enqueue/Symfony/DiUtils.php | 57 +++++ .../DependencyInjection/MonitoringFactory.php | 39 ++-- 11 files changed, 273 insertions(+), 151 deletions(-) delete mode 100644 pkg/enqueue-bundle/Resources/config/extensions/doctrine_clear_identity_map_extension.yml delete mode 100644 pkg/enqueue-bundle/Resources/config/extensions/doctrine_ping_connection_extension.yml delete mode 100644 pkg/enqueue-bundle/Resources/config/extensions/reply_extension.yml delete mode 100644 pkg/enqueue-bundle/Resources/config/extensions/signal_extension.yml create mode 100644 pkg/enqueue/Symfony/DiUtils.php diff --git a/pkg/async-command/DependencyInjection/AsyncCommandExtension.php b/pkg/async-command/DependencyInjection/AsyncCommandExtension.php index 77db687b6..3d614b4c2 100644 --- a/pkg/async-command/DependencyInjection/AsyncCommandExtension.php +++ b/pkg/async-command/DependencyInjection/AsyncCommandExtension.php @@ -2,6 +2,7 @@ namespace Enqueue\AsyncCommand\DependencyInjection; +use Enqueue\AsyncCommand\RunCommandProcessor; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; @@ -16,5 +17,13 @@ public function load(array $configs, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.yml'); + + $service = $container->register('enqueue.async_command.run_command_processor', RunCommandProcessor::class) + ->addArgument('%kernel.project_dir%') + ; + + foreach ($configs['clients'] as $client) { + $service->addTag('enqueue.command_subscriber', ['client' => $client]); + } } } diff --git a/pkg/enqueue-bundle/DependencyInjection/Configuration.php b/pkg/enqueue-bundle/DependencyInjection/Configuration.php index 3bc669077..7b75c0d71 100644 --- a/pkg/enqueue-bundle/DependencyInjection/Configuration.php +++ b/pkg/enqueue-bundle/DependencyInjection/Configuration.php @@ -5,7 +5,6 @@ use Enqueue\Monitoring\Symfony\DependencyInjection\MonitoringFactory; use Enqueue\Symfony\Client\DependencyInjection\ClientFactory; use Enqueue\Symfony\DependencyInjection\TransportFactory; -use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -69,64 +68,28 @@ public function getConfigTreeBuilder(): TreeBuilder ->append($consumerConfig) ->append($clientConfig) ->append($monitoringConfig) + ->arrayNode('extensions')->addDefaultsIfNotSet()->children() + ->booleanNode('doctrine_ping_connection_extension')->defaultFalse()->end() + ->booleanNode('doctrine_clear_identity_map_extension')->defaultFalse()->end() + ->booleanNode('signal_extension')->defaultValue(function_exists('pcntl_signal_dispatch'))->end() + ->booleanNode('reply_extension')->defaultTrue()->end() + ->end()->end() + ->arrayNode('async_commands') + ->addDefaultsIfNotSet() + ->canBeEnabled() + ->end() ->end() ->end() ; - -// $transportFactory = new TransportFactory('default'); -// -// /** @var ArrayNodeDefinition $transportNode */ -// $transportNode = $rootNode->children()->arrayNode('transport'); -// $transportNode -// ->beforeNormalization() -// ->always(function ($value) { -// if (empty($value)) { -// return ['default' => ['dsn' => 'null:']]; -// } -// if (is_string($value)) { -// return ['default' => ['dsn' => $value]]; -// } -// -// if (is_array($value) && array_key_exists('dsn', $value)) { -// return ['default' => $value]; -// } -// -// return $value; -// }); -// $transportPrototypeNode = $transportNode -// ->requiresAtLeastOneElement() -// ->useAttributeAsKey('key') -// ->prototype('array') -// ; -// -// $transportFactory->addTransportConfiguration($transportPrototypeNode); -// -// $consumptionNode = $rootNode->children()->arrayNode('consumption'); -// $transportFactory->addQueueConsumerConfiguration($consumptionNode); -// -// $clientFactory = new ClientFactory('default'); -// $clientNode = $rootNode->children()->arrayNode('client'); -// $clientFactory->addClientConfiguration($clientNode, $this->debug); -// // $rootNode->children() // ->booleanNode('job')->defaultFalse()->end() // ->arrayNode('async_events') // ->addDefaultsIfNotSet() // ->canBeEnabled() // ->end() -// ->arrayNode('async_commands') -// ->addDefaultsIfNotSet() -// ->canBeEnabled() -// ->end() -// ->arrayNode('extensions')->addDefaultsIfNotSet()->children() -// ->booleanNode('doctrine_ping_connection_extension')->defaultFalse()->end() -// ->booleanNode('doctrine_clear_identity_map_extension')->defaultFalse()->end() -// ->booleanNode('signal_extension')->defaultValue(function_exists('pcntl_signal_dispatch'))->end() -// ->booleanNode('reply_extension')->defaultTrue()->end() -// ->end()->end() // ; -// + return $tb; } } diff --git a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php index 72c02b5c0..1b015f86f 100644 --- a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php +++ b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php @@ -4,9 +4,14 @@ use Enqueue\AsyncCommand\DependencyInjection\AsyncCommandExtension; use Enqueue\AsyncEventDispatcher\DependencyInjection\AsyncEventDispatcherExtension; +use Enqueue\Bundle\Consumption\Extension\DoctrineClearIdentityMapExtension; +use Enqueue\Bundle\Consumption\Extension\DoctrinePingConnectionExtension; use Enqueue\Client\CommandSubscriberInterface; use Enqueue\Client\TopicSubscriberInterface; +use Enqueue\Consumption\Extension\ReplyExtension; +use Enqueue\Consumption\Extension\SignalExtension; use Enqueue\JobQueue\Job; +use Enqueue\Monitoring\Symfony\DependencyInjection\MonitoringFactory; use Enqueue\Symfony\Client\DependencyInjection\ClientFactory; use Enqueue\Symfony\DependencyInjection\TransportFactory; use Symfony\Component\Config\FileLocator; @@ -14,6 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; final class EnqueueExtension extends Extension implements PrependExtensionInterface @@ -46,25 +52,36 @@ public function load(array $configs, ContainerBuilder $container): void $transportNames[] = $name; $transportFactory = (new TransportFactory($name)); - $transportFactory->buildConnectionFactory($container, $config['transport']); + $transportFactory->buildConnectionFactory($container, $configs['transport']); $transportFactory->buildContext($container, []); - $transportFactory->buildQueueConsumer($container, $config['consumption']); + $transportFactory->buildQueueConsumer($container, $configs['consumption']); $transportFactory->buildRpcClient($container, []); // client if (isset($configs['client'])) { $clientNames[] = $name; - $clientConfig = $config['client']; + $clientConfig = $configs['client']; // todo - $clientConfig['transport'] = $config['transport']; - $clientConfig['consumption'] = $config['consumption']; + $clientConfig['transport'] = $configs['transport']; + $clientConfig['consumption'] = $configs['consumption']; $clientFactory = new ClientFactory($name); $clientFactory->build($container, $clientConfig, $defaultName === $name); - $clientFactory->createDriver($container, $config['transport']); + $clientFactory->createDriver($container, $configs['transport']); $clientFactory->createFlushSpoolProducerListener($container); } + + // monitoring + if (isset($configs['monitoring'])) { + $monitoringFactory = new MonitoringFactory($name); + $monitoringFactory->buildStorage($container, $configs['monitoring']); + $monitoringFactory->buildConsumerExtension($container, $configs['monitoring']); + + if (isset($configs['client'])) { + $monitoringFactory->buildClientExtension($container, $configs['monitoring']); + } + } } $container->setParameter('enqueue.transports', $transportNames); @@ -74,54 +91,34 @@ public function load(array $configs, ContainerBuilder $container): void $this->setupAutowiringForProcessors($container, $clientNames); } - // @todo register MessageQueueCollector - - return; - - // - if ($config['job']) { - if (!class_exists(Job::class)) { - throw new \LogicException('Seems "enqueue/job-queue" is not installed. Please fix this issue.'); - } - - $loader->load('job.yml'); - } - - if ($config['async_events']['enabled']) { - if (false == class_exists(AsyncEventDispatcherExtension::class)) { - throw new \LogicException('The "enqueue/async-event-dispatcher" package has to be installed.'); - } - - $extension = new AsyncEventDispatcherExtension(); - $extension->load([[ - 'context_service' => 'enqueue.transport.default.context', - ]], $container); - } - - if ($config['async_commands']['enabled']) { - if (false == class_exists(AsyncCommandExtension::class)) { - throw new \LogicException('The "enqueue/async-command" package has to be installed.'); - } + $this->loadAsyncCommands($config, $container); - $extension = new AsyncCommandExtension(); - $extension->load([[]], $container); - } - - if ($config['extensions']['doctrine_ping_connection_extension']) { - $loader->load('extensions/doctrine_ping_connection_extension.yml'); - } - - if ($config['extensions']['doctrine_clear_identity_map_extension']) { - $loader->load('extensions/doctrine_clear_identity_map_extension.yml'); - } + // extensions + $this->loadDoctrinePingConnectionExtension($config, $container); + $this->loadDoctrineClearIdentityMapExtension($config, $container); + $this->loadSignalExtension($config, $container); + $this->loadReplyExtension($config, $container); - if ($config['extensions']['signal_extension']) { - $loader->load('extensions/signal_extension.yml'); - } + // @todo register MessageQueueCollector - if ($config['extensions']['reply_extension']) { - $loader->load('extensions/reply_extension.yml'); - } +// if ($config['job']) { +// if (!class_exists(Job::class)) { +// throw new \LogicException('Seems "enqueue/job-queue" is not installed. Please fix this issue.'); +// } +// +// $loader->load('job.yml'); +// } +// +// if ($config['async_events']['enabled']) { +// if (false == class_exists(AsyncEventDispatcherExtension::class)) { +// throw new \LogicException('The "enqueue/async-event-dispatcher" package has to be installed.'); +// } +// +// $extension = new AsyncEventDispatcherExtension(); +// $extension->load([[ +// 'context_service' => 'enqueue.transport.default.context', +// ]], $container); +// } } public function getConfiguration(array $config, ContainerBuilder $container): Configuration @@ -187,4 +184,113 @@ private function setupAutowiringForProcessors(ContainerBuilder $container, array $commandSubscriber->addTag('enqueue.command_subscriber', ['client' => $clientName]); } } + + private function loadDoctrinePingConnectionExtension(array $config, ContainerBuilder $container): void + { + $configNames = []; + foreach ($config as $name => $modules) { + if ($modules['extensions']['doctrine_ping_connection_extension']) { + $configNames[] = $name; + } + } + + if (false == $configNames) { + return; + } + + $extension = $container->register('enqueue.consumption.doctrine_ping_connection_extension', DoctrinePingConnectionExtension::class) + ->addArgument(new Reference('doctrine')) + ; + + foreach ($configNames as $name) { + $extension->addTag('enqueue.consumption_extension', ['client' => $name]); + $extension->addTag('enqueue.transport.consumption_extension', ['transport' => $name]); + } + } + + private function loadDoctrineClearIdentityMapExtension(array $config, ContainerBuilder $container): void + { + $configNames = []; + foreach ($config as $name => $modules) { + if ($modules['extensions']['doctrine_clear_identity_map_extension']) { + $configNames[] = $name; + } + } + + if (false == $configNames) { + return; + } + + $extension = $container->register('enqueue.consumption.doctrine_clear_identity_map_extension', DoctrineClearIdentityMapExtension::class) + ->addArgument(new Reference('doctrine')) + ; + + foreach ($configNames as $name) { + $extension->addTag('enqueue.consumption_extension', ['client' => $name]); + $extension->addTag('enqueue.transport.consumption_extension', ['transport' => $name]); + } + } + + private function loadSignalExtension(array $config, ContainerBuilder $container): void + { + $configNames = []; + foreach ($config as $name => $modules) { + if ($modules['extensions']['signal_extension']) { + $configNames[] = $name; + } + } + + if (false == $configNames) { + return; + } + + $extension = $container->register('enqueue.consumption.signal_extension', SignalExtension::class); + + foreach ($configNames as $name) { + $extension->addTag('enqueue.consumption_extension', ['client' => $name]); + $extension->addTag('enqueue.transport.consumption_extension', ['transport' => $name]); + } + } + + private function loadReplyExtension(array $config, ContainerBuilder $container): void + { + $configNames = []; + foreach ($config as $name => $modules) { + if ($modules['extensions']['reply_extension']) { + $configNames[] = $name; + } + } + + if (false == $configNames) { + return; + } + + $extension = $container->register('enqueue.consumption.reply_extension', ReplyExtension::class); + + foreach ($configNames as $name) { + $extension->addTag('enqueue.consumption_extension', ['client' => $name]); + $extension->addTag('enqueue.transport.consumption_extension', ['transport' => $name]); + } + } + + private function loadAsyncCommands(array $config, ContainerBuilder $container): void + { + $configNames = []; + foreach ($config as $name => $modules) { + if ($modules['async_commands']['enabled']) { + $configNames[] = $name; + } + } + + if (false == $configNames) { + return; + } + + if (false == class_exists(AsyncCommandExtension::class)) { + throw new \LogicException('The "enqueue/async-command" package has to be installed.'); + } + + $extension = new AsyncCommandExtension(); + $extension->load(['clients' => $configNames], $container); + } } diff --git a/pkg/enqueue-bundle/Resources/config/extensions/doctrine_clear_identity_map_extension.yml b/pkg/enqueue-bundle/Resources/config/extensions/doctrine_clear_identity_map_extension.yml deleted file mode 100644 index c3c4cd72a..000000000 --- a/pkg/enqueue-bundle/Resources/config/extensions/doctrine_clear_identity_map_extension.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - enqueue.consumption.doctrine_clear_identity_map_extension: - class: 'Enqueue\Bundle\Consumption\Extension\DoctrineClearIdentityMapExtension' - arguments: - - '@doctrine' - tags: - - { name: 'enqueue.consumption_extension', client: 'all' } - - { name: 'enqueue.transport.consumption_extension', transport: 'all' } - diff --git a/pkg/enqueue-bundle/Resources/config/extensions/doctrine_ping_connection_extension.yml b/pkg/enqueue-bundle/Resources/config/extensions/doctrine_ping_connection_extension.yml deleted file mode 100644 index b474a707c..000000000 --- a/pkg/enqueue-bundle/Resources/config/extensions/doctrine_ping_connection_extension.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - enqueue.consumption.doctrine_ping_connection_extension: - class: 'Enqueue\Bundle\Consumption\Extension\DoctrinePingConnectionExtension' - arguments: - - '@doctrine' - tags: - - { name: 'enqueue.consumption_extension', client: 'all' } - - { name: 'enqueue.transport.consumption_extension', transport: 'all' } diff --git a/pkg/enqueue-bundle/Resources/config/extensions/reply_extension.yml b/pkg/enqueue-bundle/Resources/config/extensions/reply_extension.yml deleted file mode 100644 index a1c71fbcb..000000000 --- a/pkg/enqueue-bundle/Resources/config/extensions/reply_extension.yml +++ /dev/null @@ -1,6 +0,0 @@ -services: - enqueue.consumption.reply_extension: - class: 'Enqueue\Consumption\Extension\ReplyExtension' - tags: - - { name: 'enqueue.consumption_extension', client: 'all' } - - { name: 'enqueue.transport.consumption_extension', transport: 'all' } \ No newline at end of file diff --git a/pkg/enqueue-bundle/Resources/config/extensions/signal_extension.yml b/pkg/enqueue-bundle/Resources/config/extensions/signal_extension.yml deleted file mode 100644 index 5aa5378f7..000000000 --- a/pkg/enqueue-bundle/Resources/config/extensions/signal_extension.yml +++ /dev/null @@ -1,6 +0,0 @@ -services: - enqueue.consumption.signal_extension: - class: 'Enqueue\Consumption\Extension\SignalExtension' - tags: - - { name: 'enqueue.consumption_extension', client: 'all' } - - { name: 'enqueue.transport.consumption_extension', transport: 'all' } \ No newline at end of file diff --git a/pkg/enqueue-bundle/Tests/Functional/App/config/config.yml b/pkg/enqueue-bundle/Tests/Functional/App/config/config.yml index ac50e5afa..8a99208cb 100644 --- a/pkg/enqueue-bundle/Tests/Functional/App/config/config.yml +++ b/pkg/enqueue-bundle/Tests/Functional/App/config/config.yml @@ -22,12 +22,13 @@ doctrine: charset: UTF8 enqueue: - transport: 'null:' - client: - traceable_producer: true - job: true - async_events: true - async_commands: true + default: + transport: 'null:' + client: + traceable_producer: true + async_commands: true +# job: true +# async_commands: true services: test_enqueue.client.default.traceable_producer: @@ -114,7 +115,7 @@ services: - {name: 'enqueue.event_transformer', eventName: 'test_async_subscriber', transformerName: 'test_async' } # overwrite async listener with one based on client producer. so we can use traceable producer. - enqueue.events.async_listener: - class: 'Enqueue\Bundle\Tests\Functional\App\AsyncListener' - public: true - arguments: ['@enqueue.client.default.producer', '@enqueue.events.registry'] \ No newline at end of file +# enqueue.events.async_listener: +# class: 'Enqueue\Bundle\Tests\Functional\App\AsyncListener' +# public: true +# arguments: ['@enqueue.client.default.producer', '@enqueue.events.registry'] \ No newline at end of file diff --git a/pkg/enqueue-bundle/Tests/Functional/Events/AsyncListenerTest.php b/pkg/enqueue-bundle/Tests/Functional/Events/AsyncListenerTest.php index 6e952ab28..8436181b1 100644 --- a/pkg/enqueue-bundle/Tests/Functional/Events/AsyncListenerTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/Events/AsyncListenerTest.php @@ -18,6 +18,8 @@ class AsyncListenerTest extends WebTestCase { public function setUp() { + $this->markTestSkipped('Configuration for async_events is not yet ready'); + parent::setUp(); /** @var AsyncListener $asyncListener */ diff --git a/pkg/enqueue/Symfony/DiUtils.php b/pkg/enqueue/Symfony/DiUtils.php new file mode 100644 index 000000000..678104312 --- /dev/null +++ b/pkg/enqueue/Symfony/DiUtils.php @@ -0,0 +1,57 @@ +moduleName = $moduleName; + $this->configName = $configName; + } + + public static function create(string $moduleName, string $configName): self + { + return new static($moduleName, $configName); + } + + public function getModuleName(): string + { + return $this->moduleName; + } + + public function getConfigName(): string + { + return $this->configName; + } + + public function reference(string $serviceName, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE): Reference + { + return new Reference($this->format($serviceName), $invalidBehavior); + } + + public function parameter(string $serviceName): string + { + $fullName = $this->format($serviceName); + + return "%$fullName%"; + } + + public function format(string $serviceName): string + { + return sprintf('enqueue.%s.%s.%s', $this->moduleName, $this->configName, $serviceName); + } +} diff --git a/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php b/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php index 975ece8b1..885f6f143 100644 --- a/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php +++ b/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php @@ -2,11 +2,13 @@ namespace Enqueue\Monitoring\Symfony\DependencyInjection; +use Enqueue\Monitoring\ClientMonitoringExtension; +use Enqueue\Monitoring\ConsumerMonitoringExtension; use Enqueue\Monitoring\GenericStatsStorageFactory; use Enqueue\Monitoring\Resources; use Enqueue\Monitoring\StatsStorage; use Enqueue\Monitoring\StatsStorageFactory; -use Enqueue\Symfony\DependencyInjection\FormatTransportNameTrait; +use Enqueue\Symfony\DiUtils; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -16,12 +18,10 @@ */ final class MonitoringFactory { - use FormatTransportNameTrait; - /** - * @var string + * @var DiUtils */ - private $name; + private $diUtils; public function __construct(string $name) { @@ -29,7 +29,7 @@ public function __construct(string $name) throw new \InvalidArgumentException('The name could not be empty.'); } - $this->name = $name; + $this->diUtils = DiUtils::create('monitoring', $name); } public function getConfiguration(string $name): ArrayNodeDefinition @@ -74,15 +74,10 @@ public function getConfiguration(string $name): ArrayNodeDefinition return $builder; } - public function getName(): string - { - return $this->name; - } - public function buildStorage(ContainerBuilder $container, array $config): void { - $storageId = $this->format('storage'); - $storageFactoryId = $this->format('storage.factory'); + $storageId = $this->diUtils->format('storage'); + $storageFactoryId = $this->diUtils->format('storage.factory'); if (isset($config['storage_factory_service'])) { $container->setAlias($storageFactoryId, $config['storage_factory_service']); @@ -99,4 +94,22 @@ public function buildStorage(ContainerBuilder $container, array $config): void ->addArgument($config) ; } + + public function buildClientExtension(ContainerBuilder $container, array $config): void + { + $container->register($this->diUtils->format('client_extension'), ClientMonitoringExtension::class) + ->addArgument($this->diUtils->reference('storage')) + ->addArgument(new Reference('logger')) + ->addTag('enqueue.client_extension', ['client' => $this->diUtils->getConfigName()]) + ; + } + + public function buildConsumerExtension(ContainerBuilder $container, array $config): void + { + $container->register($this->diUtils->format('consumer_extension'), ConsumerMonitoringExtension::class) + ->addArgument($this->diUtils->reference('storage')) + ->addTag('enqueue.consumption_extension', ['client' => $this->diUtils->getConfigName()]) + ->addTag('enqueue.transport.consumption_extension', ['transport' => $this->diUtils->getConfigName()]) + ; + } } From 3e9a36786978c723b7100a9c81ee163c7cd1f5aa Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Mon, 12 Nov 2018 15:52:37 +0200 Subject: [PATCH 03/18] multi client configuration --- .../DependencyInjection/EnqueueExtension.php | 24 +- .../DependencyInjection/ConfigurationTest.php | 295 ++++++++++-------- .../EnqueueExtensionTest.php | 180 +++++++---- 3 files changed, 293 insertions(+), 206 deletions(-) diff --git a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php index 1b015f86f..a8dd3b762 100644 --- a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php +++ b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php @@ -87,10 +87,7 @@ public function load(array $configs, ContainerBuilder $container): void $container->setParameter('enqueue.transports', $transportNames); $container->setParameter('enqueue.clients', $clientNames); - if ($clientNames) { - $this->setupAutowiringForProcessors($container, $clientNames); - } - + $this->setupAutowiringForProcessors($config, $container); $this->loadAsyncCommands($config, $container); // extensions @@ -169,8 +166,19 @@ private function registerJobQueueDoctrineEntityMapping(ContainerBuilder $contain } } - private function setupAutowiringForProcessors(ContainerBuilder $container, array $clientNames) + private function setupAutowiringForProcessors(array $config, ContainerBuilder $container) { + $configNames = []; + foreach ($config as $name => $modules) { + if (isset($modules['client'])) { + $configNames[] = $name; + } + } + + if (false == $configNames) { + return; + } + $topicSubscriber = $container->registerForAutoconfiguration(TopicSubscriberInterface::class) ->setPublic(true) ; @@ -179,9 +187,9 @@ private function setupAutowiringForProcessors(ContainerBuilder $container, array ->setPublic(true) ; - foreach ($clientNames as $clientName) { - $topicSubscriber->addTag('enqueue.topic_subscriber', ['client' => $clientName]); - $commandSubscriber->addTag('enqueue.command_subscriber', ['client' => $clientName]); + foreach ($configNames as $configName) { + $topicSubscriber->addTag('enqueue.topic_subscriber', ['client' => $configName]); + $commandSubscriber->addTag('enqueue.command_subscriber', ['client' => $configName]); } } diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php index 76634af64..3e84ea470 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php @@ -36,8 +36,8 @@ public function testShouldProcessNullAsDefaultNullTransport() $config = $processor->processConfiguration($configuration, [null]); $this->assertConfigEquals([ - 'transport' => [ - 'default' => ['dsn' => 'null:'], + 'default' => [ + 'transport' => ['dsn' => 'null:'], ], ], $config); } @@ -50,8 +50,8 @@ public function testShouldProcessStringAsDefaultDsnTransport() $config = $processor->processConfiguration($configuration, ['foo://bar?option=val']); $this->assertConfigEquals([ - 'transport' => [ - 'default' => ['dsn' => 'foo://bar?option=val'], + 'default' => [ + 'transport' => ['dsn' => 'foo://bar?option=val'], ], ], $config); } @@ -61,67 +61,39 @@ public function testShouldProcessEmptyArrayAsDefaultNullTransport() $configuration = new Configuration(true); $processor = new Processor(); - $config = $processor->processConfiguration($configuration, ['foo://bar?option=val']); + $config = $processor->processConfiguration($configuration, [[]]); $this->assertConfigEquals([ - 'transport' => [ - 'default' => ['dsn' => 'foo://bar?option=val'], + 'default' => [ + 'transport' => ['dsn' => 'null:'], ], ], $config); } - public function testShouldProcessSingleTransportAsDefault() + public function testShouldProcessSeveralTransports() { $configuration = new Configuration(true); $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => 'foo://bar?option=val', - ]]); - - $this->assertConfigEquals([ - 'transport' => [ - 'default' => ['dsn' => 'foo://bar?option=val'], + 'default' => [ + 'transport' => 'default:', ], - ], $config); - } - - public function testShouldProcessTransportWithDsnKeyAsDefault() - { - $configuration = new Configuration(true); - - $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [[ - 'transport' => [ - 'dsn' => 'foo://bar?option=val', + 'foo' => [ + 'transport' => 'foo:', ], ]]); $this->assertConfigEquals([ - 'transport' => [ - 'default' => ['dsn' => 'foo://bar?option=val'], - ], - ], $config); - } - - public function testShouldProcessSeveralTransports() - { - $configuration = new Configuration(true); - - $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [[ - 'transport' => [ - 'default' => ['dsn' => 'default:'], - 'foo' => ['dsn' => 'foo:'], - 'bar' => ['dsn' => 'bar:'], + 'default' => [ + 'transport' => [ + 'dsn' => 'default:', + ], ], - ]]); - - $this->assertConfigEquals([ - 'transport' => [ - 'default' => ['dsn' => 'default:'], - 'foo' => ['dsn' => 'foo:'], - 'bar' => ['dsn' => 'bar:'], + 'foo' => [ + 'transport' => [ + 'dsn' => 'foo:', + ], ], ], $config); } @@ -136,8 +108,8 @@ public function testTransportFactoryShouldValidateEachTransportAccordingToItsRul $this->expectExceptionMessage('Both options factory_class and factory_service are set. Please choose one.'); $processor->processConfiguration($configuration, [ [ - 'transport' => [ - 'default' => [ + 'default' => [ + 'transport' => [ 'factory_class' => 'aClass', 'factory_service' => 'aService', ], @@ -154,19 +126,21 @@ public function testShouldUseDefaultConfigurationIfNothingIsConfiguredAtAll() $config = $processor->processConfiguration($configuration, [[]]); $this->assertEquals([ - 'transport' => ['default' => ['dsn' => 'null:']], - 'consumption' => [ - 'receive_timeout' => 10000, - ], - 'job' => false, - 'async_events' => ['enabled' => false], - 'async_commands' => ['enabled' => false], - 'extensions' => [ - 'doctrine_ping_connection_extension' => false, - 'doctrine_clear_identity_map_extension' => false, - 'signal_extension' => function_exists('pcntl_signal_dispatch'), - 'reply_extension' => true, - ], + 'default' => [ + 'transport' => ['dsn' => 'null:'], + 'consumption' => [ + 'receive_timeout' => 10000, + ], +// 'job' => false, +// 'async_events' => ['enabled' => false], + 'async_commands' => ['enabled' => false], + 'extensions' => [ + 'doctrine_ping_connection_extension' => false, + 'doctrine_clear_identity_map_extension' => false, + 'signal_extension' => function_exists('pcntl_signal_dispatch'), + 'reply_extension' => true, + ], + ] ], $config); } @@ -176,53 +150,62 @@ public function testShouldSetDefaultConfigurationForClient() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => 'null:', - 'client' => null, + 'default' => [ + 'transport' => 'null:', + 'client' => null, + ], ]]); $this->assertConfigEquals([ - 'client' => [ - 'prefix' => 'enqueue', - 'app_name' => 'app', - 'router_processor' => 'enqueue.client.default.router_processor', - 'router_topic' => 'default', - 'router_queue' => 'default', - 'default_processor_queue' => 'default', - 'traceable_producer' => true, - 'redelivered_delay_time' => 0, - ], + 'default' => [ + 'client' => [ + 'prefix' => 'enqueue', + 'app_name' => 'app', + 'router_processor' => null, + 'router_topic' => 'default', + 'router_queue' => 'default', + 'default_processor_queue' => 'default', + 'traceable_producer' => true, + 'redelivered_delay_time' => 0, + ], + ] ], $config); } public function testThrowExceptionIfRouterTopicIsEmpty() { $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('The path "enqueue.client.router_topic" cannot contain an empty value, but got "".'); + $this->expectExceptionMessage('The path "enqueue.default.client.router_topic" cannot contain an empty value, but got "".'); $configuration = new Configuration(true); $processor = new Processor(); $processor->processConfiguration($configuration, [[ - 'transport' => ['dsn' => 'null:'], - 'client' => [ - 'router_topic' => '', - ], + 'default' => [ + 'transport' => ['dsn' => 'null:'], + 'client' => [ + 'router_topic' => '', + ], + ] ]]); } public function testThrowExceptionIfRouterQueueIsEmpty() { $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('The path "enqueue.client.router_queue" cannot contain an empty value, but got "".'); + $this->expectExceptionMessage('The path "enqueue.default.client.router_queue" cannot contain an empty value, but got "".'); $configuration = new Configuration(true); $processor = new Processor(); $processor->processConfiguration($configuration, [[ - 'transport' => ['dsn' => 'null:'], - 'client' => [ - 'router_queue' => '', + 'default' => [ + 'transport' => ['dsn' => 'null:'], + 'client' => [ + 'router_queue' => '', + ], ], + ]]); } @@ -233,17 +216,21 @@ public function testShouldThrowExceptionIfDefaultProcessorQueueIsEmpty() $processor = new Processor(); $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('The path "enqueue.client.default_processor_queue" cannot contain an empty value, but got "".'); + $this->expectExceptionMessage('The path "enqueue.default.client.default_processor_queue" cannot contain an empty value, but got "".'); $processor->processConfiguration($configuration, [[ - 'transport' => ['dsn' => 'null:'], - 'client' => [ - 'default_processor_queue' => '', + 'default' => [ + 'transport' => ['dsn' => 'null:'], + 'client' => [ + 'default_processor_queue' => '', + ], ], ]]); } public function testJobShouldBeDisabledByDefault() { + $this->markTestSkipped('Configuration for jobs is not yet ready'); + $configuration = new Configuration(true); $processor = new Processor(); @@ -258,6 +245,8 @@ public function testJobShouldBeDisabledByDefault() public function testCouldEnableJob() { + $this->markTestSkipped('Configuration for jobs is not yet ready'); + $configuration = new Configuration(true); $processor = new Processor(); @@ -276,14 +265,14 @@ public function testDoctrinePingConnectionExtensionShouldBeDisabledByDefault() $configuration = new Configuration(true); $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], - ]]); + $config = $processor->processConfiguration($configuration, [[]]); $this->assertArraySubset([ - 'extensions' => [ - 'doctrine_ping_connection_extension' => false, - ], + 'default' => [ + 'extensions' => [ + 'doctrine_ping_connection_extension' => false, + ], + ] ], $config); } @@ -293,16 +282,20 @@ public function testDoctrinePingConnectionExtensionCouldBeEnabled() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], - 'extensions' => [ - 'doctrine_ping_connection_extension' => true, - ], + 'default' => [ + 'transport' => null, + 'extensions' => [ + 'doctrine_ping_connection_extension' => true, + ], + ] ]]); $this->assertArraySubset([ - 'extensions' => [ - 'doctrine_ping_connection_extension' => true, - ], + 'default' => [ + 'extensions' => [ + 'doctrine_ping_connection_extension' => true, + ], + ] ], $config); } @@ -311,13 +304,13 @@ public function testDoctrineClearIdentityMapExtensionShouldBeDisabledByDefault() $configuration = new Configuration(true); $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], - ]]); + $config = $processor->processConfiguration($configuration, [[]]); $this->assertArraySubset([ - 'extensions' => [ - 'doctrine_clear_identity_map_extension' => false, + 'default' => [ + 'extensions' => [ + 'doctrine_clear_identity_map_extension' => false, + ], ], ], $config); } @@ -328,15 +321,19 @@ public function testDoctrineClearIdentityMapExtensionCouldBeEnabled() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], - 'extensions' => [ - 'doctrine_clear_identity_map_extension' => true, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'doctrine_clear_identity_map_extension' => true, + ], ], ]]); $this->assertArraySubset([ - 'extensions' => [ - 'doctrine_clear_identity_map_extension' => true, + 'default' => [ + 'extensions' => [ + 'doctrine_clear_identity_map_extension' => true, + ], ], ], $config); } @@ -349,12 +346,16 @@ public function testSignalExtensionShouldBeEnabledIfPcntlExtensionIsLoaded() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], + 'default' => [ + 'transport' => [], + ], ]]); $this->assertArraySubset([ - 'extensions' => [ - 'signal_extension' => $isLoaded, + 'default' => [ + 'extensions' => [ + 'signal_extension' => $isLoaded, + ], ], ], $config); } @@ -365,15 +366,19 @@ public function testSignalExtensionCouldBeDisabled() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], - 'extensions' => [ - 'signal_extension' => false, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'signal_extension' => false, + ], ], ]]); $this->assertArraySubset([ - 'extensions' => [ - 'signal_extension' => false, + 'default' => [ + 'extensions' => [ + 'signal_extension' => false, + ], ], ], $config); } @@ -384,12 +389,16 @@ public function testReplyExtensionShouldBeEnabledByDefault() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], + 'default' => [ + 'transport' => [], + ], ]]); $this->assertArraySubset([ - 'extensions' => [ - 'reply_extension' => true, + 'default' => [ + 'extensions' => [ + 'reply_extension' => true, + ], ], ], $config); } @@ -400,21 +409,27 @@ public function testReplyExtensionCouldBeDisabled() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], - 'extensions' => [ - 'reply_extension' => false, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'reply_extension' => false, + ], ], ]]); $this->assertArraySubset([ - 'extensions' => [ - 'reply_extension' => false, + 'default' => [ + 'extensions' => [ + 'reply_extension' => false, + ], ], ], $config); } public function testShouldDisableAsyncEventsByDefault() { + $this->markTestSkipped('Configuration for async_events is not yet ready'); + $configuration = new Configuration(true); $processor = new Processor(); @@ -431,6 +446,8 @@ public function testShouldDisableAsyncEventsByDefault() public function testShouldAllowEnableAsyncEvents() { + $this->markTestSkipped('Configuration for async_events is not yet ready'); + $configuration = new Configuration(true); $processor = new Processor(); @@ -466,12 +483,16 @@ public function testShouldSetDefaultConfigurationForConsumption() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], + 'default' => [ + 'transport' => [], + ] ]]); $this->assertArraySubset([ - 'consumption' => [ - 'receive_timeout' => 10000, + 'default' => [ + 'consumption' => [ + 'receive_timeout' => 10000, + ], ], ], $config); } @@ -482,15 +503,19 @@ public function testShouldAllowConfigureConsumption() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'transport' => [], - 'consumption' => [ - 'receive_timeout' => 456, + 'default' => [ + 'transport' => [], + 'consumption' => [ + 'receive_timeout' => 456, + ], ], ]]); $this->assertArraySubset([ - 'consumption' => [ - 'receive_timeout' => 456, + 'default' => [ + 'consumption' => [ + 'receive_timeout' => 456, + ], ], ], $config); } diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php index fda7924b4..894d47a6c 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php @@ -66,8 +66,10 @@ public function testShouldRegisterClientDriver() $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => null, - 'client' => true, + 'default' => [ + 'transport' => null, + 'client' => true, + ], ]], $container); self::assertTrue($container->hasDefinition('enqueue.client.default.driver')); @@ -81,8 +83,10 @@ public function testShouldLoadClientServicesWhenEnabled() $extension = new EnqueueExtension(); $extension->load([[ - 'client' => null, - 'transport' => 'null:', + 'default' => [ + 'client' => null, + 'transport' => 'null:', + ], ]], $container); self::assertTrue($container->hasDefinition('enqueue.client.default.driver')); @@ -97,8 +101,10 @@ public function testShouldUseProducerByDefault() $extension = new EnqueueExtension(); $extension->load([[ - 'client' => null, - 'transport' => 'null', + 'default' => [ + 'client' => null, + 'transport' => 'null', + ], ]], $container); $producer = $container->getDefinition('enqueue.client.default.producer'); @@ -112,10 +118,12 @@ public function testShouldUseMessageProducerIfTraceableProducerOptionSetToFalseE $extension = new EnqueueExtension(); $extension->load([[ - 'client' => [ - 'traceable_producer' => false, + 'default' => [ + 'client' => [ + 'traceable_producer' => false, + ], + 'transport' => 'null:', ], - 'transport' => 'null:', ]], $container); $producer = $container->getDefinition('enqueue.client.default.producer'); @@ -129,8 +137,10 @@ public function testShouldUseTraceableMessageProducerIfDebugEnabled() $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => 'null:', - 'client' => null, + 'default' => [ + 'transport' => 'null:', + 'client' => null, + ], ]], $container); $producer = $container->getDefinition('enqueue.client.default.traceable_producer'); @@ -157,7 +167,9 @@ public function testShouldNotUseTraceableMessageProducerIfDebugDisabledAndNotSet $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => 'null:', + 'default' => [ + 'transport' => 'null:', + ], ]], $container); $this->assertFalse($container->hasDefinition('enqueue.client.default.traceable_producer')); @@ -170,10 +182,12 @@ public function testShouldUseTraceableMessageProducerIfDebugDisabledButTraceable $extension = new EnqueueExtension(); $extension->load([[ - 'client' => [ - 'traceable_producer' => true, + 'default' => [ + 'client' => [ + 'traceable_producer' => true, + ], + 'transport' => 'null:', ], - 'transport' => 'null:', ]], $container); $producer = $container->getDefinition('enqueue.client.default.traceable_producer'); @@ -200,9 +214,11 @@ public function testShouldLoadDelayRedeliveredMessageExtensionIfRedeliveredDelay $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => 'null:', - 'client' => [ - 'redelivered_delay_time' => 12345, + 'default' => [ + 'transport' => 'null:', + 'client' => [ + 'redelivered_delay_time' => 12345, + ], ], ]], $container); @@ -218,9 +234,11 @@ public function testShouldNotLoadDelayRedeliveredMessageExtensionIfRedeliveredDe $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => 'null:', - 'client' => [ - 'redelivered_delay_time' => 0, + 'default' => [ + 'transport' => 'null:', + 'client' => [ + 'redelivered_delay_time' => 0, + ], ], ]], $container); @@ -229,6 +247,8 @@ public function testShouldNotLoadDelayRedeliveredMessageExtensionIfRedeliveredDe public function testShouldLoadJobServicesIfEnabled() { + $this->markTestSkipped('Configuration for jobs is not yet ready'); + $container = $this->getContainerBuilder(true); $extension = new EnqueueExtension(); @@ -243,6 +263,8 @@ public function testShouldLoadJobServicesIfEnabled() public function testShouldNotLoadJobServicesIfDisabled() { + $this->markTestSkipped('Configuration for jobs is not yet ready'); + $container = $this->getContainerBuilder(true); $extension = new EnqueueExtension(); @@ -271,9 +293,11 @@ public function testShouldLoadDoctrinePingConnectionExtensionServiceIfEnabled() $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => [], - 'extensions' => [ - 'doctrine_ping_connection_extension' => true, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'doctrine_ping_connection_extension' => true, + ], ], ]], $container); @@ -287,9 +311,11 @@ public function testShouldNotLoadDoctrinePingConnectionExtensionServiceIfDisable $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => [], - 'extensions' => [ - 'doctrine_ping_connection_extension' => false, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'doctrine_ping_connection_extension' => false, + ], ], ]], $container); @@ -303,9 +329,11 @@ public function testShouldLoadDoctrineClearIdentityMapExtensionServiceIfEnabled( $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => [], - 'extensions' => [ - 'doctrine_clear_identity_map_extension' => true, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'doctrine_clear_identity_map_extension' => true, + ], ], ]], $container); @@ -319,9 +347,11 @@ public function testShouldNotLoadDoctrineClearIdentityMapExtensionServiceIfDisab $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => [], - 'extensions' => [ - 'doctrine_clear_identity_map_extension' => false, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'doctrine_clear_identity_map_extension' => false, + ], ], ]], $container); @@ -335,10 +365,13 @@ public function testShouldLoadSignalExtensionServiceIfEnabled() $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => [], - 'extensions' => [ - 'signal_extension' => true, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'signal_extension' => true, + ], ], + ]], $container); self::assertTrue($container->hasDefinition('enqueue.consumption.signal_extension')); @@ -351,9 +384,11 @@ public function testShouldNotLoadSignalExtensionServiceIfDisabled() $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => [], - 'extensions' => [ - 'signal_extension' => false, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'signal_extension' => false, + ], ], ]], $container); @@ -367,9 +402,11 @@ public function testShouldLoadReplyExtensionServiceIfEnabled() $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => [], - 'extensions' => [ - 'reply_extension' => true, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'reply_extension' => true, + ], ], ]], $container); @@ -383,9 +420,11 @@ public function testShouldNotLoadReplyExtensionServiceIfDisabled() $extension = new EnqueueExtension(); $extension->load([[ - 'transport' => [], - 'extensions' => [ - 'reply_extension' => false, + 'default' => [ + 'transport' => [], + 'extensions' => [ + 'reply_extension' => false, + ], ], ]], $container); @@ -426,11 +465,13 @@ public function testShouldConfigureQueueConsumer() $extension = new EnqueueExtension(); $extension->load([[ - 'client' => [], - 'transport' => [ - ], - 'consumption' => [ - 'receive_timeout' => 456, + 'default' => [ + 'client' => [], + 'transport' => [ + ], + 'consumption' => [ + 'receive_timeout' => 456, + ], ], ]], $container); @@ -449,11 +490,17 @@ public function testShouldSetPropertyWithAllConfiguredTransports() $extension = new EnqueueExtension(); $extension->load([[ - 'client' => [], - 'transport' => [ - 'default' => ['dsn' => 'default:'], - 'foo' => ['dsn' => 'foo:'], - 'bar' => ['dsn' => 'foo:'], + 'default' => [ + 'transport' => 'default:', + 'client' => [], + ], + 'foo' => [ + 'transport' => 'foo:', + 'client' => [], + ], + 'bar' => [ + 'transport' => 'bar:', + 'client' => [], ], ]], $container); @@ -467,16 +514,21 @@ public function testShouldSetPropertyWithAllConfiguredClients() $extension = new EnqueueExtension(); $extension->load([[ - 'client' => [], - 'transport' => [ - 'default' => ['dsn' => 'default:'], - 'foo' => ['dsn' => 'foo:'], - 'bar' => ['dsn' => 'foo:'], + 'default' => [ + 'transport' => 'default:', + 'client' => [], + ], + 'foo' => [ + 'transport' => 'foo:', + ], + 'bar' => [ + 'transport' => 'bar:', + 'client' => [], ], ]], $container); $this->assertTrue($container->hasParameter('enqueue.clients')); - $this->assertEquals(['default'], $container->getParameter('enqueue.clients')); + $this->assertEquals(['default', 'bar'], $container->getParameter('enqueue.clients')); } public function testShouldLoadProcessAutoconfigureChildDefinition() @@ -485,8 +537,10 @@ public function testShouldLoadProcessAutoconfigureChildDefinition() $extension = new EnqueueExtension(); $extension->load([[ - 'client' => [], - 'transport' => [], + 'default' => [ + 'client' => [], + 'transport' => [], + ] ]], $container); $autoconfigured = $container->getAutoconfiguredInstanceof(); From 9acc6eb96ea00b64a45ac3642d72caf34001418f Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Tue, 13 Nov 2018 10:56:13 +0200 Subject: [PATCH 04/18] multi client configuration --- .../Tests/Functional/App/CustomAppKernel.php | 16 +-- .../Tests/Functional/UseCasesTest.php | 100 ++++++++++++------ .../DependencyInjection/ClientFactory.php | 9 +- 3 files changed, 83 insertions(+), 42 deletions(-) diff --git a/pkg/enqueue-bundle/Tests/Functional/App/CustomAppKernel.php b/pkg/enqueue-bundle/Tests/Functional/App/CustomAppKernel.php index ed05537e4..59015f88a 100644 --- a/pkg/enqueue-bundle/Tests/Functional/App/CustomAppKernel.php +++ b/pkg/enqueue-bundle/Tests/Functional/App/CustomAppKernel.php @@ -16,19 +16,21 @@ class CustomAppKernel extends Kernel private $enqueueConfigId; private $enqueueConfig = [ - 'client' => [ - 'prefix' => 'enqueue', - 'app_name' => '', - 'router_topic' => 'test', - 'router_queue' => 'test', - 'default_processor_queue' => 'test', + 'default' => [ + 'client' => [ + 'prefix' => 'enqueue', + 'app_name' => '', + 'router_topic' => 'test', + 'router_queue' => 'test', + 'default_processor_queue' => 'test', + ], ], ]; public function setEnqueueConfig(array $config) { $this->enqueueConfig = array_replace_recursive($this->enqueueConfig, $config); - $this->enqueueConfig['client']['app_name'] = str_replace('.', '', uniqid('app_name', true)); + $this->enqueueConfig['default']['client']['app_name'] = str_replace('.', '', uniqid('app_name', true)); $this->enqueueConfigId = md5(json_encode($this->enqueueConfig)); $fs = new Filesystem(); diff --git a/pkg/enqueue-bundle/Tests/Functional/UseCasesTest.php b/pkg/enqueue-bundle/Tests/Functional/UseCasesTest.php index 6a9f085bf..474cb8710 100644 --- a/pkg/enqueue-bundle/Tests/Functional/UseCasesTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/UseCasesTest.php @@ -50,69 +50,91 @@ public function provideEnqueueConfigs() $this->assertDirectoryExists($certDir); yield 'amqp_dsn' => [[ - 'transport' => getenv('AMQP_DSN'), + 'default' => [ + 'transport' => getenv('AMQP_DSN'), + ], ]]; yield 'amqps_dsn' => [[ - 'transport' => [ - 'dsn' => getenv('AMQPS_DSN'), - 'ssl_verify' => false, - 'ssl_cacert' => $certDir.'/cacert.pem', - 'ssl_cert' => $certDir.'/cert.pem', - 'ssl_key' => $certDir.'/key.pem', + 'default' => [ + 'transport' => [ + 'dsn' => getenv('AMQPS_DSN'), + 'ssl_verify' => false, + 'ssl_cacert' => $certDir.'/cacert.pem', + 'ssl_cert' => $certDir.'/cert.pem', + 'ssl_key' => $certDir.'/key.pem', + ], ], ]]; yield 'dsn_as_env' => [[ - 'transport' => '%env(AMQP_DSN)%', + 'default' => [ + 'transport' => '%env(AMQP_DSN)%', + ], ]]; yield 'dbal_dsn' => [[ - 'transport' => getenv('DOCTRINE_DSN'), + 'default' => [ + 'transport' => getenv('DOCTRINE_DSN'), + ], ]]; yield 'rabbitmq_stomp' => [[ - 'transport' => [ - 'dsn' => getenv('RABITMQ_STOMP_DSN'), - 'lazy' => false, - 'management_plugin_installed' => true, + 'default' => [ + 'transport' => [ + 'dsn' => getenv('RABITMQ_STOMP_DSN'), + 'lazy' => false, + 'management_plugin_installed' => true, + ], ], ]]; yield 'predis_dsn' => [[ - 'transport' => [ - 'dsn' => getenv('PREDIS_DSN'), - 'lazy' => false, + 'default' => [ + 'transport' => [ + 'dsn' => getenv('PREDIS_DSN'), + 'lazy' => false, + ], ], ]]; yield 'phpredis_dsn' => [[ - 'transport' => [ - 'dsn' => getenv('PHPREDIS_DSN'), - 'lazy' => false, + 'default' => [ + 'transport' => [ + 'dsn' => getenv('PHPREDIS_DSN'), + 'lazy' => false, + ], ], ]]; yield 'fs_dsn' => [[ - 'transport' => 'file://'.sys_get_temp_dir(), + 'default' => [ + 'transport' => 'file://'.sys_get_temp_dir(), + ], ]]; yield 'sqs' => [[ - 'transport' => [ - 'dsn' => getenv('SQS_DSN'), + 'default' => [ + 'transport' => [ + 'dsn' => getenv('SQS_DSN'), + ], ], ]]; yield 'sqs_client' => [[ - 'transport' => [ - 'dsn' => 'sqs:', - 'service' => 'test.sqs_client', - 'factory_service' => 'test.sqs_custom_connection_factory_factory', + 'default' => [ + 'transport' => [ + 'dsn' => 'sqs:', + 'service' => 'test.sqs_client', + 'factory_service' => 'test.sqs_custom_connection_factory_factory', + ], ], ]]; yield 'mongodb_dsn' => [[ - 'transport' => getenv('MONGO_DSN'), + 'default' => [ + 'transport' => getenv('MONGO_DSN'), + ], ]]; // // yield 'gps' => [[ @@ -166,7 +188,9 @@ public function testProducerSendsCommandMessage(array $enqueueConfig) public function testProducerSendsEventMessageViaProduceCommand() { $this->customSetUp([ - 'transport' => getenv('AMQP_DSN'), + 'default' => [ + 'transport' => getenv('AMQP_DSN'), + ], ]); $expectedBody = __METHOD__.time(); @@ -191,7 +215,9 @@ public function testProducerSendsEventMessageViaProduceCommand() public function testProducerSendsCommandMessageViaProduceCommand() { $this->customSetUp([ - 'transport' => getenv('AMQP_DSN'), + 'default' => [ + 'transport' => getenv('AMQP_DSN'), + ], ]); $expectedBody = __METHOD__.time(); @@ -217,7 +243,9 @@ public function testProducerSendsCommandMessageViaProduceCommand() public function testShouldSetupBroker() { $this->customSetUp([ - 'transport' => 'file://'.sys_get_temp_dir(), + 'default' => [ + 'transport' => 'file://'.sys_get_temp_dir(), + ], ]); $command = static::$container->get('test_enqueue.client.setup_broker_command'); @@ -230,7 +258,9 @@ public function testShouldSetupBroker() public function testClientConsumeCommandMessagesFromExplicitlySetQueue() { $this->customSetUp([ - 'transport' => getenv('AMQP_DSN'), + 'default' => [ + 'transport' => getenv('AMQP_DSN'), + ], ]); $command = static::$container->get('test_enqueue.client.consume_command'); @@ -255,7 +285,9 @@ public function testClientConsumeCommandMessagesFromExplicitlySetQueue() public function testClientConsumeMessagesFromExplicitlySetQueue() { $this->customSetUp([ - 'transport' => getenv('AMQP_DSN'), + 'default' => [ + 'transport' => getenv('AMQP_DSN'), + ], ]); $expectedBody = __METHOD__.time(); @@ -280,7 +312,9 @@ public function testClientConsumeMessagesFromExplicitlySetQueue() public function testTransportConsumeMessagesCommandShouldConsumeMessage() { $this->customSetUp([ - 'transport' => getenv('AMQP_DSN'), + 'default' => [ + 'transport' => getenv('AMQP_DSN'), + ], ]); if ($this->getTestQueue() instanceof StompDestination) { diff --git a/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php b/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php index 9873b6c6c..afa5c9b6e 100644 --- a/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php +++ b/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php @@ -80,6 +80,11 @@ public function build(ContainerBuilder $container, array $config, bool $default ->addArgument($this->reference('route_collection')) ; + $routerProcessor = empty($config['router_processor']) + ? $this->format('router_processor') + : $config['router_processor'] + ; + $container->register($this->format('config'), Config::class) ->setArguments([ $config['prefix'], @@ -87,12 +92,12 @@ public function build(ContainerBuilder $container, array $config, bool $default $config['router_topic'], $config['router_queue'], $config['default_processor_queue'], - isset($config['router_processor']) ? $config['router_processor'] : $this->format('router_processor'), + $routerProcessor, // @todo should be driver options. $config['transport'], ]); - $container->setParameter($this->format('router_processor'), $config['router_processor']); + $container->setParameter($this->format('router_processor'), $routerProcessor); $container->setParameter($this->format('router_queue_name'), $config['router_queue']); $container->setParameter($this->format('default_queue_name'), $config['default_processor_queue']); From bbc342f9c787c51f4d354c2c2a71c885ee89e26d Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Tue, 13 Nov 2018 11:15:15 +0200 Subject: [PATCH 05/18] multi client configuration --- .../Functional/Events/AsyncProcessorTest.php | 2 ++ .../Functional/Events/AsyncSubscriberTest.php | 2 ++ .../CalculateRootJobStatusProcessorTest.php | 2 ++ .../Job/DependentJobServiceTest.php | 2 ++ .../Tests/Functional/Job/JobRunnerTest.php | 2 ++ .../Tests/Functional/Job/JobStorageTest.php | 2 ++ .../Tests/Functional/RoutesCommandTest.php | 7 ++++-- .../DependencyInjection/ConfigurationTest.php | 23 +++++++++---------- .../EnqueueExtensionTest.php | 7 +++--- pkg/monitoring/GenericStatsStorageFactory.php | 6 +---- pkg/monitoring/Resources.php | 1 - 11 files changed, 32 insertions(+), 24 deletions(-) diff --git a/pkg/enqueue-bundle/Tests/Functional/Events/AsyncProcessorTest.php b/pkg/enqueue-bundle/Tests/Functional/Events/AsyncProcessorTest.php index 101e5ecec..75ed3ad73 100644 --- a/pkg/enqueue-bundle/Tests/Functional/Events/AsyncProcessorTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/Events/AsyncProcessorTest.php @@ -20,6 +20,8 @@ class AsyncProcessorTest extends WebTestCase { public function setUp() { + $this->markTestSkipped('Configuration for async_events is not yet ready'); + parent::setUp(); /** @var AsyncListener $asyncListener */ diff --git a/pkg/enqueue-bundle/Tests/Functional/Events/AsyncSubscriberTest.php b/pkg/enqueue-bundle/Tests/Functional/Events/AsyncSubscriberTest.php index 6e00eafca..081da0734 100644 --- a/pkg/enqueue-bundle/Tests/Functional/Events/AsyncSubscriberTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/Events/AsyncSubscriberTest.php @@ -18,6 +18,8 @@ class AsyncSubscriberTest extends WebTestCase { public function setUp() { + $this->markTestSkipped('Configuration for async_events is not yet ready'); + parent::setUp(); /** @var AsyncListener $asyncListener */ diff --git a/pkg/enqueue-bundle/Tests/Functional/Job/CalculateRootJobStatusProcessorTest.php b/pkg/enqueue-bundle/Tests/Functional/Job/CalculateRootJobStatusProcessorTest.php index 01346ad8c..0749b8354 100644 --- a/pkg/enqueue-bundle/Tests/Functional/Job/CalculateRootJobStatusProcessorTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/Job/CalculateRootJobStatusProcessorTest.php @@ -12,6 +12,8 @@ class CalculateRootJobStatusProcessorTest extends WebTestCase { public function testCouldBeConstructedByContainer() { + $this->markTestSkipped('Configuration for jobs is not yet ready'); + $instance = static::$container->get(CalculateRootJobStatusProcessor::class); $this->assertInstanceOf(CalculateRootJobStatusProcessor::class, $instance); diff --git a/pkg/enqueue-bundle/Tests/Functional/Job/DependentJobServiceTest.php b/pkg/enqueue-bundle/Tests/Functional/Job/DependentJobServiceTest.php index 1aec06410..adee418ec 100644 --- a/pkg/enqueue-bundle/Tests/Functional/Job/DependentJobServiceTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/Job/DependentJobServiceTest.php @@ -12,6 +12,8 @@ class DependentJobServiceTest extends WebTestCase { public function testCouldBeConstructedByContainer() { + $this->markTestSkipped('Configuration for jobs is not yet ready'); + $instance = static::$container->get(DependentJobService::class); $this->assertInstanceOf(DependentJobService::class, $instance); diff --git a/pkg/enqueue-bundle/Tests/Functional/Job/JobRunnerTest.php b/pkg/enqueue-bundle/Tests/Functional/Job/JobRunnerTest.php index 4aa647f77..c27b48218 100644 --- a/pkg/enqueue-bundle/Tests/Functional/Job/JobRunnerTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/Job/JobRunnerTest.php @@ -12,6 +12,8 @@ class JobRunnerTest extends WebTestCase { public function testCouldBeConstructedByContainer() { + $this->markTestSkipped('Configuration for jobs is not yet ready'); + $instance = static::$container->get(JobRunner::class); $this->assertInstanceOf(JobRunner::class, $instance); diff --git a/pkg/enqueue-bundle/Tests/Functional/Job/JobStorageTest.php b/pkg/enqueue-bundle/Tests/Functional/Job/JobStorageTest.php index 650326ad8..4d4a83316 100644 --- a/pkg/enqueue-bundle/Tests/Functional/Job/JobStorageTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/Job/JobStorageTest.php @@ -12,6 +12,8 @@ class JobStorageTest extends WebTestCase { public function testCouldGetJobStorageAsServiceFromContainer() { + $this->markTestSkipped('Configuration for jobs is not yet ready'); + $instance = static::$container->get(JobStorage::class); $this->assertInstanceOf(JobStorage::class, $instance); diff --git a/pkg/enqueue-bundle/Tests/Functional/RoutesCommandTest.php b/pkg/enqueue-bundle/Tests/Functional/RoutesCommandTest.php index afefe6482..914d771e7 100644 --- a/pkg/enqueue-bundle/Tests/Functional/RoutesCommandTest.php +++ b/pkg/enqueue-bundle/Tests/Functional/RoutesCommandTest.php @@ -26,13 +26,16 @@ public function testShouldDisplayRegisteredTopics() $tester->execute([]); $expected = <<<'OUTPUT' -| topic | theTopic | default (prefixed) | test_topic_subscriber_processor | (hidden) | +| topic | theTopic | default (prefixed) | test_topic_subscriber_processor | (hidden) | OUTPUT; $this->assertSame(0, $tester->getStatusCode()); $this->assertContains($expected, $tester->getDisplay()); } + /** + * @group testit + */ public function testShouldDisplayCommands() { /** @var RoutesCommand $command */ @@ -42,7 +45,7 @@ public function testShouldDisplayCommands() $tester->execute([]); $expected = <<<'OUTPUT' -| command | theCommand | default (prefixed) | test_command_subscriber_processor | (hidden) | +| command | theCommand | default (prefixed) | test_command_subscriber_processor | (hidden) | OUTPUT; $this->assertSame(0, $tester->getStatusCode()); diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php index 3e84ea470..baff83925 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php @@ -140,7 +140,7 @@ public function testShouldUseDefaultConfigurationIfNothingIsConfiguredAtAll() 'signal_extension' => function_exists('pcntl_signal_dispatch'), 'reply_extension' => true, ], - ] + ], ], $config); } @@ -168,7 +168,7 @@ public function testShouldSetDefaultConfigurationForClient() 'traceable_producer' => true, 'redelivered_delay_time' => 0, ], - ] + ], ], $config); } @@ -186,7 +186,7 @@ public function testThrowExceptionIfRouterTopicIsEmpty() 'client' => [ 'router_topic' => '', ], - ] + ], ]]); } @@ -205,7 +205,6 @@ public function testThrowExceptionIfRouterQueueIsEmpty() 'router_queue' => '', ], ], - ]]); } @@ -268,11 +267,11 @@ public function testDoctrinePingConnectionExtensionShouldBeDisabledByDefault() $config = $processor->processConfiguration($configuration, [[]]); $this->assertArraySubset([ - 'default' => [ + 'default' => [ 'extensions' => [ 'doctrine_ping_connection_extension' => false, ], - ] + ], ], $config); } @@ -282,20 +281,20 @@ public function testDoctrinePingConnectionExtensionCouldBeEnabled() $processor = new Processor(); $config = $processor->processConfiguration($configuration, [[ - 'default' => [ + 'default' => [ 'transport' => null, 'extensions' => [ 'doctrine_ping_connection_extension' => true, ], - ] + ], ]]); $this->assertArraySubset([ - 'default' => [ + 'default' => [ 'extensions' => [ 'doctrine_ping_connection_extension' => true, ], - ] + ], ], $config); } @@ -307,7 +306,7 @@ public function testDoctrineClearIdentityMapExtensionShouldBeDisabledByDefault() $config = $processor->processConfiguration($configuration, [[]]); $this->assertArraySubset([ - 'default' => [ + 'default' => [ 'extensions' => [ 'doctrine_clear_identity_map_extension' => false, ], @@ -485,7 +484,7 @@ public function testShouldSetDefaultConfigurationForConsumption() $config = $processor->processConfiguration($configuration, [[ 'default' => [ 'transport' => [], - ] + ], ]]); $this->assertArraySubset([ diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php index 894d47a6c..bb1918b01 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php @@ -122,7 +122,7 @@ public function testShouldUseMessageProducerIfTraceableProducerOptionSetToFalseE 'client' => [ 'traceable_producer' => false, ], - 'transport' => 'null:', + 'transport' => 'null:', ], ]], $container); @@ -139,7 +139,7 @@ public function testShouldUseTraceableMessageProducerIfDebugEnabled() $extension->load([[ 'default' => [ 'transport' => 'null:', - 'client' => null, + 'client' => null, ], ]], $container); @@ -371,7 +371,6 @@ public function testShouldLoadSignalExtensionServiceIfEnabled() 'signal_extension' => true, ], ], - ]], $container); self::assertTrue($container->hasDefinition('enqueue.consumption.signal_extension')); @@ -540,7 +539,7 @@ public function testShouldLoadProcessAutoconfigureChildDefinition() 'default' => [ 'client' => [], 'transport' => [], - ] + ], ]], $container); $autoconfigured = $container->getAutoconfiguredInstanceof(); diff --git a/pkg/monitoring/GenericStatsStorageFactory.php b/pkg/monitoring/GenericStatsStorageFactory.php index 32b3beb8c..f4a257c66 100644 --- a/pkg/monitoring/GenericStatsStorageFactory.php +++ b/pkg/monitoring/GenericStatsStorageFactory.php @@ -28,11 +28,7 @@ public function create($config): StatsStorage return new $storageClass(1 === count($config) ? $config['dsn'] : $config); } - throw new \LogicException(sprintf( - 'A given scheme "%s" is not supported.', - $dsn->getScheme(), - Resources::class - )); + throw new \LogicException(sprintf('A given scheme "%s" is not supported.', $dsn->getScheme())); } private function findStorageClass(Dsn $dsn, array $factories): ?string diff --git a/pkg/monitoring/Resources.php b/pkg/monitoring/Resources.php index 86419a0e5..013559aef 100644 --- a/pkg/monitoring/Resources.php +++ b/pkg/monitoring/Resources.php @@ -2,7 +2,6 @@ namespace Enqueue\Monitoring; - final class Resources { /** From 263949ac3a941572e8b94d870f6444d1846f8678 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Tue, 13 Nov 2018 12:25:16 +0200 Subject: [PATCH 06/18] multi client configuration --- .../DependencyInjection/Configuration.php | 19 +- .../DependencyInjection/ClientFactory.php | 2 +- .../DependencyInjection/TransportFactory.php | 5 +- .../TransportFactoryTest.php | 162 ++++++++++-------- .../DependencyInjection/MonitoringFactory.php | 2 +- 5 files changed, 101 insertions(+), 89 deletions(-) diff --git a/pkg/enqueue-bundle/DependencyInjection/Configuration.php b/pkg/enqueue-bundle/DependencyInjection/Configuration.php index 7b75c0d71..e2d9dfde2 100644 --- a/pkg/enqueue-bundle/DependencyInjection/Configuration.php +++ b/pkg/enqueue-bundle/DependencyInjection/Configuration.php @@ -48,26 +48,15 @@ public function getConfigTreeBuilder(): TreeBuilder }) ; - $transportFactory = new TransportFactory('default'); - - $transportConfig = $transportFactory->getConfiguration('transport'); - $transportConfig->isRequired(); - - $consumerConfig = $transportFactory->getQueueConsumerConfiguration('consumption'); - - $clientConfig = (new ClientFactory('default'))->getConfiguration('client', $this->debug); - - $monitoringConfig = (new MonitoringFactory('default'))->getConfiguration('monitoring'); - $rootNode ->requiresAtLeastOneElement() ->useAttributeAsKey('key') ->arrayPrototype() ->children() - ->append($transportConfig) - ->append($consumerConfig) - ->append($clientConfig) - ->append($monitoringConfig) + ->append(TransportFactory::getConfiguration()) + ->append(TransportFactory::getQueueConsumerConfiguration()) + ->append(ClientFactory::getConfiguration($this->debug)) + ->append(MonitoringFactory::getConfiguration()) ->arrayNode('extensions')->addDefaultsIfNotSet()->children() ->booleanNode('doctrine_ping_connection_extension')->defaultFalse()->end() ->booleanNode('doctrine_clear_identity_map_extension')->defaultFalse()->end() diff --git a/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php b/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php index afa5c9b6e..b50efa545 100644 --- a/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php +++ b/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php @@ -50,7 +50,7 @@ public function __construct(string $name) $this->name = $name; } - public function getConfiguration(string $name, bool $debug): NodeDefinition + public static function getConfiguration(bool $debug, string $name = 'client'): NodeDefinition { $builder = new ArrayNodeDefinition($name); diff --git a/pkg/enqueue/Symfony/DependencyInjection/TransportFactory.php b/pkg/enqueue/Symfony/DependencyInjection/TransportFactory.php index 70b2a84ed..5d98d3f8d 100644 --- a/pkg/enqueue/Symfony/DependencyInjection/TransportFactory.php +++ b/pkg/enqueue/Symfony/DependencyInjection/TransportFactory.php @@ -41,7 +41,7 @@ public function __construct(string $name) $this->name = $name; } - public function getConfiguration(string $name): NodeDefinition + public static function getConfiguration(string $name = 'transport'): NodeDefinition { $knownSchemes = array_keys(Resources::getKnownSchemes()); $availableSchemes = array_keys(Resources::getAvailableSchemes()); @@ -74,6 +74,7 @@ public function getConfiguration(string $name): NodeDefinition throw new \LogicException(sprintf('The value must be array, null or string. Got "%s"', gettype($v))); }) ->end() + ->isRequired() ->ignoreExtraKeys(false) ->children() ->scalarNode('dsn') @@ -100,7 +101,7 @@ public function getConfiguration(string $name): NodeDefinition return $builder; } - public function getQueueConsumerConfiguration(string $name): ArrayNodeDefinition + public static function getQueueConsumerConfiguration(string $name = 'consumption'): ArrayNodeDefinition { $builder = new ArrayNodeDefinition($name); diff --git a/pkg/enqueue/Tests/Symfony/DependencyInjection/TransportFactoryTest.php b/pkg/enqueue/Tests/Symfony/DependencyInjection/TransportFactoryTest.php index 64afdc9b4..05a54ccd7 100644 --- a/pkg/enqueue/Tests/Symfony/DependencyInjection/TransportFactoryTest.php +++ b/pkg/enqueue/Tests/Symfony/DependencyInjection/TransportFactoryTest.php @@ -44,15 +44,19 @@ public function testThrowIfEmptyNameGivenOnConstruction() public function testShouldAllowAddConfigurationAsStringDsn() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); + $processor = new Processor(); - $config = $processor->process($tb->buildTree(), ['dsn://']); + $config = $processor->process($tb->buildTree(), [['transport' => 'dsn://']]); - $this->assertEquals(['dsn' => 'dsn://'], $config); + $this->assertEquals([ + 'transport' => [ + 'dsn' => 'dsn://', + ], + ], $config); } /** @@ -62,191 +66,209 @@ public function testShouldAllowAddConfigurationAsStringDsn() */ public function testShouldAllowAddConfigurationAsDsnWithoutSlashes() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); + $processor = new Processor(); - $config = $processor->process($tb->buildTree(), ['dsn:']); + $config = $processor->process($tb->buildTree(), [['transport' => 'dsn:']]); - $this->assertEquals(['dsn' => 'dsn:'], $config); + $this->assertEquals([ + 'transport' => [ + 'dsn' => 'dsn:', + ], + ], $config); } public function testShouldSetNullTransportIfNullGiven() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); + $processor = new Processor(); + $config = $processor->process($tb->buildTree(), [['transport' => null]]); - $config = $processor->process($tb->buildTree(), [null]); - $this->assertEquals(['dsn' => 'null:'], $config); + $this->assertEquals([ + 'transport' => [ + 'dsn' => 'null:', + ], + ], $config); } public function testShouldSetNullTransportIfEmptyStringGiven() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); + $processor = new Processor(); + $config = $processor->process($tb->buildTree(), [['transport' => '']]); - $config = $processor->process($tb->buildTree(), ['']); - $this->assertEquals(['dsn' => 'null:'], $config); + $this->assertEquals([ + 'transport' => [ + 'dsn' => 'null:', + ], + ], $config); } public function testShouldSetNullTransportIfEmptyArrayGiven() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); + $processor = new Processor(); + $config = $processor->process($tb->buildTree(), [['transport' => []]]); - $config = $processor->process($tb->buildTree(), [[]]); - $this->assertEquals(['dsn' => 'null:'], $config); + $this->assertEquals([ + 'transport' => [ + 'dsn' => 'null:', + ], + ], $config); } public function testThrowIfEmptyDsnGiven() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); - $processor = new Processor(); + $rootNode->append(TransportFactory::getConfiguration()); + $processor = new Processor(); $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('The path "foo.dsn" cannot contain an empty value, but got "".'); - $processor->process($tb->buildTree(), [['dsn' => '']]); + $this->expectExceptionMessage('The path "foo.transport.dsn" cannot contain an empty value, but got "".'); + $processor->process($tb->buildTree(), [['transport' => ['dsn' => '']]]); } public function testThrowIfFactoryClassAndFactoryServiceSetAtTheSameTime() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); + $processor = new Processor(); $this->expectException(\LogicException::class); $this->expectExceptionMessage('Both options factory_class and factory_service are set. Please choose one.'); $processor->process($tb->buildTree(), [[ - 'dsn' => 'foo:', - 'factory_class' => 'aFactoryClass', - 'factory_service' => 'aFactoryService', - ]]); + 'transport' => [ + 'dsn' => 'foo:', + 'factory_class' => 'aFactoryClass', + 'factory_service' => 'aFactoryService', + ]]]); } public function testThrowIfConnectionFactoryClassUsedWithFactoryClassAtTheSameTime() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); + $processor = new Processor(); $this->expectException(\LogicException::class); $this->expectExceptionMessage('The option connection_factory_class must not be used with factory_class or factory_service at the same time. Please choose one.'); $processor->process($tb->buildTree(), [[ - 'dsn' => 'foo:', - 'connection_factory_class' => 'aFactoryClass', - 'factory_service' => 'aFactoryService', - ]]); + 'transport' => [ + 'dsn' => 'foo:', + 'connection_factory_class' => 'aFactoryClass', + 'factory_service' => 'aFactoryService', + ]]]); } public function testThrowIfConnectionFactoryClassUsedWithFactoryServiceAtTheSameTime() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); $processor = new Processor(); $this->expectException(\LogicException::class); $this->expectExceptionMessage('The option connection_factory_class must not be used with factory_class or factory_service at the same time. Please choose one.'); $processor->process($tb->buildTree(), [[ - 'dsn' => 'foo:', - 'connection_factory_class' => 'aFactoryClass', - 'factory_service' => 'aFactoryService', - ]]); + 'transport' => [ + 'dsn' => 'foo:', + 'connection_factory_class' => 'aFactoryClass', + 'factory_service' => 'aFactoryService', + ]]]); } public function testShouldAllowSetFactoryClass() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); $processor = new Processor(); $config = $processor->process($tb->buildTree(), [[ - 'dsn' => 'foo:', - 'factory_class' => 'theFactoryClass', - ]]); + 'transport' => [ + 'dsn' => 'foo:', + 'factory_class' => 'theFactoryClass', + ]]]); - $this->assertArrayHasKey('factory_class', $config); - $this->assertSame('theFactoryClass', $config['factory_class']); + $this->assertArrayHasKey('factory_class', $config['transport']); + $this->assertSame('theFactoryClass', $config['transport']['factory_class']); } public function testShouldAllowSetFactoryService() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); $processor = new Processor(); $config = $processor->process($tb->buildTree(), [[ - 'dsn' => 'foo:', - 'factory_service' => 'theFactoryService', - ]]); + 'transport' => [ + 'dsn' => 'foo:', + 'factory_service' => 'theFactoryService', + ]]]); - $this->assertArrayHasKey('factory_service', $config); - $this->assertSame('theFactoryService', $config['factory_service']); + $this->assertArrayHasKey('factory_service', $config['transport']); + $this->assertSame('theFactoryService', $config['transport']['factory_service']); } public function testShouldAllowSetConnectionFactoryClass() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); $processor = new Processor(); $config = $processor->process($tb->buildTree(), [[ - 'dsn' => 'foo:', - 'connection_factory_class' => 'theFactoryClass', - ]]); + 'transport' => [ + 'dsn' => 'foo:', + 'connection_factory_class' => 'theFactoryClass', + ]]]); - $this->assertArrayHasKey('connection_factory_class', $config); - $this->assertSame('theFactoryClass', $config['connection_factory_class']); + $this->assertArrayHasKey('connection_factory_class', $config['transport']); + $this->assertSame('theFactoryClass', $config['transport']['connection_factory_class']); } public function testThrowIfExtraOptionGiven() { - $transport = new TransportFactory('default'); $tb = new TreeBuilder(); $rootNode = $tb->root('foo'); - $transport->addTransportConfiguration($rootNode); + $rootNode->append(TransportFactory::getConfiguration()); $processor = new Processor(); - $config = $processor->process($tb->buildTree(), [['dsn' => 'foo:', 'extraOption' => 'aVal']]); - $this->assertEquals( - ['dsn' => 'foo:', 'extraOption' => 'aVal'], - $config + $config = $processor->process($tb->buildTree(), [['transport' => ['dsn' => 'foo:', 'extraOption' => 'aVal']]]); + $this->assertEquals([ + 'transport' => [ + 'dsn' => 'foo:', + 'extraOption' => 'aVal', + ]], $config ); } diff --git a/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php b/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php index 885f6f143..201bfa569 100644 --- a/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php +++ b/pkg/monitoring/Symfony/DependencyInjection/MonitoringFactory.php @@ -32,7 +32,7 @@ public function __construct(string $name) $this->diUtils = DiUtils::create('monitoring', $name); } - public function getConfiguration(string $name): ArrayNodeDefinition + public static function getConfiguration(string $name = 'monitoring'): ArrayNodeDefinition { $builder = new ArrayNodeDefinition($name); From 6e0cab6bad4f29b6cd7c7537b7052c1551adde24 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Tue, 13 Nov 2018 12:29:29 +0200 Subject: [PATCH 07/18] multi client configuration --- .../DependencyInjection/TransportFactoryTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/enqueue/Tests/Symfony/DependencyInjection/TransportFactoryTest.php b/pkg/enqueue/Tests/Symfony/DependencyInjection/TransportFactoryTest.php index 05a54ccd7..7e021ca03 100644 --- a/pkg/enqueue/Tests/Symfony/DependencyInjection/TransportFactoryTest.php +++ b/pkg/enqueue/Tests/Symfony/DependencyInjection/TransportFactoryTest.php @@ -70,7 +70,7 @@ public function testShouldAllowAddConfigurationAsDsnWithoutSlashes() $rootNode = $tb->root('foo'); $rootNode->append(TransportFactory::getConfiguration()); - + $processor = new Processor(); $config = $processor->process($tb->buildTree(), [['transport' => 'dsn:']]); @@ -161,7 +161,7 @@ public function testThrowIfFactoryClassAndFactoryServiceSetAtTheSameTime() 'dsn' => 'foo:', 'factory_class' => 'aFactoryClass', 'factory_service' => 'aFactoryService', - ]]]); + ], ]]); } public function testThrowIfConnectionFactoryClassUsedWithFactoryClassAtTheSameTime() @@ -180,7 +180,7 @@ public function testThrowIfConnectionFactoryClassUsedWithFactoryClassAtTheSameTi 'dsn' => 'foo:', 'connection_factory_class' => 'aFactoryClass', 'factory_service' => 'aFactoryService', - ]]]); + ], ]]); } public function testThrowIfConnectionFactoryClassUsedWithFactoryServiceAtTheSameTime() @@ -198,7 +198,7 @@ public function testThrowIfConnectionFactoryClassUsedWithFactoryServiceAtTheSame 'dsn' => 'foo:', 'connection_factory_class' => 'aFactoryClass', 'factory_service' => 'aFactoryService', - ]]]); + ], ]]); } public function testShouldAllowSetFactoryClass() @@ -213,7 +213,7 @@ public function testShouldAllowSetFactoryClass() 'transport' => [ 'dsn' => 'foo:', 'factory_class' => 'theFactoryClass', - ]]]); + ], ]]); $this->assertArrayHasKey('factory_class', $config['transport']); $this->assertSame('theFactoryClass', $config['transport']['factory_class']); @@ -231,7 +231,7 @@ public function testShouldAllowSetFactoryService() 'transport' => [ 'dsn' => 'foo:', 'factory_service' => 'theFactoryService', - ]]]); + ], ]]); $this->assertArrayHasKey('factory_service', $config['transport']); $this->assertSame('theFactoryService', $config['transport']['factory_service']); @@ -249,7 +249,7 @@ public function testShouldAllowSetConnectionFactoryClass() 'transport' => [ 'dsn' => 'foo:', 'connection_factory_class' => 'theFactoryClass', - ]]]); + ], ]]); $this->assertArrayHasKey('connection_factory_class', $config['transport']); $this->assertSame('theFactoryClass', $config['transport']['connection_factory_class']); @@ -268,7 +268,7 @@ public function testThrowIfExtraOptionGiven() 'transport' => [ 'dsn' => 'foo:', 'extraOption' => 'aVal', - ]], $config + ], ], $config ); } From 7c486c5e35042fe77b5bf064bc97c63baf0cf0b0 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Tue, 13 Nov 2018 13:25:39 +0200 Subject: [PATCH 08/18] multi client configuration --- pkg/simple-client/SimpleClient.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/simple-client/SimpleClient.php b/pkg/simple-client/SimpleClient.php index de5922df7..118a43532 100644 --- a/pkg/simple-client/SimpleClient.php +++ b/pkg/simple-client/SimpleClient.php @@ -299,8 +299,7 @@ private function createConfiguration(): NodeInterface return ['transport' => ['dsn' => 'null:']]; }); - $transportNode = $rootNode->children()->arrayNode('transport'); - (new TransportFactory('default'))->addTransportConfiguration($transportNode); + $rootNode->children()->append(TransportFactory::getConfiguration()); $rootNode->children() ->arrayNode('client') From 152e9cab6a819252d13149babd36595adf29afd8 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Wed, 14 Nov 2018 10:24:29 +0200 Subject: [PATCH 09/18] multi client configuration --- .../DependencyInjection/EnqueueExtension.php | 29 +++++- .../Profiler/MessageQueueCollector.php | 21 ++-- .../Resources/config/client.yml | 8 -- .../Profiler/MessageQueueCollectorTest.php | 97 ++++++++++++------- 4 files changed, 96 insertions(+), 59 deletions(-) delete mode 100644 pkg/enqueue-bundle/Resources/config/client.yml diff --git a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php index a8dd3b762..1cc4a47cc 100644 --- a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php +++ b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php @@ -6,6 +6,7 @@ use Enqueue\AsyncEventDispatcher\DependencyInjection\AsyncEventDispatcherExtension; use Enqueue\Bundle\Consumption\Extension\DoctrineClearIdentityMapExtension; use Enqueue\Bundle\Consumption\Extension\DoctrinePingConnectionExtension; +use Enqueue\Bundle\Profiler\MessageQueueCollector; use Enqueue\Client\CommandSubscriberInterface; use Enqueue\Client\TopicSubscriberInterface; use Enqueue\Consumption\Extension\ReplyExtension; @@ -14,6 +15,7 @@ use Enqueue\Monitoring\Symfony\DependencyInjection\MonitoringFactory; use Enqueue\Symfony\Client\DependencyInjection\ClientFactory; use Enqueue\Symfony\DependencyInjection\TransportFactory; +use Enqueue\Symfony\DiUtils; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -87,6 +89,7 @@ public function load(array $configs, ContainerBuilder $container): void $container->setParameter('enqueue.transports', $transportNames); $container->setParameter('enqueue.clients', $clientNames); + $this->loadMessageQueueCollector($config, $container); $this->setupAutowiringForProcessors($config, $container); $this->loadAsyncCommands($config, $container); @@ -96,8 +99,6 @@ public function load(array $configs, ContainerBuilder $container): void $this->loadSignalExtension($config, $container); $this->loadReplyExtension($config, $container); - // @todo register MessageQueueCollector - // if ($config['job']) { // if (!class_exists(Job::class)) { // throw new \LogicException('Seems "enqueue/job-queue" is not installed. Please fix this issue.'); @@ -301,4 +302,28 @@ private function loadAsyncCommands(array $config, ContainerBuilder $container): $extension = new AsyncCommandExtension(); $extension->load(['clients' => $configNames], $container); } + + private function loadMessageQueueCollector(array $config, ContainerBuilder $container) + { + $configNames = []; + foreach ($config as $name => $modules) { + if (isset($modules['client'])) { + $configNames[] = $name; + } + } + + if (false == $configNames) { + return; + } + + $service = $container->register('enqueue.profiler.message_queue_collector', MessageQueueCollector::class); + $service->addTag('data_collector', [ + 'template' => '@Enqueue/Profiler/panel.html.twig', + 'id' => 'enqueue.message_queue' + ]); + + foreach ($configNames as $configName) { + $service->addMethodCall('addProducer', [$configName, DiUtils::create('client', $configName)->reference('producer')]); + } + } } diff --git a/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php b/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php index 86bdd7456..e03db0362 100644 --- a/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php +++ b/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php @@ -15,14 +15,11 @@ class MessageQueueCollector extends DataCollector /** * @var ProducerInterface */ - private $producer; + private $producers; - /** - * @param ProducerInterface $producer - */ - public function __construct(ProducerInterface $producer) + public function addProducer(string $name, ProducerInterface $producer): void { - $this->producer = $producer; + $this->producers[$name] = $producer; } /** @@ -30,12 +27,12 @@ public function __construct(ProducerInterface $producer) */ public function collect(Request $request, Response $response, \Exception $exception = null) { - $this->data = [ - 'sent_messages' => [], - ]; + $this->data = []; - if ($this->producer instanceof TraceableProducer) { - $this->data['sent_messages'] = $this->producer->getTraces(); + foreach ($this->producers as $name => $producer) { + if ($producer instanceof TraceableProducer) { + $this->data[$name] = $producer->getTraces(); + } } } @@ -44,7 +41,7 @@ public function collect(Request $request, Response $response, \Exception $except */ public function getSentMessages() { - return $this->data['sent_messages']; + return $this->data; } /** diff --git a/pkg/enqueue-bundle/Resources/config/client.yml b/pkg/enqueue-bundle/Resources/config/client.yml deleted file mode 100644 index a7b9a1b80..000000000 --- a/pkg/enqueue-bundle/Resources/config/client.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - # todo - enqueue.profiler.message_queue_collector: - class: 'Enqueue\Bundle\Profiler\MessageQueueCollector' - arguments: - - '@enqueue.client.default.producer' - tags: - - { name: 'data_collector', template: '@Enqueue/Profiler/panel.html.twig', id: 'enqueue.message_queue' } diff --git a/pkg/enqueue-bundle/Tests/Unit/Profiler/MessageQueueCollectorTest.php b/pkg/enqueue-bundle/Tests/Unit/Profiler/MessageQueueCollectorTest.php index bdc21bf29..d8bfa0996 100644 --- a/pkg/enqueue-bundle/Tests/Unit/Profiler/MessageQueueCollectorTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/Profiler/MessageQueueCollectorTest.php @@ -21,64 +21,87 @@ public function testShouldExtendDataCollectorClass() $this->assertClassExtends(DataCollector::class, MessageQueueCollector::class); } - public function testCouldBeConstructedWithMessageProducerAsFirstArgument() + public function testCouldBeConstructedWithEmptyConstructor() { - new MessageQueueCollector($this->createProducerMock()); + new MessageQueueCollector(); } public function testShouldReturnExpectedName() { - $collector = new MessageQueueCollector($this->createProducerMock()); + $collector = new MessageQueueCollector(); $this->assertEquals('enqueue.message_queue', $collector->getName()); } public function testShouldReturnEmptySentMessageArrayIfNotTraceableProducer() { - $collector = new MessageQueueCollector($this->createProducerMock()); + $collector = new MessageQueueCollector(); + $collector->addProducer('default', $this->createProducerMock()); $collector->collect(new Request(), new Response()); $this->assertSame([], $collector->getSentMessages()); } - public function testShouldReturnSentMessageArrayTakenFromTraceableProducer() + public function testShouldReturnSentMessageArrayTakenFromTraceableProducers() { - $producer = new TraceableProducer($this->createProducerMock()); - $producer->sendEvent('fooTopic', 'fooMessage'); - $producer->sendCommand('barCommand', 'barMessage'); + $producer1 = new TraceableProducer($this->createProducerMock()); + $producer1->sendEvent('fooTopic1', 'fooMessage'); + $producer1->sendCommand('barCommand1', 'barMessage'); - $collector = new MessageQueueCollector($producer); + $producer2 = new TraceableProducer($this->createProducerMock()); + $producer2->sendEvent('fooTopic2', 'fooMessage'); + + $collector = new MessageQueueCollector(); + $collector->addProducer('foo', $producer1); + $collector->addProducer('bar', $producer2); $collector->collect(new Request(), new Response()); $this->assertEquals( [ - [ - 'topic' => 'fooTopic', - 'command' => null, - 'body' => 'fooMessage', - 'headers' => [], - 'properties' => [], - 'priority' => null, - 'expire' => null, - 'delay' => null, - 'timestamp' => null, - 'contentType' => null, - 'messageId' => null, + 'foo' => [ + [ + 'topic' => 'fooTopic1', + 'command' => null, + 'body' => 'fooMessage', + 'headers' => [], + 'properties' => [], + 'priority' => null, + 'expire' => null, + 'delay' => null, + 'timestamp' => null, + 'contentType' => null, + 'messageId' => null, + ], + [ + 'topic' => null, + 'command' => 'barCommand1', + 'body' => 'barMessage', + 'headers' => [], + 'properties' => [], + 'priority' => null, + 'expire' => null, + 'delay' => null, + 'timestamp' => null, + 'contentType' => null, + 'messageId' => null, + ], ], - [ - 'topic' => null, - 'command' => 'barCommand', - 'body' => 'barMessage', - 'headers' => [], - 'properties' => [], - 'priority' => null, - 'expire' => null, - 'delay' => null, - 'timestamp' => null, - 'contentType' => null, - 'messageId' => null, + 'bar' => [ + [ + 'topic' => 'fooTopic2', + 'command' => null, + 'body' => 'fooMessage', + 'headers' => [], + 'properties' => [], + 'priority' => null, + 'expire' => null, + 'delay' => null, + 'timestamp' => null, + 'contentType' => null, + 'messageId' => null, + ], ], ], $collector->getSentMessages() @@ -87,21 +110,21 @@ public function testShouldReturnSentMessageArrayTakenFromTraceableProducer() public function testShouldPrettyPrintKnownPriority() { - $collector = new MessageQueueCollector($this->createProducerMock()); + $collector = new MessageQueueCollector(); $this->assertEquals('normal', $collector->prettyPrintPriority(MessagePriority::NORMAL)); } public function testShouldPrettyPrintUnknownPriority() { - $collector = new MessageQueueCollector($this->createProducerMock()); + $collector = new MessageQueueCollector(); $this->assertEquals('unknownPriority', $collector->prettyPrintPriority('unknownPriority')); } public function testShouldEnsureStringKeepStringSame() { - $collector = new MessageQueueCollector($this->createProducerMock()); + $collector = new MessageQueueCollector(); $this->assertEquals('foo', $collector->ensureString('foo')); $this->assertEquals('bar baz', $collector->ensureString('bar baz')); @@ -109,7 +132,7 @@ public function testShouldEnsureStringKeepStringSame() public function testShouldEnsureStringEncodeArrayToJson() { - $collector = new MessageQueueCollector($this->createProducerMock()); + $collector = new MessageQueueCollector(); $this->assertEquals('["foo","bar"]', $collector->ensureString(['foo', 'bar'])); } From d43798b8e608eaea9872681568d4b3449c8c8247 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Wed, 14 Nov 2018 14:06:25 +0200 Subject: [PATCH 10/18] multi client configuration --- .../DependencyInjection/Configuration.php | 31 +++++- .../DependencyInjection/EnqueueExtension.php | 2 +- .../Profiler/MessageQueueCollector.php | 10 ++ .../Resources/views/Profiler/panel.html.twig | 95 ++++++++++--------- pkg/enqueue/Client/TraceableProducer.php | 1 + .../DependencyInjection/ClientFactory.php | 1 + .../Symfony/MissingComponentFactory.php | 42 ++++++++ 7 files changed, 133 insertions(+), 49 deletions(-) create mode 100644 pkg/enqueue/Symfony/MissingComponentFactory.php diff --git a/pkg/enqueue-bundle/DependencyInjection/Configuration.php b/pkg/enqueue-bundle/DependencyInjection/Configuration.php index e2d9dfde2..4569500ae 100644 --- a/pkg/enqueue-bundle/DependencyInjection/Configuration.php +++ b/pkg/enqueue-bundle/DependencyInjection/Configuration.php @@ -2,9 +2,12 @@ namespace Enqueue\Bundle\DependencyInjection; +use Enqueue\AsyncCommand\RunCommandProcessor; use Enqueue\Monitoring\Symfony\DependencyInjection\MonitoringFactory; use Enqueue\Symfony\Client\DependencyInjection\ClientFactory; use Enqueue\Symfony\DependencyInjection\TransportFactory; +use Enqueue\Symfony\MissingComponentFactory; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -56,17 +59,14 @@ public function getConfigTreeBuilder(): TreeBuilder ->append(TransportFactory::getConfiguration()) ->append(TransportFactory::getQueueConsumerConfiguration()) ->append(ClientFactory::getConfiguration($this->debug)) - ->append(MonitoringFactory::getConfiguration()) + ->append($this->getMonitoringConfiguration()) + ->append($this->getAsyncCommandsConfiguration()) ->arrayNode('extensions')->addDefaultsIfNotSet()->children() ->booleanNode('doctrine_ping_connection_extension')->defaultFalse()->end() ->booleanNode('doctrine_clear_identity_map_extension')->defaultFalse()->end() ->booleanNode('signal_extension')->defaultValue(function_exists('pcntl_signal_dispatch'))->end() ->booleanNode('reply_extension')->defaultTrue()->end() ->end()->end() - ->arrayNode('async_commands') - ->addDefaultsIfNotSet() - ->canBeEnabled() - ->end() ->end() ->end() ; @@ -81,4 +81,25 @@ public function getConfigTreeBuilder(): TreeBuilder return $tb; } + + private function getMonitoringConfiguration(): ArrayNodeDefinition + { + if (false === class_exists(MonitoringFactory::class)) { + return MissingComponentFactory::getConfiguration('monitoring', ['enqueue/monitoring']); + } + + return MonitoringFactory::getConfiguration(); + } + + private function getAsyncCommandsConfiguration(): ArrayNodeDefinition + { + if (false === class_exists(RunCommandProcessor::class)) { + return MissingComponentFactory::getConfiguration('async_commands', ['enqueue/async-command']); + } + + return (new ArrayNodeDefinition('async_commands')) + ->addDefaultsIfNotSet() + ->canBeEnabled() + ; + } } diff --git a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php index 1cc4a47cc..30c4697eb 100644 --- a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php +++ b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php @@ -286,7 +286,7 @@ private function loadAsyncCommands(array $config, ContainerBuilder $container): { $configNames = []; foreach ($config as $name => $modules) { - if ($modules['async_commands']['enabled']) { + if (false === empty($modules['async_commands']['enabled'])) { $configNames[] = $name; } } diff --git a/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php b/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php index e03db0362..0c369da94 100644 --- a/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php +++ b/pkg/enqueue-bundle/Profiler/MessageQueueCollector.php @@ -36,6 +36,16 @@ public function collect(Request $request, Response $response, \Exception $except } } + public function getCount(): int + { + $count = 0; + foreach ($this->data as $name => $messages) { + $count += count($messages); + } + + return $count; + } + /** * @return array */ diff --git a/pkg/enqueue-bundle/Resources/views/Profiler/panel.html.twig b/pkg/enqueue-bundle/Resources/views/Profiler/panel.html.twig index fd6eafa30..ddd52a1e9 100644 --- a/pkg/enqueue-bundle/Resources/views/Profiler/panel.html.twig +++ b/pkg/enqueue-bundle/Resources/views/Profiler/panel.html.twig @@ -1,17 +1,17 @@ {% extends '@WebProfiler/Profiler/layout.html.twig' %} {% block toolbar %} - {% if collector.sentMessages|length > 0 %} + {% if collector.count > 0 %} {% set icon %} {{ include('@Enqueue/Icon/icon.svg') }} - {{ collector.sentMessages|length }} + {{ collector.count }} {% endset %} {% set text %}
Sent messages - {{ collector.sentMessages|length }} + {{ collector.count }}
{% endset %} @@ -20,54 +20,63 @@ {% endblock %} {% block menu %} - + {{ include('@Enqueue/Icon/icon.svg') }} Message Queue {% endblock %} {% block panel %} + {% if collector.count > 0 %}

Sent messages

- {% if collector.sentMessages|length > 0 %} - - - - - - - - - - - - {% for sentMessage in collector.sentMessages %} - - - - - - - {% endfor %} - + {% for clientName, sentMessages in collector.sentMessages %} + {% if sentMessages|length > 0 %} +

Client: {{ clientName }}

+
#TopicCommandMessagePriority
{{ loop.index }}{{ sentMessage.topic|default(null) }}{{ sentMessage.command|default(null) }} - {{ collector.prettyPrintPriority(sentMessage.priority) }} -
+ + + + + + + + + + + + {% for sentMessage in sentMessages %} + + + + + + + + {% endfor %} + -
#TopicCommandMessagePriorityTime
{{ loop.index }}{{ sentMessage.topic|default(null) }}{{ sentMessage.command|default(null) }} + {{ collector.prettyPrintPriority(sentMessage.priority) }} + + {{ sentMessage.sentAt|date('i:s.v') }} +
+ + {% endif %} + {% endfor %} {% else %}

No messages were sent.

diff --git a/pkg/enqueue/Client/TraceableProducer.php b/pkg/enqueue/Client/TraceableProducer.php index 86ff9f8c6..59b0c7b01 100644 --- a/pkg/enqueue/Client/TraceableProducer.php +++ b/pkg/enqueue/Client/TraceableProducer.php @@ -85,6 +85,7 @@ private function collectTrace(string $topic = null, string $command = null, $mes 'timestamp' => null, 'contentType' => null, 'messageId' => null, + 'sentAt' => (new \DateTime())->format('Y-m-d H:i:s.u'), ]; if ($message instanceof Message) { diff --git a/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php b/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php index b50efa545..9a2392d54 100644 --- a/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php +++ b/pkg/enqueue/Symfony/Client/DependencyInjection/ClientFactory.php @@ -107,6 +107,7 @@ public function build(ContainerBuilder $container, array $config, bool $default ; $container->register($this->format('producer'), Producer::class) + ->setPublic(true) ->addArgument($this->reference('driver')) ->addArgument($this->reference('rpc_factory')) ->addArgument($this->reference('client_extensions')) diff --git a/pkg/enqueue/Symfony/MissingComponentFactory.php b/pkg/enqueue/Symfony/MissingComponentFactory.php new file mode 100644 index 000000000..94fcb8339 --- /dev/null +++ b/pkg/enqueue/Symfony/MissingComponentFactory.php @@ -0,0 +1,42 @@ +info($message) + ->beforeNormalization() + ->always(function () { + return []; + }) + ->end() + ->validate() + ->always(function () use ($message) { + throw new \InvalidArgumentException($message); + }) + ->end() + ; + + return $node; + } +} From bc0071dfe822790e7b130d206daaae0098efcb33 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Wed, 14 Nov 2018 15:16:24 +0200 Subject: [PATCH 11/18] multi client configuration --- .../DependencyInjection/EnqueueExtension.php | 39 ++++++++++--------- .../Profiler/MessageQueueCollectorTest.php | 2 +- .../Tests/Client/TraceableProducerTest.php | 24 +++++++++--- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php index 30c4697eb..5108e912c 100644 --- a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php +++ b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php @@ -86,11 +86,25 @@ public function load(array $configs, ContainerBuilder $container): void } } + $defaultClient = null; + if (in_array($defaultName, $clientNames, true)) { + $defaultClient = $defaultName; + } + $container->setParameter('enqueue.transports', $transportNames); $container->setParameter('enqueue.clients', $clientNames); + $container->setParameter('enqueue.default_transport', $defaultName); + + if ($defaultClient) { + $container->setParameter('enqueue.default_client', $defaultClient); + } + + if ($defaultClient) { + $this->setupAutowiringForDefaultClientsProcessors($container, $defaultClient); + } + $this->loadMessageQueueCollector($config, $container); - $this->setupAutowiringForProcessors($config, $container); $this->loadAsyncCommands($config, $container); // extensions @@ -167,31 +181,18 @@ private function registerJobQueueDoctrineEntityMapping(ContainerBuilder $contain } } - private function setupAutowiringForProcessors(array $config, ContainerBuilder $container) + private function setupAutowiringForDefaultClientsProcessors(ContainerBuilder $container, string $defaultClient) { - $configNames = []; - foreach ($config as $name => $modules) { - if (isset($modules['client'])) { - $configNames[] = $name; - } - } - - if (false == $configNames) { - return; - } - - $topicSubscriber = $container->registerForAutoconfiguration(TopicSubscriberInterface::class) + $container->registerForAutoconfiguration(TopicSubscriberInterface::class) ->setPublic(true) + ->addTag('enqueue.topic_subscriber', ['client' => $defaultClient]) ; - $commandSubscriber = $container->registerForAutoconfiguration(CommandSubscriberInterface::class) + $container->registerForAutoconfiguration(CommandSubscriberInterface::class) ->setPublic(true) + ->addTag('enqueue.command_subscriber', ['client' => $defaultClient]) ; - foreach ($configNames as $configName) { - $topicSubscriber->addTag('enqueue.topic_subscriber', ['client' => $configName]); - $commandSubscriber->addTag('enqueue.command_subscriber', ['client' => $configName]); - } } private function loadDoctrinePingConnectionExtension(array $config, ContainerBuilder $container): void diff --git a/pkg/enqueue-bundle/Tests/Unit/Profiler/MessageQueueCollectorTest.php b/pkg/enqueue-bundle/Tests/Unit/Profiler/MessageQueueCollectorTest.php index d8bfa0996..4ad12f718 100644 --- a/pkg/enqueue-bundle/Tests/Unit/Profiler/MessageQueueCollectorTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/Profiler/MessageQueueCollectorTest.php @@ -58,7 +58,7 @@ public function testShouldReturnSentMessageArrayTakenFromTraceableProducers() $collector->collect(new Request(), new Response()); - $this->assertEquals( + $this->assertArraySubset( [ 'foo' => [ [ diff --git a/pkg/enqueue/Tests/Client/TraceableProducerTest.php b/pkg/enqueue/Tests/Client/TraceableProducerTest.php index 82364cacc..f58413df0 100644 --- a/pkg/enqueue/Tests/Client/TraceableProducerTest.php +++ b/pkg/enqueue/Tests/Client/TraceableProducerTest.php @@ -45,7 +45,7 @@ public function testShouldCollectInfoIfStringGivenAsEventMessage() $producer->sendEvent('aFooTopic', 'aFooBody'); - $this->assertSame([ + $this->assertArraySubset([ [ 'topic' => 'aFooTopic', 'command' => null, @@ -60,6 +60,8 @@ public function testShouldCollectInfoIfStringGivenAsEventMessage() 'messageId' => null, ], ], $producer->getTraces()); + + $this->assertArrayHasKey('sentAt', $producer->getTraces()[0]); } public function testShouldCollectInfoIfArrayGivenAsEventMessage() @@ -68,7 +70,7 @@ public function testShouldCollectInfoIfArrayGivenAsEventMessage() $producer->sendEvent('aFooTopic', ['foo' => 'fooVal', 'bar' => 'barVal']); - $this->assertSame([ + $this->assertArraySubset([ [ 'topic' => 'aFooTopic', 'command' => null, @@ -83,6 +85,8 @@ public function testShouldCollectInfoIfArrayGivenAsEventMessage() 'messageId' => null, ], ], $producer->getTraces()); + + $this->assertArrayHasKey('sentAt', $producer->getTraces()[0]); } public function testShouldCollectInfoIfEventMessageObjectGivenAsMessage() @@ -102,7 +106,7 @@ public function testShouldCollectInfoIfEventMessageObjectGivenAsMessage() $producer->sendEvent('aFooTopic', $message); - $this->assertSame([ + $this->assertArraySubset([ [ 'topic' => 'aFooTopic', 'command' => null, @@ -117,6 +121,8 @@ public function testShouldCollectInfoIfEventMessageObjectGivenAsMessage() 'messageId' => 'theMessageId', ], ], $producer->getTraces()); + + $this->assertArrayHasKey('sentAt', $producer->getTraces()[0]); } public function testShouldNotStoreAnythingIfInternalEventMessageProducerThrowsException() @@ -162,7 +168,7 @@ public function testShouldCollectInfoIfStringGivenAsCommandMessage() $producer->sendCommand('aFooCommand', 'aFooBody'); - $this->assertSame([ + $this->assertArraySubset([ [ 'topic' => null, 'command' => 'aFooCommand', @@ -177,6 +183,8 @@ public function testShouldCollectInfoIfStringGivenAsCommandMessage() 'messageId' => null, ], ], $producer->getTraces()); + + $this->assertArrayHasKey('sentAt', $producer->getTraces()[0]); } public function testShouldCollectInfoIfArrayGivenAsCommandMessage() @@ -185,7 +193,7 @@ public function testShouldCollectInfoIfArrayGivenAsCommandMessage() $producer->sendCommand('aFooCommand', ['foo' => 'fooVal', 'bar' => 'barVal']); - $this->assertSame([ + $this->assertArraySubset([ [ 'topic' => null, 'command' => 'aFooCommand', @@ -200,6 +208,8 @@ public function testShouldCollectInfoIfArrayGivenAsCommandMessage() 'messageId' => null, ], ], $producer->getTraces()); + + $this->assertArrayHasKey('sentAt', $producer->getTraces()[0]); } public function testShouldCollectInfoIfCommandMessageObjectGivenAsMessage() @@ -219,7 +229,7 @@ public function testShouldCollectInfoIfCommandMessageObjectGivenAsMessage() $producer->sendCommand('aFooCommand', $message); - $this->assertSame([ + $this->assertArraySubset([ [ 'topic' => null, 'command' => 'aFooCommand', @@ -234,6 +244,8 @@ public function testShouldCollectInfoIfCommandMessageObjectGivenAsMessage() 'messageId' => 'theMessageId', ], ], $producer->getTraces()); + + $this->assertArrayHasKey('sentAt', $producer->getTraces()[0]); } public function testShouldNotStoreAnythingIfInternalCommandMessageProducerThrowsException() From 3e4d486e217860235bcc721be2f7522ff1727e07 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Thu, 15 Nov 2018 09:49:48 +0200 Subject: [PATCH 12/18] multi client configuration --- .../DependencyInjection/EnqueueExtension.php | 2 +- .../Resources/config/services.yml | 5 ++++ pkg/enqueue/Symfony/Client/ConsumeCommand.php | 13 +++++++-- pkg/enqueue/Symfony/Client/ProduceCommand.php | 14 +++++++--- pkg/enqueue/Symfony/Client/RoutesCommand.php | 14 +++++++--- .../Symfony/Client/SetupBrokerCommand.php | 14 +++++++--- .../ConfigurableConsumeCommand.php | 13 +++++++-- .../Tests/Client/TraceableProducerTest.php | 2 +- .../Symfony/Client/ConsumeCommandTest.php | 28 +++++++++---------- .../Symfony/Client/ProduceCommandTest.php | 22 +++++++-------- .../Symfony/Client/RoutesCommandTest.php | 28 +++++++++---------- .../Symfony/Client/SetupBrokerCommandTest.php | 16 +++++------ .../ConfigurableConsumeCommandTest.php | 20 ++++++------- 13 files changed, 114 insertions(+), 77 deletions(-) diff --git a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php index 5108e912c..fec801b17 100644 --- a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php +++ b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php @@ -320,7 +320,7 @@ private function loadMessageQueueCollector(array $config, ContainerBuilder $cont $service = $container->register('enqueue.profiler.message_queue_collector', MessageQueueCollector::class); $service->addTag('data_collector', [ 'template' => '@Enqueue/Profiler/panel.html.twig', - 'id' => 'enqueue.message_queue' + 'id' => 'enqueue.message_queue', ]); foreach ($configNames as $configName) { diff --git a/pkg/enqueue-bundle/Resources/config/services.yml b/pkg/enqueue-bundle/Resources/config/services.yml index d63a4e89f..a207569c0 100644 --- a/pkg/enqueue-bundle/Resources/config/services.yml +++ b/pkg/enqueue-bundle/Resources/config/services.yml @@ -9,6 +9,7 @@ services: class: 'Enqueue\Symfony\Consumption\ConfigurableConsumeCommand' arguments: - '@enqueue.locator' + - '%enqueue.default_transport%' - 'enqueue.transport.%s.queue_consumer' - 'enqueue.transport.%s.processor_registry' tags: @@ -18,6 +19,7 @@ services: class: 'Enqueue\Symfony\Client\ConsumeCommand' arguments: - '@enqueue.locator' + - '%enqueue.default_client%' - 'enqueue.client.%s.queue_consumer' - 'enqueue.client.%s.driver' - 'enqueue.client.%s.delegate_processor' @@ -28,6 +30,7 @@ services: class: 'Enqueue\Symfony\Client\ProduceCommand' arguments: - '@enqueue.locator' + - '%enqueue.default_client%' - 'enqueue.client.%s.producer' tags: - { name: 'console.command' } @@ -36,6 +39,7 @@ services: class: 'Enqueue\Symfony\Client\SetupBrokerCommand' arguments: - '@enqueue.locator' + - '%enqueue.default_client%' - 'enqueue.client.%s.driver' tags: - { name: 'console.command' } @@ -44,6 +48,7 @@ services: class: 'Enqueue\Symfony\Client\RoutesCommand' arguments: - '@enqueue.locator' + - '%enqueue.default_client%' - 'enqueue.client.%s.driver' tags: - { name: 'console.command' } diff --git a/pkg/enqueue/Symfony/Client/ConsumeCommand.php b/pkg/enqueue/Symfony/Client/ConsumeCommand.php index cc1e46cf9..e6b25fc4f 100644 --- a/pkg/enqueue/Symfony/Client/ConsumeCommand.php +++ b/pkg/enqueue/Symfony/Client/ConsumeCommand.php @@ -34,6 +34,11 @@ class ConsumeCommand extends Command */ private $container; + /** + * @var string + */ + private $defaultClient; + /** * @var string */ @@ -51,16 +56,18 @@ class ConsumeCommand extends Command public function __construct( ContainerInterface $container, + string $defaultClient, string $queueConsumerIdPattern = 'enqueue.client.%s.queue_consumer', string $driverIdPattern = 'enqueue.client.%s.driver', string $processorIdPatter = 'enqueue.client.%s.delegate_processor' ) { - parent::__construct(self::$defaultName); - $this->container = $container; + $this->defaultClient = $defaultClient; $this->queueConsumerIdPattern = $queueConsumerIdPattern; $this->driverIdPattern = $driverIdPattern; $this->processorIdPattern = $processorIdPatter; + + parent::__construct(self::$defaultName); } protected function configure(): void @@ -77,7 +84,7 @@ protected function configure(): void 'It select an appropriate message processor based on a message headers') ->addArgument('client-queue-names', InputArgument::IS_ARRAY, 'Queues to consume messages from') ->addOption('skip', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'Queues to skip consumption of messages from', []) - ->addOption('client', 'c', InputOption::VALUE_OPTIONAL, 'The client to consume messages from.', 'default') + ->addOption('client', 'c', InputOption::VALUE_OPTIONAL, 'The client to consume messages from.', $this->defaultClient) ; } diff --git a/pkg/enqueue/Symfony/Client/ProduceCommand.php b/pkg/enqueue/Symfony/Client/ProduceCommand.php index 302b344c7..61be6a87d 100644 --- a/pkg/enqueue/Symfony/Client/ProduceCommand.php +++ b/pkg/enqueue/Symfony/Client/ProduceCommand.php @@ -20,17 +20,23 @@ class ProduceCommand extends Command */ private $container; + /** + * @var string + */ + private $defaultClient; + /** * @var string */ private $producerIdPattern; - public function __construct(ContainerInterface $container, string $producerIdPattern = 'enqueue.client.%s.producer') + public function __construct(ContainerInterface $container, string $defaultClient, string $producerIdPattern = 'enqueue.client.%s.producer') { - parent::__construct(static::$defaultName); - $this->container = $container; + $this->defaultClient = $defaultClient; $this->producerIdPattern = $producerIdPattern; + + parent::__construct(static::$defaultName); } protected function configure(): void @@ -38,7 +44,7 @@ protected function configure(): void $this ->setDescription('Sends an event to the topic') ->addArgument('message', InputArgument::REQUIRED, 'A message') - ->addOption('client', 'c', InputOption::VALUE_OPTIONAL, 'The client to consume messages from.', 'default') + ->addOption('client', 'c', InputOption::VALUE_OPTIONAL, 'The client to consume messages from.', $this->defaultClient) ->addOption('topic', null, InputOption::VALUE_OPTIONAL, 'The topic to send a message to') ->addOption('command', null, InputOption::VALUE_OPTIONAL, 'The command to send a message to') ; diff --git a/pkg/enqueue/Symfony/Client/RoutesCommand.php b/pkg/enqueue/Symfony/Client/RoutesCommand.php index 82bcacf19..04d404d85 100644 --- a/pkg/enqueue/Symfony/Client/RoutesCommand.php +++ b/pkg/enqueue/Symfony/Client/RoutesCommand.php @@ -22,6 +22,11 @@ class RoutesCommand extends Command */ private $container; + /** + * @var string + */ + private $defaultClient; + /** * @var string */ @@ -32,12 +37,13 @@ class RoutesCommand extends Command */ private $driver; - public function __construct(ContainerInterface $container, string $driverIdPatter = 'enqueue.client.%s.driver') + public function __construct(ContainerInterface $container, string $defaultClient, string $driverIdPatter = 'enqueue.client.%s.driver') { - parent::__construct(static::$defaultName); - $this->container = $container; + $this->defaultClient = $defaultClient; $this->driverIdPatter = $driverIdPatter; + + parent::__construct(static::$defaultName); } protected function configure(): void @@ -46,7 +52,7 @@ protected function configure(): void ->setAliases(['debug:enqueue:routes']) ->setDescription('A command lists all registered routes.') ->addOption('show-route-options', null, InputOption::VALUE_NONE, 'Adds ability to hide options.') - ->addOption('client', 'c', InputOption::VALUE_OPTIONAL, 'The client to consume messages from.', 'default') + ->addOption('client', 'c', InputOption::VALUE_OPTIONAL, 'The client to consume messages from.', $this->defaultClient) ; $this->driver = null; diff --git a/pkg/enqueue/Symfony/Client/SetupBrokerCommand.php b/pkg/enqueue/Symfony/Client/SetupBrokerCommand.php index 4a4f322ec..72215a8ba 100644 --- a/pkg/enqueue/Symfony/Client/SetupBrokerCommand.php +++ b/pkg/enqueue/Symfony/Client/SetupBrokerCommand.php @@ -20,17 +20,23 @@ class SetupBrokerCommand extends Command */ private $container; + /** + * @var string + */ + private $defaultClient; + /** * @var string */ private $driverIdPattern; - public function __construct(ContainerInterface $container, string $driverIdPattern = 'enqueue.client.%s.driver') + public function __construct(ContainerInterface $container, string $defaultClient, string $driverIdPattern = 'enqueue.client.%s.driver') { - parent::__construct(static::$defaultName); - $this->container = $container; + $this->defaultClient = $defaultClient; $this->driverIdPattern = $driverIdPattern; + + parent::__construct(static::$defaultName); } protected function configure(): void @@ -38,7 +44,7 @@ protected function configure(): void $this ->setAliases(['enq:sb']) ->setDescription('Setup broker. Configure the broker, creates queues, topics and so on.') - ->addOption('client', 'c', InputOption::VALUE_OPTIONAL, 'The client to consume messages from.', 'default') + ->addOption('client', 'c', InputOption::VALUE_OPTIONAL, 'The client to consume messages from.', $this->defaultClient) ; } diff --git a/pkg/enqueue/Symfony/Consumption/ConfigurableConsumeCommand.php b/pkg/enqueue/Symfony/Consumption/ConfigurableConsumeCommand.php index 68ae6dae2..9c47134a0 100644 --- a/pkg/enqueue/Symfony/Consumption/ConfigurableConsumeCommand.php +++ b/pkg/enqueue/Symfony/Consumption/ConfigurableConsumeCommand.php @@ -27,6 +27,11 @@ class ConfigurableConsumeCommand extends Command */ private $container; + /** + * @var string + */ + private $defaultTransport; + /** * @var string */ @@ -39,14 +44,16 @@ class ConfigurableConsumeCommand extends Command public function __construct( ContainerInterface $container, + string $defaultTransport, string $queueConsumerIdPattern = 'enqueue.transport.%s.queue_consumer', string $processorRegistryIdPattern = 'enqueue.transport.%s.processor_registry' ) { - parent::__construct(static::$defaultName); - $this->container = $container; + $this->defaultTransport = $defaultTransport; $this->queueConsumerIdPattern = $queueConsumerIdPattern; $this->processorRegistryIdPattern = $processorRegistryIdPattern; + + parent::__construct(static::$defaultName); } protected function configure(): void @@ -61,7 +68,7 @@ protected function configure(): void 'and a message processor service') ->addArgument('processor', InputArgument::REQUIRED, 'A message processor.') ->addArgument('queues', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'A queue to consume from', []) - ->addOption('transport', 't', InputOption::VALUE_OPTIONAL, 'The transport to consume messages from.', 'default') + ->addOption('transport', 't', InputOption::VALUE_OPTIONAL, 'The transport to consume messages from.', $this->defaultTransport) ; } diff --git a/pkg/enqueue/Tests/Client/TraceableProducerTest.php b/pkg/enqueue/Tests/Client/TraceableProducerTest.php index f58413df0..b25b7c18b 100644 --- a/pkg/enqueue/Tests/Client/TraceableProducerTest.php +++ b/pkg/enqueue/Tests/Client/TraceableProducerTest.php @@ -60,7 +60,7 @@ public function testShouldCollectInfoIfStringGivenAsEventMessage() 'messageId' => null, ], ], $producer->getTraces()); - + $this->assertArrayHasKey('sentAt', $producer->getTraces()[0]); } diff --git a/pkg/enqueue/Tests/Symfony/Client/ConsumeCommandTest.php b/pkg/enqueue/Tests/Symfony/Client/ConsumeCommandTest.php index 3b6feb662..9a45d424d 100644 --- a/pkg/enqueue/Tests/Symfony/Client/ConsumeCommandTest.php +++ b/pkg/enqueue/Tests/Symfony/Client/ConsumeCommandTest.php @@ -34,19 +34,19 @@ public function testShouldNotBeFinal() public function testCouldBeConstructedWithRequiredAttributes() { - new ConsumeCommand($this->createMock(ContainerInterface::class)); + new ConsumeCommand($this->createMock(ContainerInterface::class), 'default'); } public function testShouldHaveCommandName() { - $command = new ConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $this->assertEquals('enqueue:consume', $command->getName()); } public function testShouldHaveExpectedOptions() { - $command = new ConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $options = $command->getDefinition()->getOptions(); @@ -64,7 +64,7 @@ public function testShouldHaveExpectedOptions() public function testShouldHaveExpectedAttributes() { - $command = new ConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $arguments = $command->getDefinition()->getArguments(); @@ -104,7 +104,7 @@ public function testShouldBindDefaultQueueOnly() 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([]); @@ -164,7 +164,7 @@ public function testShouldUseRequestedClient() 'enqueue.client.foo.queue_consumer' => $fooConsumer, 'enqueue.client.foo.driver' => $fooDriver, 'enqueue.client.foo.delegate_processor' => $fooProcessor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -198,7 +198,7 @@ public function testThrowIfNotDefinedClientRequested() 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -243,7 +243,7 @@ public function testShouldBindDefaultQueueIfRouteUseDifferentQueue() 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([]); @@ -295,7 +295,7 @@ public function testShouldBindCustomExecuteConsumptionAndUseCustomClientDestinat 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([]); @@ -336,7 +336,7 @@ public function testShouldBindUserProvidedQueues() 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -378,7 +378,7 @@ public function testShouldBindNotPrefixedQueue() 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -434,7 +434,7 @@ public function testShouldBindQueuesOnlyOnce() 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([]); @@ -475,7 +475,7 @@ public function testShouldNotBindExternalRoutes() 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([]); @@ -528,7 +528,7 @@ public function testShouldSkipQueueConsumptionAndUseCustomClientDestinationName( 'enqueue.client.default.queue_consumer' => $consumer, 'enqueue.client.default.driver' => $driver, 'enqueue.client.default.delegate_processor' => $processor, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ diff --git a/pkg/enqueue/Tests/Symfony/Client/ProduceCommandTest.php b/pkg/enqueue/Tests/Symfony/Client/ProduceCommandTest.php index 321b4eebd..8e9b750a3 100644 --- a/pkg/enqueue/Tests/Symfony/Client/ProduceCommandTest.php +++ b/pkg/enqueue/Tests/Symfony/Client/ProduceCommandTest.php @@ -27,19 +27,19 @@ public function testShouldNotBeFinal() public function testCouldBeConstructedWithContainerAsFirstArgument() { - new ProduceCommand($this->createMock(ContainerInterface::class)); + new ProduceCommand($this->createMock(ContainerInterface::class), 'default'); } public function testShouldHaveCommandName() { - $command = new ProduceCommand($this->createMock(ContainerInterface::class)); + $command = new ProduceCommand($this->createMock(ContainerInterface::class), 'default'); $this->assertEquals('enqueue:produce', $command->getName()); } public function testShouldHaveExpectedOptions() { - $command = new ProduceCommand($this->createMock(ContainerInterface::class)); + $command = new ProduceCommand($this->createMock(ContainerInterface::class), 'default'); $options = $command->getDefinition()->getOptions(); $this->assertCount(3, $options); @@ -50,7 +50,7 @@ public function testShouldHaveExpectedOptions() public function testShouldHaveExpectedAttributes() { - $command = new ProduceCommand($this->createMock(ContainerInterface::class)); + $command = new ProduceCommand($this->createMock(ContainerInterface::class), 'default'); $arguments = $command->getDefinition()->getArguments(); $this->assertCount(1, $arguments); @@ -72,7 +72,7 @@ public function testThrowIfNeitherTopicNorCommandOptionsAreSet() $command = new ProduceCommand(new Container([ 'enqueue.client.default.producer' => $producerMock, - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -97,7 +97,7 @@ public function testThrowIfBothTopicAndCommandOptionsAreSet() $command = new ProduceCommand(new Container([ 'enqueue.client.default.producer' => $producerMock, - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -125,7 +125,7 @@ public function testShouldSendEventToDefaultTransport() $command = new ProduceCommand(new Container([ 'enqueue.client.default.producer' => $producerMock, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -149,7 +149,7 @@ public function testShouldSendCommandToDefaultTransport() $command = new ProduceCommand(new Container([ 'enqueue.client.default.producer' => $producerMock, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -184,7 +184,7 @@ public function testShouldSendEventToFooTransport() $command = new ProduceCommand(new Container([ 'enqueue.client.default.producer' => $defaultProducerMock, 'enqueue.client.foo.producer' => $fooProducerMock, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -220,7 +220,7 @@ public function testShouldSendCommandToFooTransport() $command = new ProduceCommand(new Container([ 'enqueue.client.default.producer' => $defaultProducerMock, 'enqueue.client.foo.producer' => $fooProducerMock, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -244,7 +244,7 @@ public function testThrowIfClientNotFound() $command = new ProduceCommand(new Container([ 'enqueue.client.default.producer' => $defaultProducerMock, - ])); + ]), 'default'); $tester = new CommandTester($command); diff --git a/pkg/enqueue/Tests/Symfony/Client/RoutesCommandTest.php b/pkg/enqueue/Tests/Symfony/Client/RoutesCommandTest.php index daab37e1c..0ed73ef1e 100644 --- a/pkg/enqueue/Tests/Symfony/Client/RoutesCommandTest.php +++ b/pkg/enqueue/Tests/Symfony/Client/RoutesCommandTest.php @@ -30,26 +30,26 @@ public function testShouldNotBeFinal() public function testCouldBeConstructedWithConfigAndRouteCollectionAsArguments() { - new RoutesCommand($this->createMock(ContainerInterface::class)); + new RoutesCommand($this->createMock(ContainerInterface::class), 'default'); } public function testShouldHaveCommandName() { - $command = new RoutesCommand($this->createMock(ContainerInterface::class)); + $command = new RoutesCommand($this->createMock(ContainerInterface::class), 'default'); $this->assertEquals('enqueue:routes', $command->getName()); } public function testShouldHaveCommandAliases() { - $command = new RoutesCommand($this->createMock(ContainerInterface::class)); + $command = new RoutesCommand($this->createMock(ContainerInterface::class), 'default'); $this->assertEquals(['debug:enqueue:routes'], $command->getAliases()); } public function testShouldHaveExpectedOptions() { - $command = new RoutesCommand($this->createMock(ContainerInterface::class)); + $command = new RoutesCommand($this->createMock(ContainerInterface::class), 'default'); $options = $command->getDefinition()->getOptions(); $this->assertCount(2, $options); @@ -60,7 +60,7 @@ public function testShouldHaveExpectedOptions() public function testShouldHaveExpectedAttributes() { - $command = new RoutesCommand($this->createMock(ContainerInterface::class)); + $command = new RoutesCommand($this->createMock(ContainerInterface::class), 'default'); $arguments = $command->getDefinition()->getArguments(); $this->assertCount(0, $arguments); @@ -72,7 +72,7 @@ public function testShouldOutputEmptyRouteCollection() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $this->createDriverStub(Config::create(), $routeCollection), - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -109,7 +109,7 @@ public function testShouldUseFooDriver() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $defaultDriverMock, 'enqueue.client.foo.driver' => $fooDriverMock, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -134,7 +134,7 @@ public function testThrowIfClientNotFound() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $defaultDriverMock, - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -154,7 +154,7 @@ public function testShouldOutputTopicRouteInfo() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $this->createDriverStub(Config::create(), $routeCollection), - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -184,7 +184,7 @@ public function testShouldOutputCommandRouteInfo() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $this->createDriverStub(Config::create(), $routeCollection), - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -214,7 +214,7 @@ public function testShouldCorrectlyOutputPrefixedCustomQueue() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $this->createDriverStub(Config::create(), $routeCollection), - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -245,7 +245,7 @@ public function testShouldCorrectlyOutputNotPrefixedCustomQueue() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $this->createDriverStub(Config::create(), $routeCollection), - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -275,7 +275,7 @@ public function testShouldCorrectlyOutputExternalRoute() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $this->createDriverStub(Config::create(), $routeCollection), - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -305,7 +305,7 @@ public function testShouldOutputRouteOptions() $command = new RoutesCommand(new Container([ 'enqueue.client.default.driver' => $this->createDriverStub(Config::create(), $routeCollection), - ])); + ]), 'default'); $tester = new CommandTester($command); diff --git a/pkg/enqueue/Tests/Symfony/Client/SetupBrokerCommandTest.php b/pkg/enqueue/Tests/Symfony/Client/SetupBrokerCommandTest.php index b81daf2b3..4bbaf5534 100644 --- a/pkg/enqueue/Tests/Symfony/Client/SetupBrokerCommandTest.php +++ b/pkg/enqueue/Tests/Symfony/Client/SetupBrokerCommandTest.php @@ -27,26 +27,26 @@ public function testShouldNotBeFinal() public function testCouldBeConstructedWithContainerAsFirstArgument() { - new SetupBrokerCommand($this->createMock(ContainerInterface::class)); + new SetupBrokerCommand($this->createMock(ContainerInterface::class), 'default'); } public function testShouldHaveCommandName() { - $command = new SetupBrokerCommand($this->createMock(ContainerInterface::class)); + $command = new SetupBrokerCommand($this->createMock(ContainerInterface::class), 'default'); $this->assertEquals('enqueue:setup-broker', $command->getName()); } public function testShouldHaveCommandAliases() { - $command = new SetupBrokerCommand($this->createMock(ContainerInterface::class)); + $command = new SetupBrokerCommand($this->createMock(ContainerInterface::class), 'default'); $this->assertEquals(['enq:sb'], $command->getAliases()); } public function testShouldHaveExpectedOptions() { - $command = new SetupBrokerCommand($this->createMock(ContainerInterface::class)); + $command = new SetupBrokerCommand($this->createMock(ContainerInterface::class), 'default'); $options = $command->getDefinition()->getOptions(); @@ -56,7 +56,7 @@ public function testShouldHaveExpectedOptions() public function testShouldHaveExpectedAttributes() { - $command = new SetupBrokerCommand($this->createMock(ContainerInterface::class)); + $command = new SetupBrokerCommand($this->createMock(ContainerInterface::class), 'default'); $arguments = $command->getDefinition()->getArguments(); @@ -73,7 +73,7 @@ public function testShouldCallDriverSetupBrokerMethod() $command = new SetupBrokerCommand(new Container([ 'enqueue.client.default.driver' => $driver, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([]); @@ -98,7 +98,7 @@ public function testShouldCallRequestedClientDriverSetupBrokerMethod() $command = new SetupBrokerCommand(new Container([ 'enqueue.client.default.driver' => $defaultDriver, 'enqueue.client.foo.driver' => $fooDriver, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -118,7 +118,7 @@ public function testShouldThrowIfClientNotFound() $command = new SetupBrokerCommand(new Container([ 'enqueue.client.default.driver' => $defaultDriver, - ])); + ]), 'default'); $tester = new CommandTester($command); diff --git a/pkg/enqueue/Tests/Symfony/Consumption/ConfigurableConsumeCommandTest.php b/pkg/enqueue/Tests/Symfony/Consumption/ConfigurableConsumeCommandTest.php index b402960ac..4586849de 100644 --- a/pkg/enqueue/Tests/Symfony/Consumption/ConfigurableConsumeCommandTest.php +++ b/pkg/enqueue/Tests/Symfony/Consumption/ConfigurableConsumeCommandTest.php @@ -34,19 +34,19 @@ public function testShouldNotBeFinal() public function testCouldBeConstructedWithRequiredAttributes() { - new ConfigurableConsumeCommand($this->createMock(ContainerInterface::class)); + new ConfigurableConsumeCommand($this->createMock(ContainerInterface::class), 'default'); } public function testShouldHaveCommandName() { - $command = new ConfigurableConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConfigurableConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $this->assertEquals('enqueue:transport:consume', $command->getName()); } public function testShouldHaveExpectedOptions() { - $command = new ConfigurableConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConfigurableConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $options = $command->getDefinition()->getOptions(); @@ -62,7 +62,7 @@ public function testShouldHaveExpectedOptions() public function testShouldHaveExpectedAttributes() { - $command = new ConfigurableConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConfigurableConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $arguments = $command->getDefinition()->getArguments(); @@ -88,7 +88,7 @@ public function testThrowIfNeitherQueueOptionNorProcessorImplementsQueueSubscrib $command = new ConfigurableConsumeCommand(new Container([ 'enqueue.transport.default.queue_consumer' => $consumer, 'enqueue.transport.default.processor_registry' => new ArrayProcessorRegistry(['aProcessor' => $processor]), - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -118,7 +118,7 @@ public function testShouldExecuteConsumptionWithExplicitlySetQueue() $command = new ConfigurableConsumeCommand(new Container([ 'enqueue.transport.default.queue_consumer' => $consumer, 'enqueue.transport.default.processor_registry' => new ArrayProcessorRegistry(['processor-service' => $processor]), - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -144,7 +144,7 @@ public function testThrowIfTransportNotDefined() $command = new ConfigurableConsumeCommand(new Container([ 'enqueue.transport.default.queue_consumer' => $consumer, 'enqueue.transport.default.processor_registry' => new ArrayProcessorRegistry(['processor-service' => $processor]), - ])); + ]), 'default'); $tester = new CommandTester($command); @@ -181,7 +181,7 @@ public function testShouldExecuteConsumptionWithSeveralCustomQueues() $command = new ConfigurableConsumeCommand(new Container([ 'enqueue.transport.default.queue_consumer' => $consumer, 'enqueue.transport.default.processor_registry' => new ArrayProcessorRegistry(['processor-service' => $processor]), - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -223,7 +223,7 @@ public static function getSubscribedQueues() $command = new ConfigurableConsumeCommand(new Container([ 'enqueue.transport.default.queue_consumer' => $consumer, 'enqueue.transport.default.processor_registry' => new ArrayProcessorRegistry(['processor-service' => $processor]), - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ @@ -263,7 +263,7 @@ public function testShouldExecuteConsumptionWithCustomTransportExplicitlySetQueu 'enqueue.transport.foo.processor_registry' => new ArrayProcessorRegistry(['processor-service' => $processor]), 'enqueue.transport.bar.queue_consumer' => $barConsumer, 'enqueue.transport.bar.processor_registry' => new ArrayProcessorRegistry(['processor-service' => $processor]), - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([ From 6a84f65cbfe991f73570b1812da251ee3aae6a6c Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Thu, 15 Nov 2018 09:59:55 +0200 Subject: [PATCH 13/18] multi client configuration --- .../Symfony/Consumption/ConsumeCommand.php | 17 +++++++++-------- .../Symfony/Consumption/ConsumeCommandTest.php | 14 +++++++------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pkg/enqueue/Symfony/Consumption/ConsumeCommand.php b/pkg/enqueue/Symfony/Consumption/ConsumeCommand.php index 632a7de17..e65acc314 100644 --- a/pkg/enqueue/Symfony/Consumption/ConsumeCommand.php +++ b/pkg/enqueue/Symfony/Consumption/ConsumeCommand.php @@ -27,19 +27,20 @@ class ConsumeCommand extends Command /** * @var string */ - private $queueConsumerIdPattern; + private $defaultTransport; /** - * [name => QueueConsumerInterface]. - * - * @param QueueConsumerInterface[] + * @var string */ - public function __construct(ContainerInterface $container, string $queueConsumerIdPattern = 'enqueue.transport.%s.queue_consumer') - { - parent::__construct(static::$defaultName); + private $queueConsumerIdPattern; + public function __construct(ContainerInterface $container, string $defaultTransport, string $queueConsumerIdPattern = 'enqueue.transport.%s.queue_consumer') + { $this->container = $container; + $this->defaultTransport = $defaultTransport; $this->queueConsumerIdPattern = $queueConsumerIdPattern; + + parent::__construct(static::$defaultName); } protected function configure(): void @@ -49,7 +50,7 @@ protected function configure(): void $this->configureLoggerExtension(); $this - ->addOption('transport', 't', InputOption::VALUE_OPTIONAL, 'The transport to consume messages from.', 'default') + ->addOption('transport', 't', InputOption::VALUE_OPTIONAL, 'The transport to consume messages from.', $this->defaultTransport) ->setDescription('A worker that consumes message from a broker. '. 'To use this broker you have to configure queue consumer before adding to the command') ; diff --git a/pkg/enqueue/Tests/Symfony/Consumption/ConsumeCommandTest.php b/pkg/enqueue/Tests/Symfony/Consumption/ConsumeCommandTest.php index a8ead2d8e..6396568cb 100644 --- a/pkg/enqueue/Tests/Symfony/Consumption/ConsumeCommandTest.php +++ b/pkg/enqueue/Tests/Symfony/Consumption/ConsumeCommandTest.php @@ -28,19 +28,19 @@ public function testShouldNotBeFinal() public function testCouldBeConstructedWithRequiredAttributes() { - new ConsumeCommand($this->createMock(ContainerInterface::class)); + new ConsumeCommand($this->createMock(ContainerInterface::class), 'default'); } public function testShouldHaveCommandName() { - $command = new ConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $this->assertEquals('enqueue:transport:consume', $command->getName()); } public function testShouldHaveExpectedOptions() { - $command = new ConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $options = $command->getDefinition()->getOptions(); @@ -56,7 +56,7 @@ public function testShouldHaveExpectedOptions() public function testShouldHaveExpectedAttributes() { - $command = new ConsumeCommand($this->createMock(ContainerInterface::class)); + $command = new ConsumeCommand($this->createMock(ContainerInterface::class), 'default'); $arguments = $command->getDefinition()->getArguments(); @@ -74,7 +74,7 @@ public function testShouldExecuteDefaultConsumption() $command = new ConsumeCommand(new Container([ 'enqueue.transport.default.queue_consumer' => $consumer, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute([]); @@ -98,7 +98,7 @@ public function testShouldExecuteCustomConsumption() $command = new ConsumeCommand(new Container([ 'enqueue.transport.default.queue_consumer' => $defaultConsumer, 'enqueue.transport.custom.queue_consumer' => $customConsumer, - ])); + ]), 'default'); $tester = new CommandTester($command); $tester->execute(['--transport' => 'custom']); @@ -114,7 +114,7 @@ public function testThrowIfNotDefinedTransportRequested() $command = new ConsumeCommand(new Container([ 'enqueue.transport.default.queue_consumer' => $defaultConsumer, - ])); + ]), 'default'); $tester = new CommandTester($command); From 39bcab2532bde5d5d459b213c63503e5e1b51135 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Thu, 15 Nov 2018 10:04:21 +0200 Subject: [PATCH 14/18] multi client configuration --- pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php index fec801b17..81c356688 100644 --- a/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php +++ b/pkg/enqueue-bundle/DependencyInjection/EnqueueExtension.php @@ -192,7 +192,6 @@ private function setupAutowiringForDefaultClientsProcessors(ContainerBuilder $co ->setPublic(true) ->addTag('enqueue.command_subscriber', ['client' => $defaultClient]) ; - } private function loadDoctrinePingConnectionExtension(array $config, ContainerBuilder $container): void From a4f5524d8d4bdb75de9735a3a1436936e229e330 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Thu, 15 Nov 2018 10:19:24 +0200 Subject: [PATCH 15/18] multi client configuration --- .../DependencyInjection/Configuration.php | 26 ------ .../DependencyInjection/ConfigurationTest.php | 80 +++---------------- 2 files changed, 10 insertions(+), 96 deletions(-) diff --git a/pkg/enqueue-bundle/DependencyInjection/Configuration.php b/pkg/enqueue-bundle/DependencyInjection/Configuration.php index 4569500ae..260a50e9e 100644 --- a/pkg/enqueue-bundle/DependencyInjection/Configuration.php +++ b/pkg/enqueue-bundle/DependencyInjection/Configuration.php @@ -24,32 +24,6 @@ public function getConfigTreeBuilder(): TreeBuilder { $tb = new TreeBuilder(); $rootNode = $tb->root('enqueue'); - $rootNode - ->beforeNormalization() - ->always(function ($value) { - if (empty($value)) { - return [ - 'default' => [ - 'transport' => [ - 'dsn' => 'null:', - ], - ], - ]; - } - - if (is_string($value)) { - return [ - 'default' => [ - 'transport' => [ - 'dsn' => $value, - ], - ], - ]; - } - - return $value; - }) - ; $rootNode ->requiresAtLeastOneElement() diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php index baff83925..1b95fb6f2 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php @@ -28,48 +28,6 @@ public function testCouldBeConstructedWithDebugAsArgument() new Configuration(true); } - public function testShouldProcessNullAsDefaultNullTransport() - { - $configuration = new Configuration(true); - - $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [null]); - - $this->assertConfigEquals([ - 'default' => [ - 'transport' => ['dsn' => 'null:'], - ], - ], $config); - } - - public function testShouldProcessStringAsDefaultDsnTransport() - { - $configuration = new Configuration(true); - - $processor = new Processor(); - $config = $processor->processConfiguration($configuration, ['foo://bar?option=val']); - - $this->assertConfigEquals([ - 'default' => [ - 'transport' => ['dsn' => 'foo://bar?option=val'], - ], - ], $config); - } - - public function testShouldProcessEmptyArrayAsDefaultNullTransport() - { - $configuration = new Configuration(true); - - $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [[]]); - - $this->assertConfigEquals([ - 'default' => [ - 'transport' => ['dsn' => 'null:'], - ], - ], $config); - } - public function testShouldProcessSeveralTransports() { $configuration = new Configuration(true); @@ -118,32 +76,6 @@ public function testTransportFactoryShouldValidateEachTransportAccordingToItsRul ]); } - public function testShouldUseDefaultConfigurationIfNothingIsConfiguredAtAll() - { - $configuration = new Configuration(true); - - $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [[]]); - - $this->assertEquals([ - 'default' => [ - 'transport' => ['dsn' => 'null:'], - 'consumption' => [ - 'receive_timeout' => 10000, - ], -// 'job' => false, -// 'async_events' => ['enabled' => false], - 'async_commands' => ['enabled' => false], - 'extensions' => [ - 'doctrine_ping_connection_extension' => false, - 'doctrine_clear_identity_map_extension' => false, - 'signal_extension' => function_exists('pcntl_signal_dispatch'), - 'reply_extension' => true, - ], - ], - ], $config); - } - public function testShouldSetDefaultConfigurationForClient() { $configuration = new Configuration(true); @@ -264,7 +196,11 @@ public function testDoctrinePingConnectionExtensionShouldBeDisabledByDefault() $configuration = new Configuration(true); $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [[]]); + $config = $processor->processConfiguration($configuration, [[ + 'default' => [ + 'transport' => null, + ] + ]]); $this->assertArraySubset([ 'default' => [ @@ -303,7 +239,11 @@ public function testDoctrineClearIdentityMapExtensionShouldBeDisabledByDefault() $configuration = new Configuration(true); $processor = new Processor(); - $config = $processor->processConfiguration($configuration, [[]]); + $config = $processor->processConfiguration($configuration, [[ + 'default' => [ + 'transport' => null, + ] + ]]); $this->assertArraySubset([ 'default' => [ From cec8fb35924dfeff911a751ae67cd845305f0901 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Thu, 15 Nov 2018 10:27:20 +0200 Subject: [PATCH 16/18] multi client configuration --- .../DependencyInjection/EnqueueExtensionTest.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php index bb1918b01..9fd7c2e98 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php @@ -41,7 +41,11 @@ public function testShouldRegisterConnectionFactory() $extension = new EnqueueExtension(); - $extension->load([[]], $container); + $extension->load([[ + 'default' => [ + 'transport' => null, + ], + ]], $container); self::assertTrue($container->hasDefinition('enqueue.transport.default.connection_factory')); self::assertNotEmpty($container->getDefinition('enqueue.transport.default.connection_factory')->getFactory()); @@ -53,7 +57,11 @@ public function testShouldRegisterContext() $extension = new EnqueueExtension(); - $extension->load([[]], $container); + $extension->load([[ + 'default' => [ + 'transport' => null, + ], + ]], $container); self::assertTrue($container->hasDefinition('enqueue.transport.default.context')); self::assertNotEmpty($container->getDefinition('enqueue.transport.default.context')->getFactory()); From 8b44199988e8cdc694984b90fd07823d6614fb39 Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Thu, 15 Nov 2018 10:34:25 +0200 Subject: [PATCH 17/18] multi client configuration --- .../Tests/Unit/DependencyInjection/ConfigurationTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php index 1b95fb6f2..b735bda14 100644 --- a/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/pkg/enqueue-bundle/Tests/Unit/DependencyInjection/ConfigurationTest.php @@ -199,7 +199,7 @@ public function testDoctrinePingConnectionExtensionShouldBeDisabledByDefault() $config = $processor->processConfiguration($configuration, [[ 'default' => [ 'transport' => null, - ] + ], ]]); $this->assertArraySubset([ @@ -242,7 +242,7 @@ public function testDoctrineClearIdentityMapExtensionShouldBeDisabledByDefault() $config = $processor->processConfiguration($configuration, [[ 'default' => [ 'transport' => null, - ] + ], ]]); $this->assertArraySubset([ From 135193093896ff0b7b1f7b31b6a89923496fb22b Mon Sep 17 00:00:00 2001 From: Alexander Kozienko Date: Thu, 15 Nov 2018 11:17:23 +0200 Subject: [PATCH 18/18] multi client configuration --- docs/bundle/async_commands.md | 3 +- docs/bundle/async_events.md | 9 ++-- docs/bundle/config_reference.md | 74 +++++++++++++++---------------- docs/bundle/debugging.md | 5 ++- docs/bundle/functional_testing.md | 10 +++-- docs/bundle/job_queue.md | 7 +-- docs/bundle/quick_tour.md | 5 ++- 7 files changed, 59 insertions(+), 54 deletions(-) diff --git a/docs/bundle/async_commands.md b/docs/bundle/async_commands.md index 51f60532d..21299911c 100644 --- a/docs/bundle/async_commands.md +++ b/docs/bundle/async_commands.md @@ -21,7 +21,8 @@ $ composer require enqueue/async-command:0.9.x-dev # config/packages/enqueue_async_commands.yaml enqueue: - async_commands: true + default: + async_commands: true ``` ## Usage diff --git a/docs/bundle/async_events.md b/docs/bundle/async_events.md index e70f41d7f..7c20381bc 100644 --- a/docs/bundle/async_events.md +++ b/docs/bundle/async_events.md @@ -31,10 +31,11 @@ If you already [installed the bundle](quick_tour.md#install), then enable `async # app/config/config.yml enqueue: - async_events: - enabled: true - # if you'd like to send send messages onTerminate use spool_producer (it further reduces response time): - # spool_producer: true + default: + async_events: + enabled: true + # if you'd like to send send messages onTerminate use spool_producer (it further reduces response time): + # spool_producer: true ``` ## Usage diff --git a/docs/bundle/config_reference.md b/docs/bundle/config_reference.md index 346372c77..9118a8f9c 100644 --- a/docs/bundle/config_reference.md +++ b/docs/bundle/config_reference.md @@ -14,44 +14,42 @@ You can get this info by running `./bin/console config:dump-reference enqueue` c ```yaml # Default configuration for extension with alias: "enqueue" enqueue: - - # The transport option could accept a string DSN, an array with DSN key, or null. It accept extra options. To find out what option you can set, look at connection factory constructor docblock. - transport: - - # The broker DSN. These schemes are supported: "file", "amqp", "amqps", "db2", "ibm-db2", "mssql", "sqlsrv", "mysql", "mysql2", "pgsql", "postgres", "sqlite", "sqlite3", "null", "gearman", "beanstalk", "kafka", "rdkafka", "redis", "stomp", "sqs", "gps", "mongodb", to use these "file", "amqp", "amqps", "db2", "ibm-db2", "mssql", "sqlsrv", "mysql", "mysql2", "pgsql", "postgres", "sqlite", "sqlite3", "null", "gearman", "beanstalk", "kafka", "rdkafka", "redis", "stomp", "sqs", "gps", "mongodb" you have to install a package. - dsn: ~ # Required - - # The connection factory class should implement "Interop\Queue\ConnectionFactory" interface - connection_factory_class: ~ - - # The factory class should implement "Enqueue\ConnectionFactoryFactoryInterface" interface - factory_service: ~ - - # The factory service should be a class that implements "Enqueue\ConnectionFactoryFactoryInterface" interface - factory_class: ~ - client: - traceable_producer: true - prefix: enqueue - app_name: app - router_topic: default - router_queue: default - router_processor: Enqueue\Client\RouterProcessor - default_processor_queue: default - redelivered_delay_time: 0 - consumption: - - # the time in milliseconds queue consumer waits for a message (100 ms by default) - receive_timeout: 100 - job: false - async_events: - enabled: false - async_commands: - enabled: false - extensions: - doctrine_ping_connection_extension: false - doctrine_clear_identity_map_extension: false - signal_extension: true - reply_extension: true + # Configuration name + default: + # The transport option could accept a string DSN, an array with DSN key, or null. It accept extra options. To find out what option you can set, look at connection factory constructor docblock. + transport: + + # The broker DSN. These schemes are supported: "file", "amqp", "amqps", "db2", "ibm-db2", "mssql", "sqlsrv", "mysql", "mysql2", "pgsql", "postgres", "sqlite", "sqlite3", "null", "gearman", "beanstalk", "kafka", "rdkafka", "redis", "stomp", "sqs", "gps", "mongodb", to use these "file", "amqp", "amqps", "db2", "ibm-db2", "mssql", "sqlsrv", "mysql", "mysql2", "pgsql", "postgres", "sqlite", "sqlite3", "null", "gearman", "beanstalk", "kafka", "rdkafka", "redis", "stomp", "sqs", "gps", "mongodb" you have to install a package. + dsn: ~ # Required + + # The connection factory class should implement "Interop\Queue\ConnectionFactory" interface + connection_factory_class: ~ + + # The factory class should implement "Enqueue\ConnectionFactoryFactoryInterface" interface + factory_service: ~ + + # The factory service should be a class that implements "Enqueue\ConnectionFactoryFactoryInterface" interface + factory_class: ~ + client: + traceable_producer: true + prefix: enqueue + app_name: app + router_topic: default + router_queue: default + router_processor: Enqueue\Client\RouterProcessor + default_processor_queue: default + redelivered_delay_time: 0 + consumption: + + # the time in milliseconds queue consumer waits for a message (100 ms by default) + receive_timeout: 100 + async_commands: + enabled: false + extensions: + doctrine_ping_connection_extension: false + doctrine_clear_identity_map_extension: false + signal_extension: true + reply_extension: true ``` [back to index](../index.md) diff --git a/docs/bundle/debugging.md b/docs/bundle/debugging.md index f11c1e599..4dd16f05e 100644 --- a/docs/bundle/debugging.md +++ b/docs/bundle/debugging.md @@ -21,8 +21,9 @@ To enable profiler # app/config/config_dev.yml enqueue: - client: - traceable_producer: true + default: + client: + traceable_producer: true ``` Now suppose you have this code in an action: diff --git a/docs/bundle/functional_testing.md b/docs/bundle/functional_testing.md index d19153c5d..6afa4f4c9 100644 --- a/docs/bundle/functional_testing.md +++ b/docs/bundle/functional_testing.md @@ -27,8 +27,9 @@ Here's how you can configure it. # app/config/config_test.yml enqueue: - transport: 'null:' - client: ~ + default: + transport: 'null:' + client: ~ ``` ## Traceable message producer @@ -40,8 +41,9 @@ There is a solution for that. You have to enable traceable message producer in t # app/config/config_test.yml enqueue: - client: - traceable_producer: true + default: + client: + traceable_producer: true ``` If you did so, you can use its methods `getTraces`, `getTopicTraces` or `clearTraces`. Here's an example: diff --git a/docs/bundle/job_queue.md b/docs/bundle/job_queue.md index ffa3dc30c..f33df1d8d 100644 --- a/docs/bundle/job_queue.md +++ b/docs/bundle/job_queue.md @@ -57,9 +57,10 @@ class AppKernel extends Kernel # app/config/config.yml enqueue: - # plus basic bundle configuration - - job: true + default: + # plus basic bundle configuration + + job: true doctrine: # plus basic bundle configuration diff --git a/docs/bundle/quick_tour.md b/docs/bundle/quick_tour.md index 321c88e38..17496102b 100644 --- a/docs/bundle/quick_tour.md +++ b/docs/bundle/quick_tour.md @@ -57,8 +57,9 @@ First, you have to configure a transport layer and set one to be default. # app/config/config.yml enqueue: - transport: "amqp:" - client: ~ + default: + transport: "amqp:" + client: ~ ``` Once you configured everything you can start producing messages: