From cb220c4c93067e3e688e67a80e1ca6b50b05dc4c Mon Sep 17 00:00:00 2001 From: "nicolas.couet" Date: Thu, 18 Feb 2016 15:43:54 +0100 Subject: [PATCH 1/7] first realease bundle --- .gitignore | 2 + CHANGELOG.md | 5 + Command/AddMessagesCommand.php | 68 +++++++++ Command/CreateQueuesCommand.php | 150 ++++++++++++++++++ Command/DeleteQueuesCommand.php | 152 +++++++++++++++++++ Command/GetMessagesCommand.php | 80 ++++++++++ Command/ListPrioritiesCommand.php | 57 +++++++ Command/PurgeQueuesCommand.php | 152 +++++++++++++++++++ Command/QueuesInfoCommand.php | 139 +++++++++++++++++ DependencyInjection/Configuration.php | 43 ++++++ DependencyInjection/QueueClientExtension.php | 50 ++++++ QueueClientAdapterFactory.php | 46 ++++++ QueueClientBundle.php | 9 ++ QueueClientFactory.php | 74 +++++++++ README.md | 73 ++++++++- Resources/config/queues.yml | 1 + Resources/config/services.yml | 24 +++ Utils/Output.php | 75 +++++++++ composer.json | 25 +++ doc/queues-configuration-file.md | 27 ++++ 20 files changed, 1250 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 Command/AddMessagesCommand.php create mode 100644 Command/CreateQueuesCommand.php create mode 100644 Command/DeleteQueuesCommand.php create mode 100644 Command/GetMessagesCommand.php create mode 100644 Command/ListPrioritiesCommand.php create mode 100644 Command/PurgeQueuesCommand.php create mode 100644 Command/QueuesInfoCommand.php create mode 100644 DependencyInjection/Configuration.php create mode 100644 DependencyInjection/QueueClientExtension.php create mode 100644 QueueClientAdapterFactory.php create mode 100644 QueueClientBundle.php create mode 100644 QueueClientFactory.php create mode 100644 Resources/config/queues.yml create mode 100644 Resources/config/services.yml create mode 100644 Utils/Output.php create mode 100644 composer.json create mode 100644 doc/queues-configuration-file.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7579f74 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +vendor +composer.lock diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6ef2fb1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Queue Client Bundle Changelog + +## v1.0.0 + +- Initial commit diff --git a/Command/AddMessagesCommand.php b/Command/AddMessagesCommand.php new file mode 100644 index 0000000..0c29294 --- /dev/null +++ b/Command/AddMessagesCommand.php @@ -0,0 +1,68 @@ +setName('queue-client:add-messages') + ->setDescription('Add message in queue') + ->addOption('priority', 'p', InputOption::VALUE_OPTIONAL, 'Add in queue with specific priority') + ->addArgument('queueName', InputArgument::REQUIRED, 'queue') + ->addArgument('messages', InputArgument::IS_ARRAY, 'messages to add') + ->setHelp(<<getContainer()->get('logger'); + } catch (ServiceNotFoundException $e) { + $logger = null; + } + $this->output = new Output($logger, $output); + /** @var QueueClientInterface $queueClient */ + $queueClient = $this->getContainer()->get('queue_client'); + + $priority = null; + if ($input->getOption('priority')) { + $priority = $input->getOption('priority'); + if (!in_array($priority, $queueClient->getPriorityHandler()->getAll())) { + throw new \InvalidArgumentException('Priority "' . $priority . '" not found.'); + } + } + + $queueName = $input->getArgument('queueName'); + $messages = $input->getArgument('messages'); + + $queueClient->addMessages($queueName, $messages, $priority); + + return 0; + } +} diff --git a/Command/CreateQueuesCommand.php b/Command/CreateQueuesCommand.php new file mode 100644 index 0000000..9b5ab2f --- /dev/null +++ b/Command/CreateQueuesCommand.php @@ -0,0 +1,150 @@ +setName('queue-client:create-queues') + ->setDescription('Create queues') + ->addOption('file', 'f', InputOption::VALUE_REQUIRED, 'File to read') + ->addArgument('queues', InputArgument::IS_ARRAY, 'queues to create') + ->setHelp(<<getContainer()); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::CRITICAL); + return 1; + } + if (null === $yml) { + $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); + return 1; + } + if (array_key_exists(static::QUEUES_NODE, $yml)) { + if (null === $yml[static::QUEUES_NODE]) { + $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); + return 1; + } + $this->output->write('Start create queue.', Output::INFO); + foreach ($yml[static::QUEUES_NODE] as $queue) { + if (empty($queue[static::QUEUE_NAME_NODE])) { + $this->output->write('Empty ' . static::QUEUE_NAME_NODE . ' node.', Output::CRITICAL); + } + $queueName = $queue[static::QUEUE_NAME_NODE]; + try { + $queueClient->createQueue($queueName); + $this->output->write('Queue ' . $queueName . ' created.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); + } + if (!empty($queue[static::QUEUE_ALIASES_NODE])) { + foreach ($queue[static::QUEUE_ALIASES_NODE] as $alias) { + try { + $queueClient->addAlias($queueName, $alias); + $this->output->write('Queue alias ' . $alias . ' -> ' . $queueName . ' found.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); + } + } + } + } + $this->output->write('End create queue.', Output::INFO); + } else { + $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); + return 1; + } + return 0; + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + /** @var LoggerInterface $logger */ + $logger = $this->getContainer()->get('logger'); + } catch (ServiceNotFoundException $e) { + $logger = null; + } + $this->output = new Output($logger, $output); + try { + /** @var QueueClientInterface $queueClient */ + $queueClient = $this->getContainer()->get('queue_client'); + } catch (ServiceNotFoundException $e) { + $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; + } + if ($input->getOption('file')) { + $fileName = $input->getOption('file'); + return $this->createFromFile($queueClient, $fileName); + } else { + $queues = $input->getArgument('queues'); + if (count($queues)) { + foreach ($queues as $queue) { + try { + $queueClient->createQueue($queue); + $this->output->write('Queue ' . $queue . ' created.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); + } + } + return 0; + } + try { + $fileName = $this->getContainer()->getParameter('queue_client.queues_file'); + return $this->createFromFile($queueClient, $fileName); + } catch (InvalidArgumentException $e) { + $this->output->write('No queue_client.queues_file parameter found.', Output::CRITICAL); + return 1; + } + } + } +} diff --git a/Command/DeleteQueuesCommand.php b/Command/DeleteQueuesCommand.php new file mode 100644 index 0000000..11ed42e --- /dev/null +++ b/Command/DeleteQueuesCommand.php @@ -0,0 +1,152 @@ +setName('queue-client:delete-queues') + ->setDescription('Delete queues') + ->addOption('file', 'f', InputOption::VALUE_REQUIRED, 'File to read') + ->addOption('force', null, InputOption::VALUE_NONE, 'If set, the task will not ask for confirm delete') + ->addArgument('queues', InputArgument::IS_ARRAY, 'queues to delete') + ->setHelp(<<getContainer()); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::CRITICAL); + return 1; + } + if (null === $yml) { + $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); + return 1; + } + if (array_key_exists(static::QUEUES_NODE, $yml)) { + if (null === $yml[static::QUEUES_NODE]) { + $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); + return 1; + } + $this->output->write('Start delete queue.', Output::INFO); + foreach ($yml[static::QUEUES_NODE] as $queue) { + if (empty($queue[static::QUEUE_NAME_NODE])) { + $this->output->write('Empty ' . static::QUEUE_NAME_NODE . ' node.', Output::CRITICAL); + } + $queueName = $queue[static::QUEUE_NAME_NODE]; + try { + $queueClient->deleteQueue($queueName); + $this->output->write('Queue ' . $queueName . ' deleted.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); + } + } + $this->output->write('End delete queue.', Output::INFO); + } else { + $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); + return 1; + } + return 0; + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $helper = $this->getHelper('question'); + $force = $input->getOption('force') ? true : false; + try { + /** @var LoggerInterface $logger */ + $logger = $this->getContainer()->get('logger'); + } catch (ServiceNotFoundException $e) { + $logger = null; + } + $this->output = new Output($logger, $output); + try { + /** @var QueueClientInterface $queueClient */ + $queueClient = $this->getContainer()->get('queue_client'); + } catch (ServiceNotFoundException $e) { + $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; + } + if ($input->getOption('file')) { + $fileName = $input->getOption('file'); + if (!($force || $helper->ask($input, $output, new ConfirmationQuestion('Delete queues in file "' . $fileName . '"?', false)))) { + return 0; + } + return $this->deleteFromFile($queueClient, $fileName); + } else { + $queues = $input->getArgument('queues'); + if (count($queues)) { + if (!($force || $helper->ask($input, $output, new ConfirmationQuestion(implode("\n", $queues) . "\nDelete queues list above?" , false)))) { + return 0; + } + foreach ($queues as $queue) { + try { + $queueClient->deleteQueue($queue); + $this->output->write('Queue ' . $queue . ' deleted.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); + } + } + return 0; + } + try { + $fileName = $this->getContainer()->getParameter('queue_client.queues_file'); + if (!($force || $helper->ask($input, $output, new ConfirmationQuestion('Delete queues in file "' . $fileName . '"?', false)))) { + return 0; + } + return $this->deleteFromFile($queueClient, $fileName); + } catch (InvalidArgumentException $e) { + $this->output->write('No queue_client.queues_file parameter found.', Output::CRITICAL); + return 1; + } + } + } +} diff --git a/Command/GetMessagesCommand.php b/Command/GetMessagesCommand.php new file mode 100644 index 0000000..06875cf --- /dev/null +++ b/Command/GetMessagesCommand.php @@ -0,0 +1,80 @@ +setName('queue-client:get-messages') + ->setDescription('Get messages from queue') + ->addOption('number-messages', 'c', InputOption::VALUE_OPTIONAL, 'Number of messages to be retrieved') + ->addOption('pop', null, InputOption::VALUE_NONE, 'If set, the task will remove ask messages from queue') + ->addOption('priority', 'p', InputOption::VALUE_OPTIONAL, 'Get messages from specific priority') + ->addArgument('queueName', InputArgument::REQUIRED, 'queue') + ->setHelp(<<getContainer()->get('logger'); + } catch (ServiceNotFoundException $e) { + $logger = null; + } + $this->output = new Output($logger, $output); + try { + /** @var QueueClientInterface $queueClient */ + $queueClient = $this->getContainer()->get('queue_client'); + } catch (ServiceNotFoundException $e) { + $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; + } + $queueName = $input->getArgument('queueName'); + $numberMessages = $input->getOption('number-messages') ?: 1; + $priority = null; + if ($input->getOption('priority')) { + $priority = $input->getOption('priority'); + if (!in_array($priority, $queueClient->getPriorityHandler()->getAll())) { + throw new \InvalidArgumentException('Priority "' . $priority . '" not found.'); + } + } + $messages = $queueClient->getMessages($queueName, $numberMessages, $priority); + foreach ($messages as $message) { + if (is_array($message['Body'])) { + $output->writeln(json_encode($message['Body'])); + } else { + $output->writeln($message['Body']); + } + } + if ($input->getOption('pop')) { + $queueClient->deleteMessages($queueName, $messages); + } + return 0; + } +} diff --git a/Command/ListPrioritiesCommand.php b/Command/ListPrioritiesCommand.php new file mode 100644 index 0000000..7ad65e7 --- /dev/null +++ b/Command/ListPrioritiesCommand.php @@ -0,0 +1,57 @@ +setName('queue-client:list-priorities') + ->setDescription('List priorities') + ->setHelp(<<getContainer()->get('logger'); + } catch (ServiceNotFoundException $e) { + $logger = null; + } + $this->output = new Output($logger, $output); + try { + /** @var QueueClientInterface $queueClient */ + $queueClient = $this->getContainer()->get('queue_client'); + } catch (ServiceNotFoundException $e) { + $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; + } + foreach ($queueClient->getPriorityHandler()->getAll() as $priority) { + $output->writeln($priority); + } + return 0; + } +} diff --git a/Command/PurgeQueuesCommand.php b/Command/PurgeQueuesCommand.php new file mode 100644 index 0000000..e7992b8 --- /dev/null +++ b/Command/PurgeQueuesCommand.php @@ -0,0 +1,152 @@ +setName('queue-client:purge-queues') + ->setDescription('Purge queues') + ->addOption('file', 'f', InputOption::VALUE_REQUIRED, 'File to read') + ->addOption('force', null, InputOption::VALUE_NONE, 'If set, the task will not ask for confirm purge') + ->addArgument('queues', InputArgument::IS_ARRAY, 'queues to purge') + ->setHelp(<<getContainer()); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::CRITICAL); + return 1; + } + if (null === $yml) { + $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); + return 1; + } + if (array_key_exists(static::QUEUES_NODE, $yml)) { + if (null === $yml[static::QUEUES_NODE]) { + $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); + return 1; + } + $this->output->write('Start purge queue.', Output::INFO); + foreach ($yml[static::QUEUES_NODE] as $queue) { + if (empty($queue[static::QUEUE_NAME_NODE])) { + $this->output->write('Empty ' . static::QUEUE_NAME_NODE . ' node.', Output::CRITICAL); + } + $queueName = $queue[static::QUEUE_NAME_NODE]; + try { + $queueClient->purgeQueue($queueName); + $this->output->write('Queue ' . $queueName . ' purged.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); + } + } + $this->output->write('End purge queue.', Output::INFO); + } else { + $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); + return 1; + } + return 0; + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $helper = $this->getHelper('question'); + $force = $input->getOption('force') ? true : false; + try { + /** @var LoggerInterface $logger */ + $logger = $this->getContainer()->get('logger'); + } catch (ServiceNotFoundException $e) { + $logger = null; + } + $this->output = new Output($logger, $output); + try { + /** @var QueueClientInterface $queueClient */ + $queueClient = $this->getContainer()->get('queue_client'); + } catch (ServiceNotFoundException $e) { + $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; + } + if ($input->getOption('file')) { + $fileName = $input->getOption('file'); + if (!($force || $helper->ask($input, $output, new ConfirmationQuestion('Purge queues in file "' . $fileName . '"?', false)))) { + return 0; + } + return $this->purgeFromFile($queueClient, $fileName); + } else { + $queues = $input->getArgument('queues'); + if (count($queues)) { + if (!($force || $helper->ask($input, $output, new ConfirmationQuestion(implode("\n", $queues) . "\nPurge queues list above?" , false)))) { + return 0; + } + foreach ($queues as $queue) { + try { + $queueClient->purgeQueue($queue); + $this->output->write('Queue ' . $queue . ' purged.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); + } + } + return 0; + } + try { + $fileName = $this->getContainer()->getParameter('queue_client.queues_file'); + if (!($force || $helper->ask($input, $output, new ConfirmationQuestion('Purge queues in file "' . $fileName . '"?', false)))) { + return 0; + } + return $this->purgeFromFile($queueClient, $fileName); + } catch (InvalidArgumentException $e) { + $this->output->write('No queue_client.queues_file parameter found.', Output::CRITICAL); + return 1; + } + } + } +} diff --git a/Command/QueuesInfoCommand.php b/Command/QueuesInfoCommand.php new file mode 100644 index 0000000..e02b9d8 --- /dev/null +++ b/Command/QueuesInfoCommand.php @@ -0,0 +1,139 @@ +setName('queue-client:queues-info') + ->setDescription('Display queues information') + ->addOption('no-header', null, InputOption::VALUE_NONE, 'Skip header display') + ->addOption('alias', 'a', InputOption::VALUE_NONE, 'Display queues aliases info') + ->addOption('count', 'c', InputOption::VALUE_NONE, 'Display count messages in queue info') + ->addOption('priority', 'p', InputOption::VALUE_NONE, 'Display count message for each priorities') + ->addArgument('queues', InputArgument::IS_ARRAY, 'select info from specific queues') + ->setHelp(<<getContainer()->get('logger'); + } catch (ServiceNotFoundException $e) { + $logger = null; + } + $this->output = new Output($logger, $output); + try { + /** @var QueueClientInterface $queueClient */ + $queueClient = $this->getContainer()->get('queue_client'); + } catch (ServiceNotFoundException $e) { + $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; + } + $queues = $input->getArgument('queues'); + $queuesList = $queueClient->listQueues(); + if (0 === count($queues)) { + try { + $queues = $queuesList; + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::ERROR); + return 1; + } + } + + $table = new Table($output); + $arrayRows = []; + $queuesAliases = []; + $priorities = []; + + if ($input->getOption('alias')) { + $queuesAliases = $queueClient->getAliases(); + } + if ($input->getOption('priority')) { + $priorities = $queueClient->getPriorityHandler()->getAll(); + } + foreach ($queues as $queue) { + if (in_array($queue, $queuesList)) { + $row = [$queue]; + if ($input->getOption('count')) { + if ($input->getOption('priority')) { + foreach ($priorities as $priority) { + $count = $queueClient->getNumberMessages($queue, $priority); + $row[] = $count; + } + } else { + $count = $queueClient->getNumberMessages($queue); + $row[] = $count; + } + } + if ($input->getOption('alias')) { + $aliases = []; + foreach ($queuesAliases as $keyAlias => $alias) { + $keys = array_keys($alias, $queue); + foreach ($keys as $key) { + $aliases[] = $keyAlias; + } + } + $row[] = implode(',', $aliases); + } + $arrayRows[] = $row; + } else { + $this->output->write('Queue "' . $queue . '" does not exists.', Output::WARNING); + } + } + if (empty($queues)) { + $this->output->write('No queue found.', Output::NOTICE); + return 0; + } + $table->setRows($arrayRows); + if (!$input->getOption('no-header')) { + $headers = []; + $headers['main'] = ['Name']; + if ($input->getOption('count')) { + if ($input->getOption('priority')) { + $headers['main'][] = new TableCell('Messages number', array('colspan' => 3)); + $headers['sub'][] = ''; + foreach ($priorities as $priority) { + $headers['sub'][] = $priority; + } + } else { + $headers['main'][] = 'Messages number'; + } + } + if ($input->getOption('alias')) { + $headers['main'][] = 'Aliases'; + } + $table->setHeaders($headers); + } + $table->render(); + return 0; + } +} diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php new file mode 100644 index 0000000..facffa0 --- /dev/null +++ b/DependencyInjection/Configuration.php @@ -0,0 +1,43 @@ +root('queue_client'); + + $rootNode + ->children() + ->arrayNode('adapter') + ->isRequired() + ->children() + ->scalarNode('type') + ->isRequired() + ->beforeNormalization() + ->always() + ->then(function ($v) { return strtolower($v); }) + ->end() + ->end() + ->scalarNode('key')->end() + ->scalarNode('secret')->end() + ->scalarNode('region')->defaultValue('eu-west-1')->end() + ->scalarNode('version')->defaultValue('2012-11-05')->end() + ->scalarNode('repository')->defaultValue('/tmp/queues')->end() + ->end() + ->end() + ->scalarNode('queues_file') + ->defaultValue(__DIR__.'/../Resources/config/queues.yml') + ->end() + ->scalarNode('priority_handler') + ->defaultValue('ReputationVIP\QueueClient\PriorityHandler\StandardPriorityHandler') + ->end(); + + return $treeBuilder; + } +} diff --git a/DependencyInjection/QueueClientExtension.php b/DependencyInjection/QueueClientExtension.php new file mode 100644 index 0000000..820247c --- /dev/null +++ b/DependencyInjection/QueueClientExtension.php @@ -0,0 +1,50 @@ + 'ReputationVIP\QueueClient\Adapter\SQSAdapter', + 'file' => 'ReputationVIP\QueueClient\Adapter\FileAdapter', + 'memory' => 'ReputationVIP\QueueClient\Adapter\MemoryAdapter', + 'null' => 'ReputationVIP\QueueClient\Adapter\NullAdapter' + ); + $configuration = new Configuration(); + $config = $this->processConfiguration($configuration, $configs); + + $loader = new YamlFileLoader( + $container, + new FileLocator(__DIR__.'/../Resources/config') + ); + $loader->load('services.yml'); + + if (!isset($adapterChoice[$config['adapter']['type']])) { + throw new \InvalidArgumentException('Unknown handler type : ' . $config['adapter']['type']); + } + + $container->setParameter( + 'queue_client.adapter.priority_handler.class', + $config['priority_handler'] + ); + $container->setParameter( + 'queue_client.queues_file', + $config['queues_file'] + ); + $container->setParameter( + 'queue_client.adapter.class', + $adapterChoice[$config['adapter']['type']] + ); + $container->setParameter( + 'queue_client.config', + $config['adapter'] + ); + } +} diff --git a/QueueClientAdapterFactory.php b/QueueClientAdapterFactory.php new file mode 100644 index 0000000..df1297e --- /dev/null +++ b/QueueClientAdapterFactory.php @@ -0,0 +1,46 @@ + $config['region'], + 'version' => $config['version'], + 'credentials' => array( + 'key' => $config['key'], + 'secret' => $config['secret'], + ), + )), $priorityHandler); + break; + case 'memory': + $adapter = new MemoryAdapter($priorityHandler); + break; + } + return $adapter; + } +} diff --git a/QueueClientBundle.php b/QueueClientBundle.php new file mode 100644 index 0000000..980baae --- /dev/null +++ b/QueueClientBundle.php @@ -0,0 +1,9 @@ +getParameter($param), $item); + } + else { + throw new \InvalidArgumentException('Empty parameter!'); + } + } + } + } + + /** + * @param ContainerInterface $container + * @param AdapterInterface $adapter + * @param string $queuesFile + * @return null|QueueClientInterface + * @throws \ErrorException + */ + public function get($container, $adapter, $queuesFile) + { + $queueClient = new QueueClient($adapter); + + $yml = Yaml::parse(file_get_contents($queuesFile)); + array_walk_recursive($yml, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $container); + if (array_key_exists(static::QUEUES_NODE, $yml)) { + if (null === $yml[static::QUEUES_NODE]) { + throw new \InvalidArgumentException('Empty ' . static::QUEUES_NODE . ' node.'); + } + foreach ($yml[static::QUEUES_NODE] as $queue) { + $queueName = $queue[static::QUEUE_NAME_NODE]; + if (!empty($queue[static::QUEUE_ALIASES_NODE])) { + foreach ($queue[static::QUEUE_ALIASES_NODE] as $alias) { + try { + $queueClient->addAlias($queueName, $alias); + } catch (\ErrorException $e) { + if ($e->getSeverity() === E_ERROR) { + throw $e; + } + } + } + } + } + } else { + throw new \InvalidArgumentException('No ' . static::QUEUES_NODE . ' node found in ' . $queuesFile . '.'); + } + return $queueClient; + } +} diff --git a/README.md b/README.md index 3ab99a5..e515c50 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,71 @@ -# queue-client-bundle -An easy way to use queue client library in Symfony project with his own Symfony bundle. +# Queue Client Bundle + +[![Join the chat at https://gitter.im/ReputationVIP/queue-client](https://badges.gitter.im/ReputationVIP/queue-client.svg)](https://gitter.im/ReputationVIP/queue-client?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +An easy way to use [queue client library](https://github.com/ReputationVIP/queue-client) in [Symfony](http://symfony.com) project with its own [Symfony](http://symfony.com) bundle. + +## Available commands + +- `queue-client:add-messages` Add message in queue +- `queue-client:create-queues` Create queues +- `queue-client:delete-queues` Delete queues +- `queue-client:get-messages` Get messages from queue +- `queue-client:list-priorities` List priorities +- `queue-client:purge-queues` Purge queues +- `queue-client:queues-info` Display queues information + +Use `--help` option for command usage. + +## Configuration + +Add queue client configuration in config.yml and retrieve the service using Symfony container. + +``` +container->get('queue-client') +``` + +`queue_client` node needs an ```adapter``` node to define the adapter to be used. +`adapter` node must define a ```type``` parameter (see "Available adapter types") + +Then add specific configuration for each ```type```. + +``` +queue_client: + adapter: + type: queue type +``` + +Sample configuration: +``` +queue_client: + queues_file: %kernel.root_dir%/config/queues.yml + adapter: + type: file + repository: /tmp/queues + priority_handler: 'ReputationVIP\QueueClient\PriorityHandler\ThreeLevelPriorityHandler' + +``` + +### General configuration + +- ```queues_file``` specifies the default [queues configuration file](doc/queues-configuration-file.md). +- ```priority_handler``` specifies the priority handler. Default is the `ReputationVIP\QueueClient\PriorityHandler\StandardPriorityHandler`. + +### Available adapter types + +- ```null``` a black hole type. +- ```memory``` a memory type. +- ```file``` a file queue type. +- ```sqs``` a SQS queue type. + +### File type Configuration + +- ```repository```: this config value set the absolute path of the repository which contains queues files (default `/tmp/queues`). + +### SQS type Configuration + +- ```key:``` this config value set the SQS key. +- ```secret:``` this config value set the SQS secret. +- ```region:``` this config value set the SQS region (default `eu-west-1`). +- ```version:``` this config value set the SQS version (default `2012-11-05`). + diff --git a/Resources/config/queues.yml b/Resources/config/queues.yml new file mode 100644 index 0000000..9a23959 --- /dev/null +++ b/Resources/config/queues.yml @@ -0,0 +1 @@ +queues: diff --git a/Resources/config/services.yml b/Resources/config/services.yml new file mode 100644 index 0000000..354d445 --- /dev/null +++ b/Resources/config/services.yml @@ -0,0 +1,24 @@ +services: + queue_client_adapter_priority_handler: + class: "%queue_client.adapter.priority_handler.class%" + + queue_client_adapter_factory: + class: ReputationVIP\Bundle\QueueClientBundle\QueueClientAdapterFactory + + queue_client_factory: + class: ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory + + queue_client_adapter: + class: "%queue_client.adapter.class%" + factory: ["@queue_client_adapter_factory", get] + arguments: + - "%queue_client.config%" + - "@queue_client_adapter_priority_handler" + + queue_client: + class: ReputationVIP\QueueClient\QueueClient + factory: ["@queue_client_factory", get] + arguments: + - "@service_container" + - "@queue_client_adapter" + - "%queue_client.queues_file%" diff --git a/Utils/Output.php b/Utils/Output.php new file mode 100644 index 0000000..878af3d --- /dev/null +++ b/Utils/Output.php @@ -0,0 +1,75 @@ +logger = $logger; + $this->output = $output; + } + + public function write($msg, $level) { + if (null !== $this->logger) { + switch ($level) { + case self::ERROR : + $this->logger->error($msg); + break; + case self::CRITICAL : + $this->logger->critical($msg); + break; + case self::INFO : + $this->logger->info($msg); + break; + case self::NOTICE : + $this->logger->notice($msg); + break; + case self::WARNING : + $this->logger->warning($msg); + break; + default : + $this->logger->debug($msg); + } + } else { + switch ($level) { + case self::ERROR : + $this->output->writeln('' . $msg . ''); + break; + case self::CRITICAL : + $this->output->writeln('' . $msg . ''); + break; + case self::INFO : + $this->output->writeln('' . $msg . ''); + break; + case self::NOTICE : + $this->output->writeln('' . $msg . ''); + break; + case self::WARNING : + $this->output->writeln('' . $msg . ''); + break; + default : + $this->output->writeln($msg); + } + } + } +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..08f9e95 --- /dev/null +++ b/composer.json @@ -0,0 +1,25 @@ +{ + "name": "reputation-vip/queue-client-bundle", + "description": "Queue Client Symfony Bundle", + "authors": [ + { + "name": "Nicolas Couet", + "email": "tejerka@gmail.com" + } + ], + "require": { + "reputation-vip/queue-client": "~1.0", + "symfony/http-kernel": ">=2.7", + "symfony/config": ">=2.7", + "symfony/dependency-injection": ">=2.7", + "symfony/framework-bundle": ">=2.7", + "symfony/console": ">=2.7", + "symfony/yaml": ">=2.7", + "psr/log": "^1.0" + }, + "autoload": { + "psr-4": { + "ReputationVIP\\Bundle\\QueueClientBundle\\": "/" + } + } +} diff --git a/doc/queues-configuration-file.md b/doc/queues-configuration-file.md new file mode 100644 index 0000000..4cd3dbe --- /dev/null +++ b/doc/queues-configuration-file.md @@ -0,0 +1,27 @@ +# Queues configuration file + +## Usage + +this file describe your queues structure. +It require a main node `queues` with one sub node for each queue. + +## Sample + +``` +queues: + queue1: + name: queue1 + aliases: + - queue1-alias1 + - queue1-alias2 + queue2: + name: queue2 + aliases: + - queue2-alias1 + - queue2-alias2 + queue3: + name: queue3 + aliases: + - queue3-alias1 + - queue3-alias2 +``` \ No newline at end of file From 4e14e4982aa77a5f03e5d6490a7f54ab38d86c7e Mon Sep 17 00:00:00 2001 From: "nicolas.couet" Date: Thu, 18 Feb 2016 17:11:18 +0100 Subject: [PATCH 2/7] pull request fix --- .gitignore | 2 +- Command/AddMessagesCommand.php | 5 +-- Command/CreateQueuesCommand.php | 9 +++--- Command/DeleteQueuesCommand.php | 9 +++--- Command/GetMessagesCommand.php | 5 +-- Command/ListPrioritiesCommand.php | 5 +-- Command/PurgeQueuesCommand.php | 9 +++--- Command/QueuesInfoCommand.php | 5 +-- DependencyInjection/Configuration.php | 44 +++++++++++++++------------ 9 files changed, 44 insertions(+), 49 deletions(-) diff --git a/.gitignore b/.gitignore index 7579f74..3a9875b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -vendor +/vendor/ composer.lock diff --git a/Command/AddMessagesCommand.php b/Command/AddMessagesCommand.php index 0c29294..fd1f9a8 100644 --- a/Command/AddMessagesCommand.php +++ b/Command/AddMessagesCommand.php @@ -27,10 +27,7 @@ protected function configure() ->addOption('priority', 'p', InputOption::VALUE_OPTIONAL, 'Add in queue with specific priority') ->addArgument('queueName', InputArgument::REQUIRED, 'queue') ->addArgument('messages', InputArgument::IS_ARRAY, 'messages to add') - ->setHelp(<<setHelp('This command add messages in queue.'); } /** diff --git a/Command/CreateQueuesCommand.php b/Command/CreateQueuesCommand.php index 9b5ab2f..32f1efa 100644 --- a/Command/CreateQueuesCommand.php +++ b/Command/CreateQueuesCommand.php @@ -33,16 +33,16 @@ protected function configure() ->addOption('file', 'f', InputOption::VALUE_REQUIRED, 'File to read') ->addArgument('queues', InputArgument::IS_ARRAY, 'queues to create') ->setHelp(<<getContainer()); diff --git a/Command/DeleteQueuesCommand.php b/Command/DeleteQueuesCommand.php index 11ed42e..25461e2 100644 --- a/Command/DeleteQueuesCommand.php +++ b/Command/DeleteQueuesCommand.php @@ -34,16 +34,16 @@ protected function configure() ->addOption('force', null, InputOption::VALUE_NONE, 'If set, the task will not ask for confirm delete') ->addArgument('queues', InputArgument::IS_ARRAY, 'queues to delete') ->setHelp(<<getContainer()); diff --git a/Command/GetMessagesCommand.php b/Command/GetMessagesCommand.php index 06875cf..d4daa9c 100644 --- a/Command/GetMessagesCommand.php +++ b/Command/GetMessagesCommand.php @@ -28,10 +28,7 @@ protected function configure() ->addOption('pop', null, InputOption::VALUE_NONE, 'If set, the task will remove ask messages from queue') ->addOption('priority', 'p', InputOption::VALUE_OPTIONAL, 'Get messages from specific priority') ->addArgument('queueName', InputArgument::REQUIRED, 'queue') - ->setHelp(<<setHelp('This command get messages from queue'); } /** diff --git a/Command/ListPrioritiesCommand.php b/Command/ListPrioritiesCommand.php index 7ad65e7..65d73c9 100644 --- a/Command/ListPrioritiesCommand.php +++ b/Command/ListPrioritiesCommand.php @@ -22,10 +22,7 @@ protected function configure() $this ->setName('queue-client:list-priorities') ->setDescription('List priorities') - ->setHelp(<<setHelp('This command list available message priorities.'); } /** diff --git a/Command/PurgeQueuesCommand.php b/Command/PurgeQueuesCommand.php index e7992b8..51ff205 100644 --- a/Command/PurgeQueuesCommand.php +++ b/Command/PurgeQueuesCommand.php @@ -34,16 +34,16 @@ protected function configure() ->addOption('force', null, InputOption::VALUE_NONE, 'If set, the task will not ask for confirm purge') ->addArgument('queues', InputArgument::IS_ARRAY, 'queues to purge') ->setHelp(<<getContainer()); diff --git a/Command/QueuesInfoCommand.php b/Command/QueuesInfoCommand.php index e02b9d8..2748c67 100644 --- a/Command/QueuesInfoCommand.php +++ b/Command/QueuesInfoCommand.php @@ -31,10 +31,7 @@ protected function configure() ->addOption('count', 'c', InputOption::VALUE_NONE, 'Display count messages in queue info') ->addOption('priority', 'p', InputOption::VALUE_NONE, 'Display count message for each priorities') ->addArgument('queues', InputArgument::IS_ARRAY, 'select info from specific queues') - ->setHelp(<<setHelp('This command display queues information.'); } /** diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index facffa0..11f5310 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -14,28 +14,32 @@ public function getConfigTreeBuilder() $rootNode ->children() - ->arrayNode('adapter') - ->isRequired() - ->children() - ->scalarNode('type') - ->isRequired() - ->beforeNormalization() - ->always() - ->then(function ($v) { return strtolower($v); }) + ->arrayNode('adapter') + ->isRequired() + ->children() + ->scalarNode('type') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('key')->end() + ->scalarNode('secret')->end() + ->scalarNode('region') + ->defaultValue('eu-west-1') + ->end() + ->scalarNode('version') + ->defaultValue('2012-11-05') + ->end() + ->scalarNode('repository') + ->defaultValue('/tmp/queues') + ->end() + ->end() ->end() + ->scalarNode('queues_file') + ->defaultValue(__DIR__.'/../Resources/config/queues.yml') + ->end() + ->scalarNode('priority_handler') + ->defaultValue('ReputationVIP\QueueClient\PriorityHandler\StandardPriorityHandler') ->end() - ->scalarNode('key')->end() - ->scalarNode('secret')->end() - ->scalarNode('region')->defaultValue('eu-west-1')->end() - ->scalarNode('version')->defaultValue('2012-11-05')->end() - ->scalarNode('repository')->defaultValue('/tmp/queues')->end() - ->end() - ->end() - ->scalarNode('queues_file') - ->defaultValue(__DIR__.'/../Resources/config/queues.yml') - ->end() - ->scalarNode('priority_handler') - ->defaultValue('ReputationVIP\QueueClient\PriorityHandler\StandardPriorityHandler') ->end(); return $treeBuilder; From 76cf127937915dd608d9015ea13a1b1754ccb877 Mon Sep 17 00:00:00 2001 From: "nicolas.couet" Date: Thu, 18 Feb 2016 17:51:59 +0100 Subject: [PATCH 3/7] line before return --- Command/CreateQueuesCommand.php | 10 ++++++++++ Command/DeleteQueuesCommand.php | 13 +++++++++++++ Command/GetMessagesCommand.php | 2 ++ Command/ListPrioritiesCommand.php | 2 ++ Command/PurgeQueuesCommand.php | 13 +++++++++++++ Command/QueuesInfoCommand.php | 4 ++++ QueueClientAdapterFactory.php | 1 + QueueClientFactory.php | 1 + 8 files changed, 46 insertions(+) diff --git a/Command/CreateQueuesCommand.php b/Command/CreateQueuesCommand.php index 32f1efa..fc99902 100644 --- a/Command/CreateQueuesCommand.php +++ b/Command/CreateQueuesCommand.php @@ -60,15 +60,18 @@ private function createFromFile($queueClient, $fileName) array_walk_recursive($yml, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); } catch (\Exception $e) { $this->output->write($e->getMessage(), Output::CRITICAL); + return 1; } if (null === $yml) { $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); + return 1; } if (array_key_exists(static::QUEUES_NODE, $yml)) { if (null === $yml[static::QUEUES_NODE]) { $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); + return 1; } $this->output->write('Start create queue.', Output::INFO); @@ -97,8 +100,10 @@ private function createFromFile($queueClient, $fileName) $this->output->write('End create queue.', Output::INFO); } else { $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); + return 1; } + return 0; } @@ -121,10 +126,12 @@ protected function execute(InputInterface $input, OutputInterface $output) $queueClient = $this->getContainer()->get('queue_client'); } catch (ServiceNotFoundException $e) { $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; } if ($input->getOption('file')) { $fileName = $input->getOption('file'); + return $this->createFromFile($queueClient, $fileName); } else { $queues = $input->getArgument('queues'); @@ -137,13 +144,16 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->output->write($e->getMessage(), Output::WARNING); } } + return 0; } try { $fileName = $this->getContainer()->getParameter('queue_client.queues_file'); + return $this->createFromFile($queueClient, $fileName); } catch (InvalidArgumentException $e) { $this->output->write('No queue_client.queues_file parameter found.', Output::CRITICAL); + return 1; } } diff --git a/Command/DeleteQueuesCommand.php b/Command/DeleteQueuesCommand.php index 25461e2..8f9588c 100644 --- a/Command/DeleteQueuesCommand.php +++ b/Command/DeleteQueuesCommand.php @@ -61,15 +61,18 @@ private function deleteFromFile($queueClient, $fileName) array_walk_recursive($yml, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); } catch (\Exception $e) { $this->output->write($e->getMessage(), Output::CRITICAL); + return 1; } if (null === $yml) { $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); + return 1; } if (array_key_exists(static::QUEUES_NODE, $yml)) { if (null === $yml[static::QUEUES_NODE]) { $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); + return 1; } $this->output->write('Start delete queue.', Output::INFO); @@ -88,8 +91,10 @@ private function deleteFromFile($queueClient, $fileName) $this->output->write('End delete queue.', Output::INFO); } else { $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); + return 1; } + return 0; } @@ -114,18 +119,22 @@ protected function execute(InputInterface $input, OutputInterface $output) $queueClient = $this->getContainer()->get('queue_client'); } catch (ServiceNotFoundException $e) { $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; } if ($input->getOption('file')) { $fileName = $input->getOption('file'); if (!($force || $helper->ask($input, $output, new ConfirmationQuestion('Delete queues in file "' . $fileName . '"?', false)))) { + return 0; } + return $this->deleteFromFile($queueClient, $fileName); } else { $queues = $input->getArgument('queues'); if (count($queues)) { if (!($force || $helper->ask($input, $output, new ConfirmationQuestion(implode("\n", $queues) . "\nDelete queues list above?" , false)))) { + return 0; } foreach ($queues as $queue) { @@ -136,16 +145,20 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->output->write($e->getMessage(), Output::WARNING); } } + return 0; } try { $fileName = $this->getContainer()->getParameter('queue_client.queues_file'); if (!($force || $helper->ask($input, $output, new ConfirmationQuestion('Delete queues in file "' . $fileName . '"?', false)))) { + return 0; } + return $this->deleteFromFile($queueClient, $fileName); } catch (InvalidArgumentException $e) { $this->output->write('No queue_client.queues_file parameter found.', Output::CRITICAL); + return 1; } } diff --git a/Command/GetMessagesCommand.php b/Command/GetMessagesCommand.php index d4daa9c..7c8690b 100644 --- a/Command/GetMessagesCommand.php +++ b/Command/GetMessagesCommand.php @@ -50,6 +50,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $queueClient = $this->getContainer()->get('queue_client'); } catch (ServiceNotFoundException $e) { $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; } $queueName = $input->getArgument('queueName'); @@ -72,6 +73,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($input->getOption('pop')) { $queueClient->deleteMessages($queueName, $messages); } + return 0; } } diff --git a/Command/ListPrioritiesCommand.php b/Command/ListPrioritiesCommand.php index 65d73c9..cd0aa00 100644 --- a/Command/ListPrioritiesCommand.php +++ b/Command/ListPrioritiesCommand.php @@ -44,11 +44,13 @@ protected function execute(InputInterface $input, OutputInterface $output) $queueClient = $this->getContainer()->get('queue_client'); } catch (ServiceNotFoundException $e) { $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; } foreach ($queueClient->getPriorityHandler()->getAll() as $priority) { $output->writeln($priority); } + return 0; } } diff --git a/Command/PurgeQueuesCommand.php b/Command/PurgeQueuesCommand.php index 51ff205..0d696d7 100644 --- a/Command/PurgeQueuesCommand.php +++ b/Command/PurgeQueuesCommand.php @@ -61,15 +61,18 @@ private function purgeFromFile($queueClient, $fileName) array_walk_recursive($yml, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); } catch (\Exception $e) { $this->output->write($e->getMessage(), Output::CRITICAL); + return 1; } if (null === $yml) { $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); + return 1; } if (array_key_exists(static::QUEUES_NODE, $yml)) { if (null === $yml[static::QUEUES_NODE]) { $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); + return 1; } $this->output->write('Start purge queue.', Output::INFO); @@ -88,8 +91,10 @@ private function purgeFromFile($queueClient, $fileName) $this->output->write('End purge queue.', Output::INFO); } else { $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); + return 1; } + return 0; } @@ -114,18 +119,22 @@ protected function execute(InputInterface $input, OutputInterface $output) $queueClient = $this->getContainer()->get('queue_client'); } catch (ServiceNotFoundException $e) { $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; } if ($input->getOption('file')) { $fileName = $input->getOption('file'); if (!($force || $helper->ask($input, $output, new ConfirmationQuestion('Purge queues in file "' . $fileName . '"?', false)))) { + return 0; } + return $this->purgeFromFile($queueClient, $fileName); } else { $queues = $input->getArgument('queues'); if (count($queues)) { if (!($force || $helper->ask($input, $output, new ConfirmationQuestion(implode("\n", $queues) . "\nPurge queues list above?" , false)))) { + return 0; } foreach ($queues as $queue) { @@ -136,16 +145,20 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->output->write($e->getMessage(), Output::WARNING); } } + return 0; } try { $fileName = $this->getContainer()->getParameter('queue_client.queues_file'); if (!($force || $helper->ask($input, $output, new ConfirmationQuestion('Purge queues in file "' . $fileName . '"?', false)))) { + return 0; } + return $this->purgeFromFile($queueClient, $fileName); } catch (InvalidArgumentException $e) { $this->output->write('No queue_client.queues_file parameter found.', Output::CRITICAL); + return 1; } } diff --git a/Command/QueuesInfoCommand.php b/Command/QueuesInfoCommand.php index 2748c67..26cf3ad 100644 --- a/Command/QueuesInfoCommand.php +++ b/Command/QueuesInfoCommand.php @@ -53,6 +53,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $queueClient = $this->getContainer()->get('queue_client'); } catch (ServiceNotFoundException $e) { $this->output->write('No queue client service found.', Output::CRITICAL); + return 1; } $queues = $input->getArgument('queues'); @@ -62,6 +63,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $queues = $queuesList; } catch (\Exception $e) { $this->output->write($e->getMessage(), Output::ERROR); + return 1; } } @@ -108,6 +110,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } if (empty($queues)) { $this->output->write('No queue found.', Output::NOTICE); + return 0; } $table->setRows($arrayRows); @@ -131,6 +134,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $table->setHeaders($headers); } $table->render(); + return 0; } } diff --git a/QueueClientAdapterFactory.php b/QueueClientAdapterFactory.php index df1297e..9597a4d 100644 --- a/QueueClientAdapterFactory.php +++ b/QueueClientAdapterFactory.php @@ -41,6 +41,7 @@ public function get($config, $priorityHandler) { $adapter = new MemoryAdapter($priorityHandler); break; } + return $adapter; } } diff --git a/QueueClientFactory.php b/QueueClientFactory.php index 3fb7ba4..b286114 100644 --- a/QueueClientFactory.php +++ b/QueueClientFactory.php @@ -69,6 +69,7 @@ public function get($container, $adapter, $queuesFile) } else { throw new \InvalidArgumentException('No ' . static::QUEUES_NODE . ' node found in ' . $queuesFile . '.'); } + return $queueClient; } } From 42d26946ba6e87982174edbfb889746ea51dfd94 Mon Sep 17 00:00:00 2001 From: "nicolas.couet" Date: Thu, 18 Feb 2016 17:53:30 +0100 Subject: [PATCH 4/7] fix pull request comment --- doc/queues-configuration-file.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/queues-configuration-file.md b/doc/queues-configuration-file.md index 4cd3dbe..e521558 100644 --- a/doc/queues-configuration-file.md +++ b/doc/queues-configuration-file.md @@ -2,8 +2,8 @@ ## Usage -this file describe your queues structure. -It require a main node `queues` with one sub node for each queue. +this file describes your queues structure. +It requires a main node `queues` with one sub node for each queue. ## Sample From 9f3daabeb583185a4c395231440eeed7efb9a27b Mon Sep 17 00:00:00 2001 From: Olivier Balais Date: Thu, 18 Feb 2016 23:02:15 +0100 Subject: [PATCH 5/7] Switch yaml validation implementation to ConfigurationInterface --- Command/CreateQueuesCommand.php | 8 ++++++-- Command/DeleteQueuesCommand.php | 8 ++++++-- Configuration/QueuesConfiguration.php | 29 +++++++++++++++++++++++++++ doc/queues-configuration-file.md | 2 +- 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 Configuration/QueuesConfiguration.php diff --git a/Command/CreateQueuesCommand.php b/Command/CreateQueuesCommand.php index fc99902..5690597 100644 --- a/Command/CreateQueuesCommand.php +++ b/Command/CreateQueuesCommand.php @@ -5,8 +5,10 @@ use InvalidArgumentException; use Psr\Log\LoggerInterface; use ReputationVIP\Bundle\QueueClientBundle\Utils\Output; +use ReputationVIP\Bundle\QueuesConfiguration\QueuesConfiguration; use ReputationVIP\QueueClient\QueueClientInterface; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -56,8 +58,10 @@ protected function configure() private function createFromFile($queueClient, $fileName) { try { - $yml = Yaml::parse(file_get_contents($fileName)); - array_walk_recursive($yml, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); + $processor = new Processor(); + $configuration = new QueuesConfiguration(); + $processedConfiguration = $processor->processConfiguration($configuration, Yaml::parse(file_get_contents($fileName))); + } catch (\Exception $e) { $this->output->write($e->getMessage(), Output::CRITICAL); diff --git a/Command/DeleteQueuesCommand.php b/Command/DeleteQueuesCommand.php index 8f9588c..09d72b0 100644 --- a/Command/DeleteQueuesCommand.php +++ b/Command/DeleteQueuesCommand.php @@ -5,8 +5,10 @@ use InvalidArgumentException; use Psr\Log\LoggerInterface; use ReputationVIP\Bundle\QueueClientBundle\Utils\Output; +use ReputationVIP\Bundle\QueuesConfiguration\QueuesConfiguration; use ReputationVIP\QueueClient\QueueClientInterface; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -57,8 +59,10 @@ protected function configure() private function deleteFromFile($queueClient, $fileName) { try { - $yml = Yaml::parse(file_get_contents($fileName)); - array_walk_recursive($yml, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); + $processor = new Processor(); + $configuration = new QueuesConfiguration(); + $processedConfiguration = $processor->processConfiguration($configuration, Yaml::parse(file_get_contents($fileName))); + } catch (\Exception $e) { $this->output->write($e->getMessage(), Output::CRITICAL); diff --git a/Configuration/QueuesConfiguration.php b/Configuration/QueuesConfiguration.php new file mode 100644 index 0000000..ec5a324 --- /dev/null +++ b/Configuration/QueuesConfiguration.php @@ -0,0 +1,29 @@ +root('queues'); + + $rootNode + ->prototype('array') + ->children() + ->scalarNode('name')->end() + ->arrayNode('aliases') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ; + + + return $treeBuilder; + } +} diff --git a/doc/queues-configuration-file.md b/doc/queues-configuration-file.md index e521558..276d82b 100644 --- a/doc/queues-configuration-file.md +++ b/doc/queues-configuration-file.md @@ -24,4 +24,4 @@ queues: aliases: - queue3-alias1 - queue3-alias2 -``` \ No newline at end of file +``` From 072899d1d2f1acc94ad64ebadcc80f5e3b6dae76 Mon Sep 17 00:00:00 2001 From: "nicolas.couet" Date: Fri, 19 Feb 2016 15:39:53 +0100 Subject: [PATCH 6/7] use ConfigurationInterface to parse yml file --- Command/CreateQueuesCommand.php | 52 ++++++++------------------- Command/DeleteQueuesCommand.php | 43 ++++++---------------- Command/PurgeQueuesCommand.php | 48 +++++++++---------------- Configuration/QueuesConfiguration.php | 26 +++++++++----- DependencyInjection/Configuration.php | 1 + QueueClientFactory.php | 39 ++++++++------------ 6 files changed, 75 insertions(+), 134 deletions(-) diff --git a/Command/CreateQueuesCommand.php b/Command/CreateQueuesCommand.php index 5690597..a6b1ae7 100644 --- a/Command/CreateQueuesCommand.php +++ b/Command/CreateQueuesCommand.php @@ -5,7 +5,7 @@ use InvalidArgumentException; use Psr\Log\LoggerInterface; use ReputationVIP\Bundle\QueueClientBundle\Utils\Output; -use ReputationVIP\Bundle\QueuesConfiguration\QueuesConfiguration; +use ReputationVIP\Bundle\QueueClientBundle\Configuration\QueuesConfiguration; use ReputationVIP\QueueClient\QueueClientInterface; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Config\Definition\Processor; @@ -18,10 +18,6 @@ class CreateQueuesCommand extends ContainerAwareCommand { - const QUEUES_NODE = 'queues'; - const QUEUE_NAME_NODE = 'name'; - const QUEUE_ALIASES_NODE = 'aliases'; - /** * @var Output $output */ @@ -67,46 +63,26 @@ private function createFromFile($queueClient, $fileName) return 1; } - if (null === $yml) { - $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); - - return 1; - } - if (array_key_exists(static::QUEUES_NODE, $yml)) { - if (null === $yml[static::QUEUES_NODE]) { - $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); - - return 1; + array_walk_recursive($processedConfiguration, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); + $this->output->write('Start create queue.', Output::INFO); + foreach ($processedConfiguration[QueuesConfiguration::QUEUES_NODE] as $queue) { + $queueName = $queue[QueuesConfiguration::QUEUE_NAME_NODE]; + try { + $queueClient->createQueue($queueName); + $this->output->write('Queue ' . $queueName . ' created.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); } - $this->output->write('Start create queue.', Output::INFO); - foreach ($yml[static::QUEUES_NODE] as $queue) { - if (empty($queue[static::QUEUE_NAME_NODE])) { - $this->output->write('Empty ' . static::QUEUE_NAME_NODE . ' node.', Output::CRITICAL); - } - $queueName = $queue[static::QUEUE_NAME_NODE]; + foreach ($queue[QueuesConfiguration::QUEUE_ALIASES_NODE] as $alias) { try { - $queueClient->createQueue($queueName); - $this->output->write('Queue ' . $queueName . ' created.', Output::INFO); + $queueClient->addAlias($queueName, $alias); + $this->output->write('Queue alias ' . $alias . ' -> ' . $queueName . ' found.', Output::INFO); } catch (\Exception $e) { $this->output->write($e->getMessage(), Output::WARNING); } - if (!empty($queue[static::QUEUE_ALIASES_NODE])) { - foreach ($queue[static::QUEUE_ALIASES_NODE] as $alias) { - try { - $queueClient->addAlias($queueName, $alias); - $this->output->write('Queue alias ' . $alias . ' -> ' . $queueName . ' found.', Output::INFO); - } catch (\Exception $e) { - $this->output->write($e->getMessage(), Output::WARNING); - } - } - } } - $this->output->write('End create queue.', Output::INFO); - } else { - $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); - - return 1; } + $this->output->write('End create queue.', Output::INFO); return 0; } diff --git a/Command/DeleteQueuesCommand.php b/Command/DeleteQueuesCommand.php index 09d72b0..98da8db 100644 --- a/Command/DeleteQueuesCommand.php +++ b/Command/DeleteQueuesCommand.php @@ -4,8 +4,8 @@ use InvalidArgumentException; use Psr\Log\LoggerInterface; +use ReputationVIP\Bundle\QueueClientBundle\Configuration\QueuesConfiguration; use ReputationVIP\Bundle\QueueClientBundle\Utils\Output; -use ReputationVIP\Bundle\QueuesConfiguration\QueuesConfiguration; use ReputationVIP\QueueClient\QueueClientInterface; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Config\Definition\Processor; @@ -19,9 +19,6 @@ class DeleteQueuesCommand extends ContainerAwareCommand { - const QUEUES_NODE = 'queues'; - const QUEUE_NAME_NODE = 'name'; - /** * @var Output $output */ @@ -68,36 +65,18 @@ private function deleteFromFile($queueClient, $fileName) return 1; } - if (null === $yml) { - $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); - - return 1; - } - if (array_key_exists(static::QUEUES_NODE, $yml)) { - if (null === $yml[static::QUEUES_NODE]) { - $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); - - return 1; - } - $this->output->write('Start delete queue.', Output::INFO); - foreach ($yml[static::QUEUES_NODE] as $queue) { - if (empty($queue[static::QUEUE_NAME_NODE])) { - $this->output->write('Empty ' . static::QUEUE_NAME_NODE . ' node.', Output::CRITICAL); - } - $queueName = $queue[static::QUEUE_NAME_NODE]; - try { - $queueClient->deleteQueue($queueName); - $this->output->write('Queue ' . $queueName . ' deleted.', Output::INFO); - } catch (\Exception $e) { - $this->output->write($e->getMessage(), Output::WARNING); - } + array_walk_recursive($processedConfiguration, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); + $this->output->write('Start delete queue.', Output::INFO); + foreach ($processedConfiguration[QueuesConfiguration::QUEUES_NODE] as $queue) { + $queueName = $queue[QueuesConfiguration::QUEUE_NAME_NODE]; + try { + $queueClient->deleteQueue($queueName); + $this->output->write('Queue ' . $queueName . ' deleted.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); } - $this->output->write('End delete queue.', Output::INFO); - } else { - $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); - - return 1; } + $this->output->write('End delete queue.', Output::INFO); return 0; } diff --git a/Command/PurgeQueuesCommand.php b/Command/PurgeQueuesCommand.php index 0d696d7..19376d6 100644 --- a/Command/PurgeQueuesCommand.php +++ b/Command/PurgeQueuesCommand.php @@ -4,9 +4,11 @@ use InvalidArgumentException; use Psr\Log\LoggerInterface; +use ReputationVIP\Bundle\QueueClientBundle\Configuration\QueuesConfiguration; use ReputationVIP\Bundle\QueueClientBundle\Utils\Output; use ReputationVIP\QueueClient\QueueClientInterface; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -17,8 +19,6 @@ class PurgeQueuesCommand extends ContainerAwareCommand { - const QUEUES_NODE = 'queues'; - const QUEUE_NAME_NODE = 'name'; /** * @var Output $output @@ -57,43 +57,27 @@ protected function configure() private function purgeFromFile($queueClient, $fileName) { try { - $yml = Yaml::parse(file_get_contents($fileName)); - array_walk_recursive($yml, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); + $processor = new Processor(); + $configuration = new QueuesConfiguration(); + $processedConfiguration = $processor->processConfiguration($configuration, Yaml::parse(file_get_contents($fileName))); + } catch (\Exception $e) { $this->output->write($e->getMessage(), Output::CRITICAL); return 1; } - if (null === $yml) { - $this->output->write('File ' . $fileName . ' is empty.', Output::WARNING); - - return 1; - } - if (array_key_exists(static::QUEUES_NODE, $yml)) { - if (null === $yml[static::QUEUES_NODE]) { - $this->output->write('Empty ' . static::QUEUES_NODE . ' node.', Output::CRITICAL); - - return 1; - } - $this->output->write('Start purge queue.', Output::INFO); - foreach ($yml[static::QUEUES_NODE] as $queue) { - if (empty($queue[static::QUEUE_NAME_NODE])) { - $this->output->write('Empty ' . static::QUEUE_NAME_NODE . ' node.', Output::CRITICAL); - } - $queueName = $queue[static::QUEUE_NAME_NODE]; - try { - $queueClient->purgeQueue($queueName); - $this->output->write('Queue ' . $queueName . ' purged.', Output::INFO); - } catch (\Exception $e) { - $this->output->write($e->getMessage(), Output::WARNING); - } + array_walk_recursive($processedConfiguration, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $this->getContainer()); + $this->output->write('Start delete queue.', Output::INFO); + foreach ($processedConfiguration[QueuesConfiguration::QUEUES_NODE] as $queue) { + $queueName = $queue[QueuesConfiguration::QUEUE_NAME_NODE]; + try { + $queueClient->deleteQueue($queueName); + $this->output->write('Queue ' . $queueName . ' deleted.', Output::INFO); + } catch (\Exception $e) { + $this->output->write($e->getMessage(), Output::WARNING); } - $this->output->write('End purge queue.', Output::INFO); - } else { - $this->output->write('No ' . static::QUEUES_NODE . ' node found in ' . $fileName . '.', Output::CRITICAL); - - return 1; } + $this->output->write('End delete queue.', Output::INFO); return 0; } diff --git a/Configuration/QueuesConfiguration.php b/Configuration/QueuesConfiguration.php index ec5a324..c62cb2c 100644 --- a/Configuration/QueuesConfiguration.php +++ b/Configuration/QueuesConfiguration.php @@ -1,29 +1,39 @@ root('queues'); + $rootNode = $treeBuilder->root(static::ROOT_NODE); $rootNode - ->prototype('array') - ->children() - ->scalarNode('name')->end() - ->arrayNode('aliases') - ->prototype('scalar')->end() + ->children() + ->arrayNode(static::QUEUES_NODE) + ->isRequired() + ->prototype('array') + ->children() + ->scalarNode(static::QUEUE_NAME_NODE) + ->isRequired() + ->end() + ->arrayNode(static::QUEUE_ALIASES_NODE) + ->prototype('scalar')->end() + ->end() ->end() ->end() ->end() ; - return $treeBuilder; } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 11f5310..2a1f78e 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -7,6 +7,7 @@ class Configuration implements ConfigurationInterface { + public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); diff --git a/QueueClientFactory.php b/QueueClientFactory.php index b286114..98304aa 100644 --- a/QueueClientFactory.php +++ b/QueueClientFactory.php @@ -2,17 +2,16 @@ namespace ReputationVIP\Bundle\QueueClientBundle; +use ReputationVIP\Bundle\QueueClientBundle\Configuration\QueuesConfiguration; use ReputationVIP\QueueClient\Adapter\AdapterInterface; use ReputationVIP\QueueClient\QueueClient; use ReputationVIP\QueueClient\QueueClientInterface; +use Symfony\Component\Config\Definition\Processor; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Yaml\Yaml; class QueueClientFactory { - const QUEUES_NODE = 'queues'; - const QUEUE_NAME_NODE = 'name'; - const QUEUE_ALIASES_NODE = 'aliases'; /** * @param $item @@ -27,8 +26,7 @@ public static function resolveParameters(&$item, $key, $container) $param = $matches[0]; if (!empty($param)) { $item = str_replace('%' . $param . '%', $container->getParameter($param), $item); - } - else { + } else { throw new \InvalidArgumentException('Empty parameter!'); } } @@ -45,29 +43,22 @@ public static function resolveParameters(&$item, $key, $container) public function get($container, $adapter, $queuesFile) { $queueClient = new QueueClient($adapter); + $processor = new Processor(); + $configuration = new QueuesConfiguration(); + $processedConfiguration = $processor->processConfiguration($configuration, Yaml::parse(file_get_contents($queuesFile))); - $yml = Yaml::parse(file_get_contents($queuesFile)); - array_walk_recursive($yml, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $container); - if (array_key_exists(static::QUEUES_NODE, $yml)) { - if (null === $yml[static::QUEUES_NODE]) { - throw new \InvalidArgumentException('Empty ' . static::QUEUES_NODE . ' node.'); - } - foreach ($yml[static::QUEUES_NODE] as $queue) { - $queueName = $queue[static::QUEUE_NAME_NODE]; - if (!empty($queue[static::QUEUE_ALIASES_NODE])) { - foreach ($queue[static::QUEUE_ALIASES_NODE] as $alias) { - try { - $queueClient->addAlias($queueName, $alias); - } catch (\ErrorException $e) { - if ($e->getSeverity() === E_ERROR) { - throw $e; - } - } + array_walk_recursive($processedConfiguration, 'ReputationVIP\Bundle\QueueClientBundle\QueueClientFactory::resolveParameters', $container); + foreach ($processedConfiguration[QueuesConfiguration::QUEUES_NODE] as $queue) { + $queueName = $queue[QueuesConfiguration::QUEUE_NAME_NODE]; + foreach ($queue[QueuesConfiguration::QUEUE_ALIASES_NODE] as $alias) { + try { + $queueClient->addAlias($queueName, $alias); + } catch (\ErrorException $e) { + if ($e->getSeverity() === E_ERROR) { + throw $e; } } } - } else { - throw new \InvalidArgumentException('No ' . static::QUEUES_NODE . ' node found in ' . $queuesFile . '.'); } return $queueClient; From 40e3203df65029ce1770f207b258f5dfa483b5ab Mon Sep 17 00:00:00 2001 From: "nicolas.couet" Date: Fri, 19 Feb 2016 15:46:30 +0100 Subject: [PATCH 7/7] Maj documentation --- CHANGELOG.md | 2 +- Resources/config/queues.yml | 3 ++- doc/queues-configuration-file.md | 33 ++++++++++++++++---------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ef2fb1..adfa2cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,4 +2,4 @@ ## v1.0.0 -- Initial commit +- Initial release diff --git a/Resources/config/queues.yml b/Resources/config/queues.yml index 9a23959..945d877 100644 --- a/Resources/config/queues.yml +++ b/Resources/config/queues.yml @@ -1 +1,2 @@ -queues: +queue_client: + queues: diff --git a/doc/queues-configuration-file.md b/doc/queues-configuration-file.md index 276d82b..024ab66 100644 --- a/doc/queues-configuration-file.md +++ b/doc/queues-configuration-file.md @@ -8,20 +8,21 @@ It requires a main node `queues` with one sub node for each queue. ## Sample ``` -queues: - queue1: - name: queue1 - aliases: - - queue1-alias1 - - queue1-alias2 - queue2: - name: queue2 - aliases: - - queue2-alias1 - - queue2-alias2 - queue3: - name: queue3 - aliases: - - queue3-alias1 - - queue3-alias2 +queue_client: + queues: + queue1: + name: queue1 + aliases: + - queue1-alias1 + - queue1-alias2 + queue2: + name: queue2 + aliases: + - queue2-alias1 + - queue2-alias2 + queue3: + name: queue3 + aliases: + - queue3-alias1 + - queue3-alias2 ```