<?php /** * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; under version 2 * of the License (non-upgradable). * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (c) 2017 - 2020 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); * */ namespace oat\taoTaskQueue\scripts\tools; use common_report_Report as Report; use InvalidArgumentException; use oat\oatbox\extension\InstallAction; use oat\oatbox\service\ConfigurableService; use oat\tao\model\taskQueue\Queue\TaskSelector\SelectorStrategyInterface; use oat\tao\model\taskQueue\QueueDispatcherInterface; use oat\tao\model\taskQueue\TaskLogInterface; use Zend\ServiceManager\ServiceLocatorAwareTrait; /** * - Without any parameter, it uses the current settings for initialization: * - creates the queues * - creates the task log container * ``` * $ sudo -u www-data php index.php 'oat\taoTaskQueue\scripts\tools\InitializeQueue' * ``` * * - Using Sync Queues. Every existing queue will be changed to use InMemoryQueueBroker if there is no queue specified. * ``` * $ sudo -u www-data php index.php 'oat\taoTaskQueue\scripts\tools\InitializeQueue' --broker=memory [--queue=myQueue] * ``` * * - Using RDS Queues. Every existing queue will be changed to use RdsQueueBroker if there is no queue specified. You can set the following parameters: * - persistence: Required * - receive: Optional (Maximum amount of tasks that can be received when polling the queue) * ``` * $ sudo -u www-data php index.php 'oat\taoTaskQueue\scripts\tools\InitializeQueue' --broker=rds --persistence=default --receive=10 [--queue=myQueue] * ``` * * - Using SQS Queues. Every existing queue will be changed to use SqsQueueBroker if there is no queue specified. You can set the following parameters: * - receive: Optional (Maximum amount of tasks that can be received when polling the queue) * ``` * $ sudo -u www-data php index.php 'oat\taoTaskQueue\scripts\tools\InitializeQueue' --broker=sqs --receive=10 [--queue=myQueue] * ``` * * - To set a task selector strategy, please provide the FQCN of the wanted strategy * ``` * $ sudo -u www-data php index.php 'oat\taoTaskQueue\scripts\tools\InitializeQueue' --strategy="\oat\taoTaskQueue\model\TaskSelector\StrictPriorityStrategy" */ class InitializeQueue extends InstallAction { use ServiceLocatorAwareTrait; private const AVAILABLE_BROKERS = [ BrokerFactory::BROKER_MEMORY, BrokerFactory::BROKER_RDS, BrokerFactory::BROKER_NEW_SQL, BrokerFactory::BROKER_SQS, ]; /** @var string */ private $wantedBroker; /** @var string */ private $persistenceId; /** @var int */ private $receive; /** @var string */ private $queue; /** @var SelectorStrategyInterface */ private $strategy; public function __invoke($params) { try { $this->checkParams($params); $report = Report::createInfo('Running command...'); /** @var QueueDispatcherInterface|ConfigurableService $queueService */ $queueService = $this->getServiceLocator()->get(QueueDispatcherInterface::SERVICE_ID); $registerBroker = $this->registerBroker($params, $queueService); // Create queues if (!$queueService->isSync()) { $queueService->initialize(); $report->add(Report::createSuccess('Queue(s) initialized.')); } if ($registerBroker) { $this->registerService(QueueDispatcherInterface::SERVICE_ID, $queueService); $report->add(Report::createSuccess('Queue service re-registered.')); } // Create task log container /** @var TaskLogInterface $taskLog */ $taskLog = $this->getServiceLocator()->get(TaskLogInterface::SERVICE_ID); $taskLog->createContainer(); $report->add(Report::createSuccess('Task Log container created.')); return $report; } catch (\Exception $e) { return Report::createFailure($e->getMessage()); } } /** * @param array $params */ private function checkParams(array $params) { foreach ($params as $param) { list($option, $value) = explode('=', $param); switch ($option) { case '--broker': if (!in_array($value, self::AVAILABLE_BROKERS)) { throw new InvalidArgumentException( sprintf('Broker "%s" is not a valid broker option. Valid options: %s', $value, implode(', ', self::AVAILABLE_BROKERS) ) ); } $this->wantedBroker = $value; break; case '--persistence': $this->persistenceId = $value; break; case '--receive': $this->receive = abs((int) $value); break; case '--queue': $this->queue = (string) $value; break; case '--strategy': if (!class_exists($value)) { throw new InvalidArgumentException('Strategy "' . $value . '" does not exist.'); } $this->strategy = new $value(); break; } } } private function registerBroker(array $params, QueueDispatcherInterface $queueService): bool { $reRegister = false; // if any new change is wanted on queues if (count($params) > 0) { // BROKER settings if ($this->wantedBroker) { $brokerFactory = $this->getBrokerFactory(); $broker = $brokerFactory->create($this->wantedBroker, $this->persistenceId, $this->receive ?: 1); if (!is_null($this->queue)) { $queue = $queueService->getQueue($this->queue); $queue->setBroker(clone $broker); } else { foreach ($queueService->getQueues() as $queue) { $queue->setBroker(clone $broker); } } } // STRATEGY settings if ($this->strategy) { $queueService->setTaskSelector($this->strategy); } $reRegister = true; } return $reRegister; } private function getBrokerFactory(): BrokerFactory { return $this->getServiceLocator()->get(BrokerFactory::class); } }