/**
  * @param Elasticsearch\Job $job
  * @param Token $token
  * @return OrchestrationTask[]
  */
 public function findTasksByJob(Elasticsearch\Job $job, Token $token)
 {
     $data = $this->components->getConfiguration(KeboolaOrchestratorBundle::SYRUP_COMPONENT_NAME, (new Entity\Orchestration())->setId($job->getOrchestrationId())->getId());
     if (empty($data['configuration']['tasks'])) {
         return array();
     }
     $data = $data['configuration']['tasks'];
     /** @var OrchestrationTask[] $rows */
     $rows = array_map(function ($line) use($token) {
         $task = new OrchestrationTask($token);
         $task->fromArray($line);
         return $task;
     }, $data['configuration']['tasks']);
     return $this->sortTasks($rows);
 }
예제 #2
0
 /**
  * @param Elasticsearch\Job $job
  * @param StorageApi\OrchestrationTask $task
  * @param Encryptor $encryptor
  * @return \GuzzleHttp\Psr7\Response
  */
 public function sendOrchestratorRequest(Elasticsearch\Job $job, StorageApi\OrchestrationTask $task, Encryptor $encryptor)
 {
     $timeout = $task->getTimeoutMinutes() ? $task->getTimeoutMinutes() : KeboolaOrchestratorBundle::TIMEOUT_MINUTES;
     try {
         return $this->post($task->getComponentUrl(), array('config' => array('curl' => array(CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0)), 'body' => json_encode($task->getActionParameters()), 'headers' => array('X-StorageApi-Token' => $encryptor->decrypt($job->getToken()), 'X-KBC-RunId' => $job->getRunId(), 'X-User-Agent', KeboolaOrchestratorBundle::SYRUP_COMPONENT_NAME . " - JobExecutor"), 'timeout' => $timeout * 60));
     } catch (RequestException $e) {
         $handlerContext = $e->getHandlerContext();
         if (is_array($handlerContext)) {
             if (array_key_exists('errno', $handlerContext)) {
                 if ($handlerContext['errno'] == CURLE_OPERATION_TIMEOUTED) {
                     $this->logger->debug('curl.debug', array('handlerContext' => $e->getHandlerContext()));
                     //						throw new Exception\JobRuntimeException(sprintf('Task processing timeout after %d minutes', $timeout));
                 }
             }
         }
         throw $e;
     }
 }
예제 #3
0
 /**
  * @param \Exception $e
  * @param \Monolog\Logger $logger
  * @return StorageApiEvent
  * @throws \Keboola\StorageApi\Exception
  */
 public function someError(\Exception $e, \Monolog\Logger $logger)
 {
     $exceptionId = KeboolaOrchestratorBundle::SYRUP_COMPONENT_NAME . '-' . md5(microtime());
     $code = $e->getCode() < 300 || $e->getCode() >= 600 ? 500 : $e->getCode();
     if ($e instanceof HttpExceptionInterface) {
         $code = $e->getStatusCode();
     }
     $content = array('status' => 'error', 'error' => 'Application error', 'code' => $code, 'message' => 'Contact support@keboola.com and attach this exception id.', 'exceptionId' => $exceptionId);
     $logger->error($e->getMessage(), $content);
     $event = $this->prepareEvent();
     $event->setMessage(sprintf(self::MESSAGE_END, $this->task->getRunUrl()))->setDescription(sprintf('%s %s', $content['message'], $content['exceptionId']))->setType(StorageApiEvent::TYPE_WARN)->setResults(array('exceptionId' => $exceptionId));
     $this->save($event);
     return $event;
 }
 /**
  * @param Orchestration $entity
  * @param \Keboola\StorageApi\Client $storageApi
  * @return Orchestration
  */
 public function fillOrchestrationEntity(Orchestration $entity, Client $storageApi)
 {
     /** @var $entity Orchestration */
     $entity = parent::fillEntity($entity);
     if (!$entity->getTokenId()) {
         $entity->setTokenId($storageApi->createToken('manage', sprintf('Orchestrator %s', $entity->getName()), null, true));
     }
     // fill token data
     $token = $storageApi->getToken($entity->getTokenId());
     $token = new Token(new Client(array('token' => $token['token'], 'url' => $storageApi->getApiUrl())));
     $entity->setToken($token)->setTokenId($token->getId())->setTokenDesc($token->getDescription())->setTokenOwnerName($token->getOwnerName())->setProjectId($token->getProjectId());
     // notifications
     $data = $this->getPostJsonData();
     if (!empty($data['notifications'])) {
         $data['notifications'] = array_map(function ($row) {
             $notification = new Notification();
             $notification->fromArray($row);
             return $notification;
         }, $data['notifications']);
         $entity->setNotifications($data['notifications']);
     }
     // tasks
     $data = $this->getPostJsonData();
     if (!empty($data['tasks'])) {
         $data['tasks'] = array_map(function ($row) {
             $notification = new OrchestrationTask();
             $notification->fromArray($row);
             return $notification;
         }, $data['tasks']);
         foreach ($data['tasks'] as $task) {
             $entity->addTask($task);
         }
     }
     //@FIXME catch and throw exception
     return $entity;
 }
