tao-test/app/taoTaskQueue/model/Service/QueueAssociationService.php

159 lines
5.9 KiB
PHP

<?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) 2020 (original work) Open Assessment Technologies SA;
*/
declare(strict_types=1);
namespace oat\taoTaskQueue\model\Service;
use common_exception_Error;
use InvalidArgumentException;
use oat\oatbox\action\Action;
use oat\oatbox\service\ConfigurableService;
use oat\tao\model\taskQueue\Queue;
use oat\tao\model\taskQueue\QueueDispatcher;
use oat\tao\model\taskQueue\QueueDispatcherInterface;
use oat\taoTaskQueue\model\QueueBroker\RdsQueueBroker;
use oat\taoTaskQueue\scripts\tools\BrokerFactory;
use oat\taoTaskQueue\scripts\tools\InitializeQueue;
class QueueAssociationService extends ConfigurableService
{
public function associate(string $taskClass, string $queue): InitializeQueue
{
$targetClass = $this->getTargetClass($taskClass);
$existingQueues = $this->getQueueDispatcher()->getOption(QueueDispatcherInterface::OPTION_QUEUES);
$newQueue = new Queue($queue, new RdsQueueBroker('default', 1), 30);
$existingOptions = $this->getQueueDispatcher()->getOptions();
$existingOptions[QueueDispatcherInterface::OPTION_QUEUES] = array_unique(
array_merge($existingQueues, [$newQueue])
);
$existingAssociations = $this->getQueueDispatcher()->getOption(QueueDispatcherInterface::OPTION_TASK_TO_QUEUE_ASSOCIATIONS);
$existingOptions[QueueDispatcherInterface::OPTION_TASK_TO_QUEUE_ASSOCIATIONS] = array_merge(
$existingAssociations,
[$targetClass => $queue]
);
$this->getQueueDispatcher()->setOptions($existingOptions);
$this->getServiceManager()->register(QueueDispatcherInterface::SERVICE_ID, $this->getQueueDispatcher());
$initializer = new InitializeQueue();
$this->propagate($initializer);
return $initializer;
}
private function getTargetClass(string $taskClass): string
{
if (class_exists($taskClass) && is_a($taskClass, Action::class, true)) {
return $taskClass;
}
throw new InvalidArgumentException(
sprintf('%s - Task must extend %s', $taskClass, Action::class)
);
}
private function getQueueDispatcher(): QueueDispatcher
{
return $this->getServiceLocator()->get(QueueDispatcher::SERVICE_ID);
}
/**
* @throws common_exception_Error
*/
public function associateBulk(
string $newQueueName,
array $newAssociations
): ?Queue {
$factory = $this->getBrokerFactory();
$queueService = $this->getQueueDispatcher();
$existingOptions = $queueService->getOptions();
$existingQueues = $queueService->getOption(QueueDispatcherInterface::OPTION_QUEUES);
$newQueue = null;
if (!in_array($newQueueName, $queueService->getQueueNames())){
$broker = $factory->create($this->guessDefaultBrokerType(), 'default', 2);
$newQueue = new Queue($newQueueName, $broker, 30);
$this->propagate($broker);
$existingOptions[QueueDispatcherInterface::OPTION_QUEUES] = array_merge($existingQueues, [$newQueue]);
}
$existingAssociations = $existingOptions[QueueDispatcherInterface::OPTION_TASK_TO_QUEUE_ASSOCIATIONS];
$existingOptions[QueueDispatcherInterface::OPTION_TASK_TO_QUEUE_ASSOCIATIONS] = array_merge(
$existingAssociations,
$newAssociations
);
$queueService->setOptions($existingOptions);
$this->getServiceManager()->register(QueueDispatcherInterface::SERVICE_ID, $queueService);
return $newQueue;
}
public function guessDefaultBrokerType(): string
{
$queueService = $this->getQueueDispatcher();
$existingQueues = $queueService->getOption(QueueDispatcherInterface::OPTION_QUEUES);
/** @var Queue $queue */
$queue = $existingQueues[0];
$this->propagate($queue);
return $queue->getBroker()->getBrokerId();
}
public function deleteAndRemoveAssociations(string $queueNameForRemoval): void
{
/** @var QueueDispatcher $queueService */
$queueService = $this->getServiceManager()->get(QueueDispatcher::SERVICE_ID);
$existingQueues = $queueService->getOption(QueueDispatcherInterface::OPTION_QUEUES);
$newQueue = [];
/** @var Queue $queue */
foreach ($existingQueues as $queue) {
if ($queue->getName() !== $queueNameForRemoval) {
$newQueue[] = $queue;
}
}
$existingOptions = $queueService->getOptions();
$existingOptions[QueueDispatcherInterface::OPTION_QUEUES] = $newQueue;
$existingAssociations = $existingOptions[QueueDispatcherInterface::OPTION_TASK_TO_QUEUE_ASSOCIATIONS];
$newAssociations = array_filter(
$existingAssociations,
function ($queueName) use ($queueNameForRemoval) {
return $queueNameForRemoval !== $queueName;
}
);
$existingOptions[QueueDispatcherInterface::OPTION_TASK_TO_QUEUE_ASSOCIATIONS] = $newAssociations;
$queueService->setOptions($existingOptions);
$this->getServiceManager()->register(QueueDispatcherInterface::SERVICE_ID, $queueService);
}
private function getBrokerFactory(): BrokerFactory
{
return $this->getServiceManager()->get(BrokerFactory::class);
}
}