179 lines
5.8 KiB
PHP
179 lines
5.8 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) 2017 (original work) Open Assessment Technologies SA;
|
|
*
|
|
*/
|
|
|
|
namespace oat\taoDelivery\model\execution;
|
|
|
|
use common_exception_NotFound;
|
|
use oat\oatbox\event\Event;
|
|
use oat\oatbox\event\EventManager;
|
|
use oat\oatbox\log\LoggerAwareTrait;
|
|
use oat\oatbox\service\ConfigurableService;
|
|
use oat\oatbox\session\SessionService;
|
|
use oat\oatbox\user\User;
|
|
use oat\taoDelivery\models\classes\execution\event\DeliveryExecutionCreated;
|
|
use oat\taoDelivery\models\classes\execution\event\DeliveryExecutionReactivated;
|
|
use oat\taoDelivery\models\classes\execution\event\DeliveryExecutionState as DeliveryExecutionStateEvent;
|
|
|
|
/**
|
|
* Class AbstractStateService
|
|
* @package oat\taoDelivery
|
|
* @author Aleh Hutnikau, <hutnikau@1pt.com>
|
|
*/
|
|
abstract class AbstractStateService extends ConfigurableService implements StateServiceInterface
|
|
{
|
|
use LoggerAwareTrait;
|
|
|
|
public const OPTION_REACTIVABLE_STATES = 'reactivableStates';
|
|
|
|
private const DEFAULT_REACTIVABLE_STATES = [
|
|
DeliveryExecutionInterface::STATE_TERMINATED,
|
|
];
|
|
|
|
private const INTERACTIVE_STATES = [
|
|
DeliveryExecutionInterface::STATE_ACTIVE,
|
|
DeliveryExecutionInterface::STATE_PAUSED,
|
|
];
|
|
|
|
/**
|
|
* Legacy function to ensure all calls to setState use
|
|
* the correct transition instead
|
|
*
|
|
* @param DeliveryExecution $deliveryExecution
|
|
* @param string $state
|
|
*
|
|
* @return bool
|
|
*/
|
|
abstract public function legacyTransition(DeliveryExecution $deliveryExecution, $state);
|
|
|
|
/**
|
|
* Get the status new delivery executions should be started with
|
|
*
|
|
* @param string $deliveryId
|
|
* @param User $user
|
|
*
|
|
* @return string
|
|
*/
|
|
abstract public function getInitialStatus($deliveryId, User $user);
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
public function createDeliveryExecution($deliveryId, User $user, $label)
|
|
{
|
|
$status = $this->getInitialStatus($deliveryId, $user);
|
|
$deliveryExecution = $this->getStorageEngine()->spawnDeliveryExecution($label, $deliveryId, $user->getIdentifier(), $status);
|
|
// trigger event
|
|
$event = new DeliveryExecutionCreated($deliveryExecution, $user);
|
|
$this->getEventManager()->trigger($event);
|
|
|
|
return $deliveryExecution;
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
public function reactivateExecution(DeliveryExecution $deliveryExecution, $reason = null)
|
|
{
|
|
$executionState = $deliveryExecution->getState()->getUri();
|
|
$result = false;
|
|
|
|
if (in_array($executionState, $this->getReactivableStates(), true)) {
|
|
$this->setState($deliveryExecution, DeliveryExecution::STATE_PAUSED, $reason);
|
|
$result = true;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param DeliveryExecution $deliveryExecution
|
|
* @param string $state
|
|
* @param string|array|null $reason
|
|
*
|
|
* @return bool
|
|
*
|
|
* @throws common_exception_NotFound
|
|
*/
|
|
protected function setState(DeliveryExecution $deliveryExecution, string $state, $reason = null): bool
|
|
{
|
|
$previousState = $deliveryExecution->getState()->getUri();
|
|
if ($previousState === $state) {
|
|
$this->logWarning('Delivery execution ' . $deliveryExecution->getIdentifier() . ' already in state ' . $state);
|
|
|
|
return false;
|
|
}
|
|
|
|
$result = $deliveryExecution->getImplementation()->setState($state);
|
|
|
|
$this->emitEvent(new DeliveryExecutionStateEvent($deliveryExecution, $state, $previousState));
|
|
$this->logDebug(sprintf('DeliveryExecutionState from %s to %s triggered', $previousState, $state));
|
|
|
|
if (!$this->isStateInteractive($previousState) && $this->isStateInteractive($state)) {
|
|
$this->emitEvent(
|
|
new DeliveryExecutionReactivated(
|
|
$deliveryExecution,
|
|
$this->getSessionService()->getCurrentUser(),
|
|
$reason
|
|
)
|
|
);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected function getStorageEngine(): DeliveryExecutionService
|
|
{
|
|
/** @noinspection PhpIncompatibleReturnTypeInspection */
|
|
return $this->getServiceLocator()->get(DeliveryExecutionService::SERVICE_ID);
|
|
}
|
|
|
|
private function getSessionService(): SessionService
|
|
{
|
|
/** @noinspection PhpIncompatibleReturnTypeInspection */
|
|
return $this->getServiceLocator()->get(SessionService::SERVICE_ID);
|
|
}
|
|
|
|
private function getEventManager(): EventManager
|
|
{
|
|
/** @noinspection PhpIncompatibleReturnTypeInspection */
|
|
return $this->getServiceLocator()->get(EventManager::SERVICE_ID);
|
|
}
|
|
|
|
private function emitEvent(Event $event): void
|
|
{
|
|
$this->getEventManager()->trigger($event);
|
|
}
|
|
|
|
private function getReactivableStates(): array
|
|
{
|
|
if (!$this->hasOption(self::OPTION_REACTIVABLE_STATES)) {
|
|
return self::DEFAULT_REACTIVABLE_STATES;
|
|
}
|
|
|
|
return $this->getOption(self::OPTION_REACTIVABLE_STATES);
|
|
}
|
|
|
|
private function isStateInteractive(string $state): bool
|
|
{
|
|
return in_array($state, self::INTERACTIVE_STATES, true);
|
|
}
|
|
}
|