예제 #5
0
 public function execute(SyrupJob $job)
 {
     parent::build($job);
     $jobLogger = new JobLogger($this->job, $this->storageApi);
     try {
         $jobLogger->start($this->stopwatch->getEvent(self::STOPWATCH_ORCHESTRATION_EVENT));
         if ($this->job->getTasks()) {
             /** @var StorageApi\OrchestrationTask[] $rows */
             $orchestrationTasks = array_map(function ($line) {
                 $task = new StorageApi\OrchestrationTask();
                 $task->fromArray(json_decode(json_encode($line), true));
                 return $task;
             }, $this->job->getTasks());
         } else {
             $orchestrationTasks = $this->loadTasks($this->job, $this->token);
             if (!$this->job->getTasks() && $orchestrationTasks) {
                 $this->logger->info('orchestration.job.emptyTasks', array('jobId' => $this->job->getId(), 'orchestrationId' => $this->job->getOrchestrationId(), 'orchestrationName' => $this->job->getOrchestrationName(), 'projectId' => $this->job->getProjectId()));
             }
         }
         // fill result
         foreach ($orchestrationTasks as $task) {
             $this->jobResult->addTaskResult(new TaskResult($task));
         }
         $this->saveJobResult($this->jobResult);
         foreach ($orchestrationTasks as $task) {
             // skip inactive taks
             if (!$task->getActive()) {
                 continue;
             }
             try {
                 $taskResult = (new TaskResult($task))->setProcessingStatus();
                 $this->jobResult->addTaskResult($taskResult);
                 $this->saveJobResult($this->jobResult);
                 $result = $this->executeJobTask($this->job, $taskResult, $this->storageApi);
                 $this->jobResult->addTaskResult($result);
                 $this->saveJobResult($this->jobResult);
                 if (!$task->getContinueOnFailure() && $result->getError()) {
                     break;
                 }
                 if ($task->getContinueOnFailure() && $result->getError()) {
                     continue;
                 }
             } catch (\Exception $taskE) {
                 //@FIXME better handling = not log to sapi
                 throw Exception\JobRuntimeException::factory($taskE);
             }
         }
         $jobLogger->end($this->jobResult);
         $status = StatusConverter::orchestratorToSyrup($this->jobResult->getEventType());
         $result = array('tasks' => $this->jobResult->toArray());
         if ($status === SyrupJob::STATUS_SUCCESS) {
             return $result;
         }
         if ($status === SyrupJob::STATUS_WARNING) {
             $eData = array('jobId' => $this->job->getId(), 'orchestrationId' => $this->orchestration->getId(), 'projectId' => $this->orchestration->getProjectId());
             $e = new JobException(500, sprintf('Some of tasks failed'), null, $eData);
             $e->setStatus($status)->setResult($result);
             throw $e;
         }
         if ($status === SyrupJob::STATUS_ERROR) {
             $eData = array('jobId' => $this->job->getId(), 'orchestrationId' => $this->orchestration->getId(), 'projectId' => $this->orchestration->getProjectId());
             $e = new JobException(500, sprintf('Job failed', $job->getId()), null, $eData);
             $e->setStatus($status)->setResult($result);
             throw $e;
         }
     } catch (Exception\JobInvalidStateException $e) {
         $jobLogger->stateError($e);
         // any change of job status, job is probably processing
     } catch (Exception\JobRuntimeException $e) {
         throw $e->getPrevious();
     }
     return array();
 }
