getDeliveryMonitoringService(); $executionsMonitoringData = $deliveryMonitoringService->find([ DeliveryMonitoringService::STATUS => $this->getUpdateableStatuses() ]); $this->report = Report::createInfo('Updating executions...'); $count = 0; foreach ($executionsMonitoringData as $datum) { try{ $data = $datum->get(); $executionId = $data[DeliveryMonitoringService::DELIVERY_EXECUTION_ID]; if ($this->isBasedOnEndDateTime()){ $deliveryID = $data[DeliveryMonitoringService::DELIVERY_ID]; $endDateTime = $this->getDeliveryEndDateTime($deliveryID); //if no end date time found, fallback to normal updating execution based on TTL. if (!is_null($endDateTime)){ $updated = $this->actionBasedOnEndDate($endDateTime, $executionId); if($updated){ $count++; } continue; } } $updated = $this->actionBasedOnTTL($executionId); if($updated){ $count++; } }catch (\Exception $exception){ $this->report->add(Report::createFailure($exception->getMessage())); } } $this->report->add(Report::createInfo('Number of executions updated: ' . $count)); return $this->report; } /** * Run an action if the end date matches the condition * * @param DateTimeImmutable $endDateTime * @param $executionId * @return bool * @throws \common_exception_Error * @throws \Exception */ protected function actionBasedOnEndDate(DateTimeImmutable $endDateTime, $executionId) { try { $deliveryExecution = $this->getServiceProxy()->getDeliveryExecution($executionId); $lastInteraction = $this->getLastInteractionDateTime($deliveryExecution); if ($lastInteraction === null){ $this->report->add(Report::createFailure('Execution last interaction cannot be found: '. $executionId)); return false; } if (new DateTimeImmutable('now') >= $endDateTime) { $this->action($deliveryExecution, $executionId, true); return true; } $this->report->add(Report::createInfo('Execution not expired yet:'. $executionId . ' Last Interaction:'.$lastInteraction->format('Y-m-d H:i:s') . ' Time when will expire:'.$endDateTime->format('Y-m-d H:i:s') )); } catch (\common_exception_NotFound $e) { $this->report->add(Report::createFailure('Execution cannot be found: '. $executionId)); $this->report->add(Report::createFailure($e->getMessage())); } return false; } /** * Run an action if TTL matches the condition * * @param $executionId * @return bool * @throws \common_exception_Error * @throws \Exception */ protected function actionBasedOnTTL($executionId) { try { $deliveryExecution = $this->getServiceProxy()->getDeliveryExecution($executionId); $lastInteraction = $this->getLastInteractionDateTime($deliveryExecution); if ($lastInteraction === null){ $this->report->add(Report::createFailure('Execution last interaction cannot be found: '. $executionId)); return false; } $ttl = $this->getTtlAsActive(); if ($ttl === null) { $this->report->add(Report::createFailure('Execution ttl not set: '. $executionId)); return false; } $timeUntilToLive = clone $lastInteraction; $timeUntilToLive = $timeUntilToLive->add(new DateInterval($ttl)); if ((new DateTimeImmutable('now')) >= $timeUntilToLive) { $this->action($deliveryExecution, $executionId); return true; } else { $this->report->add(Report::createInfo('Execution not expired yet:'. $executionId . ' Last Interaction: '.$lastInteraction->format('Y-m-d H:i:s') . ' Time when will expire: '.$timeUntilToLive->format('Y-m-d H:i:s') )); } } catch (\common_exception_NotFound $e) { $this->report->add(Report::createFailure('Execution cannot be found: '. $executionId)); $this->report->add(Report::createFailure($e->getMessage())); } return false; } /** * Getting statuses of the delivery executions which needs to be updated * by default used 'active' and 'paused' deliveryExecutions (for backwards compatibility) * @return array|mixed */ protected function getUpdateableStatuses() { return $this->hasOption(self::OPTION_UPDATEABLE_STATUSES) ? $this->getOption(self::OPTION_UPDATEABLE_STATUSES) : [ DeliveryExecution::STATE_ACTIVE, DeliveryExecution::STATE_PAUSED, ]; } /** * @return array|DeliveryExecutionStateService|object */ protected function getDeliveryStateService() { /** @var DeliveryExecutionStateService $service */ $service = $this->getServiceLocator()->get(DeliveryExecutionStateService::SERVICE_ID); return $service; } /** * @return array|DeliveryMonitoringService|object */ protected function getDeliveryMonitoringService() { /** @var DeliveryMonitoringService $service */ $service = $this->getServiceLocator()->get(DeliveryMonitoringService::SERVICE_ID); return $service; } /** * @return array|ServiceProxy|object */ protected function getServiceProxy() { /** @var ServiceProxy $service */ $service = $this->getServiceLocator()->get(ServiceProxy::SERVICE_ID); return $service; } /** * @return array|DeliveryLog|object */ protected function getDeliveryLog() { /** @var DeliveryLog $deliveryLogService */ $deliveryLogService = $this->getServiceLocator()->get(DeliveryLog::SERVICE_ID); return $deliveryLogService; } /** * @param DeliveryExecution $deliveryExecution * @return bool|DateTimeImmutable|null * @throws \common_exception_NotFound * @throws \Exception */ protected function getLastInteractionDateTime(DeliveryExecution $deliveryExecution) { $deliveryLogService = $this->getDeliveryLog(); $testTakerIdentifier = $deliveryExecution->getUserIdentifier(); $events = array_reverse($deliveryLogService->get($deliveryExecution->getIdentifier())); $lastTestTakersEvent = null; foreach ($events as $event) { if ($event[DeliveryLog::CREATED_BY] === $testTakerIdentifier) { $lastTestTakersEvent = $event; break; } } if (!is_null($lastTestTakersEvent)){ $lastEventTime = (new DateTimeImmutable())->setTimestamp($lastTestTakersEvent[DeliveryLog::CREATED_AT]); } else { return null; } return $lastEventTime; } /** * @return string|null */ protected function getTtlAsActive() { return $this->getOption(static::OPTION_TTL_AS_ACTIVE); } /** * @return string|null */ protected function isBasedOnEndDateTime() { return (bool)$this->getOption(static::OPTION_USE_DELIVERY_END_TIME); } /** * @param $deliveryId * @return null|DateTimeImmutable */ protected function getDeliveryEndDateTime($deliveryId) { $delivery = $this->getResource($deliveryId); try { $endDate = (string)$delivery->getUniquePropertyValue($this->getDeliveryEndDateProperty()); return (new DateTimeImmutable)->setTimestamp($endDate); } catch (\Exception $e) { return null; } } /** * Caching property to avoid multiple generations * @return \core_kernel_classes_Property */ private function getDeliveryEndDateProperty() { $this->propertyDeliveryEndDate = $this->propertyDeliveryEndDate ?: $this->getProperty(DeliveryAssemblyService::PROPERTY_END); return $this->propertyDeliveryEndDate; } }