예제 #6
0
 /**
  * @return boolean
  */
 public function getActive()
 {
     return $this->task->getActive();
 }
 /**
  * @param Orchestration $entity
  * @param \Keboola\StorageApi\Client $storageApi
  * @return Orchestration
  */
 public function fillOrchestrationEntity(Orchestration $entity, Client $storageApi)
 {
     $oldTokenId = $entity->getTokenId();
     $oldName = $entity->getName();
     /** @var $entity Orchestration */
     $entity = parent::fillEntity($entity);
     $name = $entity->getName();
     if (empty($name)) {
         $entity->setName($oldName);
     }
     // token change
     if ($oldTokenId !== $entity->getTokenId()) {
         $token = $storageApi->getToken($entity->getTokenId());
         $token = new Token(new Client(array('token' => $token['token'], 'url' => $storageApi->getApiUrl())));
         $entity->setToken($token)->setTokenId($token->getId())->setTokenDesc($token->getDescription())->setTokenOwnerName($token->getOwnerName())->setProjectId($token->getProjectId());
     }
     // notifications
     $data = $this->getPostJsonData();
     if (!empty($data['notifications'])) {
         $data['notifications'] = array_map(function ($row) {
             $notification = new Notification();
             $notification->fromArray($row);
             return $notification;
         }, $data['notifications']);
         $entity->setNotifications($data['notifications']);
     }
     // tasks
     $data = $this->getPostJsonData();
     if (array_key_exists('tasks', $data)) {
         $entity->removeTasks();
         $data['tasks'] = array_map(function ($row) {
             $notification = new OrchestrationTask();
             $notification->fromArray($row);
             return $notification;
         }, $data['tasks']);
         foreach ($data['tasks'] as $task) {
             $entity->addTask($task);
         }
     }
     //@FIXME catch and throw exception
     return $entity;
 }
 /**
  * @return OrchestrationTask[]
  */
 public function getTaskList()
 {
     $return = array();
     // tasks
     $data = $this->getPostJsonData();
     if (array_key_exists('tasks', $data)) {
         $return = array_map(function ($row) {
             $notification = new OrchestrationTask();
             $notification->fromArray($row);
             return $notification;
         }, $data['tasks']);
     }
     return $return;
 }
예제 #9
0
 /**
  * @param Job $job
  * @return Phase[]
  */
 private function createPhases(Job $job)
 {
     /** @var StorageApi\OrchestrationTask[] $orchestrationTasks */
     $orchestrationTasks = array();
     if ($job->getTasks()) {
         $orchestrationTasks = array_map(function ($line) {
             $task = new StorageApi\OrchestrationTask();
             $task->fromArray(json_decode(json_encode($line), true));
             return $task;
         }, $job->getTasks());
     }
     /**
      * @var Phase[] $phases
      */
     $phases = array();
     $prevPhase = false;
     foreach ($orchestrationTasks as $orchestrationTask) {
         if ($orchestrationTask->getPhase() !== $prevPhase || $orchestrationTask->getPhase() == null) {
             $phase = new Phase($job);
             $phases[count($phases)] = $phase;
             $this->jobResult->addPhase($phase);
         }
         $taskResult = new TaskResult($orchestrationTask);
         $this->jobResult->addTaskResult($taskResult);
         $phases[count($phases) - 1]->addTaskResult($taskResult);
         $prevPhase = $orchestrationTask->getPhase();
     }
     return $phases;
 }