/**
  * Cancel waiting job
  *
  * @param $jobId
  * @throws \Keboola\OrchestratorBundle\Exception\OrchestratorException
  * @return Response
  */
 public function deleteAction($jobId)
 {
     $job = $this->jobEsManager->findJobById($jobId);
     if (!$job) {
         $exception = new OrchestratorException(404, sprintf('Job %s not found', $jobId));
         $exception->setExceptionCode('JOB_NOT_FOUND');
         throw $exception;
     }
     if (!$job->isWaiting()) {
         $exception = new OrchestratorException(403, 'Only waiting job can be cancelled');
         $exception->setExceptionCode('INVALID_JOB_STATUS');
         throw $exception;
     }
     $client = new GuzzleHttp\Client([]);
     try {
         $response = $client->post(sprintf($this->killUrl, $job->getId()), array('config' => array('curl' => array(CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0)), 'headers' => array('X-StorageApi-Token' => $this->token, 'X-KBC-RunId' => $this->storageApi->getRunId(), 'X-User-Agent', KeboolaOrchestratorBundle::SYRUP_COMPONENT_NAME . " - API cancel"), 'timeout' => 60));
         if ($response->getStatusCode() == 202) {
             $this->logger->info(sprintf('Orchestration job %s cancelled', $job->getId()));
             $this->logger->debug(sprintf('Orchestration job %s cancelled - old api', $job->getId()), array('orchestrationId' => $job->getOrchestrationId(), 'orchestration' => $job->getOrchestrationName(), 'projectId' => $job->getProjectId(), 'project' => $job->getTokenOwnerName(), 'tokenId' => $this->token->getId(), 'token' => $this->token->getDescription()));
         } else {
             throw new ApplicationException('Job cancel via syrup api failed', null, array('statusCode' => $response->getStatusCode(), 'body' => ResponseDecoder::decode($response)));
         }
     } catch (GuzzleHttp\Exception\RequestException $e) {
         throw new ApplicationException('Job cancel via syrup api failed', $e);
     }
     $jsonResponse = $this->createJsonResponse(array(), 204);
     return $jsonResponse;
 }
Example #2
0
 /**
  * @param Elasticsearch\Job $job
  * @param Orchestration $orchestration
  * @param Elasticsearch\JobManager $jobManager
  * @param KbcComponentsList $components
  */
 public function sendJobWarningMessage(Elasticsearch\Job $job, Orchestration $orchestration, Elasticsearch\JobManager $jobManager, KbcComponentsList $components)
 {
     /**
      * @var Notification[] $notifications
      */
     $notifications = array_filter($orchestration->getNotifications(), function ($row) {
         /**
          * @var Notification $row
          */
         if (!\Swift_Validate::email($row->getEmail())) {
             return false;
         }
         return $row->getChannel() === Job::STATUS_WARNING;
     });
     $notificationsEmails = $jobManager->getWarningNotificationsEmails($job);
     if (!$notificationsEmails) {
         $notificationsEmails = array();
     }
     // validating emails
     foreach ($notificationsEmails as $key => $notificationsEmail) {
         if (!\Swift_Validate::email($notificationsEmail)) {
             unset($notificationsEmails[$key]);
         }
     }
     if (!count($notifications) && !count($notificationsEmails)) {
         return;
     }
     $message = \Swift_Message::newInstance();
     $message->setSubject(sprintf("[KBC] %s orchestrator %s warning", $job->getTokenOwnerName(), $job->getOrchestrationName()));
     $message->setFrom(self::MAIL_SENDER);
     foreach ($notificationsEmails as $notificationsEmail) {
         $message->addTo($notificationsEmail);
     }
     foreach ($notifications as $notification) {
         if ($job->getInitializedBy() !== 'manually') {
             if (!in_array($notification->getEmail(), $notificationsEmails)) {
                 $message->addTo($notification->getEmail());
             }
         }
     }
     $schedule = null;
     try {
         $cronSchedule = CronSchedule::fromCronString($orchestration->getCrontabRecord(), 'en');
         $schedule = $cronSchedule->asNaturalLanguage();
     } catch (\Exception $e) {
     }
     $tasks = $job->getResults();
     if (empty($tasks->tasks)) {
         $tasks = array();
     } else {
         $tasks = $tasks->tasks;
     }
     $jobUrl = $components->getJobUriTemplate(KeboolaOrchestratorBundle::SYRUP_COMPONENT_NAME);
     $jobUrl = str_replace('&&projectId&&', $job->getProjectId(), $jobUrl);
     $jobUrl = str_replace('&&orchestrationId&&', $job->getOrchestrationId(), $jobUrl);
     $jobUrl = str_replace('&&jobId&&', $job->getId(), $jobUrl);
     $message->setBody($this->templating->render('KeboolaOrchestratorBundle:Email:jobWarning.email.html.twig', array('schedule' => $schedule, 'tasks' => $tasks, 'componentsIcons' => $components->getComponentsIcons(), 'componentsNames' => $components->getComponentsNames(), 'componentsTypes' => $this->filterComponentsTypes($components->getComponentsTypes()), 'job' => $job, 'jobUrl' => $jobUrl)), 'text/html');
     $this->mailer->send($message);
     /**
      * @var \Swift_Spool $spool
      */
     $spool = $this->mailer->getTransport()->getSpool();
     $spool->flushQueue($this->mailerTransport);
 }
 private function handlePostJobs($orchestrationId, Request $request, $async = false)
 {
     $orchestration = $this->dbOrchestrationManager->findOrchestrationById($orchestrationId, $this->token, true);
     if (!$orchestration) {
         $exception = new OrchestratorException(404, sprintf('Orchestration %s not found', $orchestrationId));
         $exception->setExceptionCode('ORCHESTRATION_NOT_FOUND');
         throw $exception;
     }
     // waiting jobs limit
     $jobsStats = $this->jobEsManager->getWaitingStats();
     // skip waiting
     if (array_key_exists($orchestration->getId(), $jobsStats) && $jobsStats[$orchestration->getId()] >= AppConfiguration::MAX_WAITING_JOBS_COUNT) {
         $count = $jobsStats[$orchestration->getId()];
         if ($count > 1) {
             $exception = new OrchestratorException(409, sprintf('Orchestration %s has %d waiting jobs. Current limit is %d.', $orchestrationId, $count, AppConfiguration::MAX_WAITING_JOBS_COUNT));
         } else {
             $exception = new OrchestratorException(409, sprintf('Orchestration %s has %d waiting job. Current limit is %d.', $orchestrationId, $count, AppConfiguration::MAX_WAITING_JOBS_COUNT));
         }
         $exception->setExceptionCode('ORCHESTRATION_VALIDATION');
         throw $exception;
     }
     // skip jobs depth
     $jobsDepth = $this->jobEsManager->getDepthFromRunId($this->storageApi->getRunId());
     if ($jobsDepth >= AppConfiguration::MAX_ORCHESTRATION_RUN_DEPTH) {
         $this->logger->info('scheduler.orchestration.skipped', array('depth' => $jobsDepth, 'limit' => AppConfiguration::MAX_ORCHESTRATION_RUN_DEPTH, 'orchestrationId' => $orchestration->getId(), 'orchestrationName' => $orchestration->getName(), 'projectId' => $this->token->getProjectId(), 'projectName' => $this->token->getOwnerName()));
         $exception = new OrchestratorException(409, sprintf('Orchestrations can be started only %d times for current id.', AppConfiguration::MAX_ORCHESTRATION_RUN_DEPTH));
         $exception->setExceptionCode('RUNTIME_VALIDATION');
         throw $exception;
     }
     try {
         $form = $this->createForm(new OrchestrationRunType($this->storageApi, $this->dbOrchestrationManager, $this->token, $orchestration));
         $handler = $this->createRunFormHandler($form, $request, $orchestration);
         if ($handler->process()) {
             if ($handler->getTaskList()) {
                 $tasks = array_map(function ($task) {
                     /** @var StorageApi\OrchestrationTask $task */
                     $task->setId($this->storageApi->generateId());
                     return $task->toApiArray();
                 }, $handler->getTaskList());
             } else {
                 $tasks = array_map(function ($task) {
                     /**
                      * @var StorageApi\OrchestrationTask $task
                      */
                     return $task->toApiArray();
                 }, $orchestration->getTasks());
             }
         }
     } catch (HttpException $e) {
         $exception = new OrchestratorException($e->getStatusCode(), $e->getMessage());
         $exception->setExceptionCode('JOB_VALIDATION');
         throw $exception;
     }
     $form = $this->createForm(new ScheduleJobType($this->storageApi, $this->dbOrchestrationManager, $this->token));
     $handler = parent::createFormHandler($form, $request);
     try {
         $notificationsEmails = array();
         if ($handler->process()) {
             $notificationsEmails = $handler->getPost('notificationsEmails', array());
         }
         if (!$notificationsEmails && \Swift_Validate::email($this->token->getDescription())) {
             $notificationsEmails = array($this->token->getDescription());
         }
     } catch (HttpException $e) {
         $exception = new OrchestratorException(400, $e->getMessage());
         $exception->setExceptionCode('JOB_VALIDATION');
         throw $exception;
     }
     $this->initSqsQueue();
     $job = new Elasticsearch\Job();
     $job->setOrchestrationId($orchestration->getId())->setConfig($orchestration->getId())->setOrchestrationName($orchestration->getName())->setToken($orchestration->getToken())->setTokenId($orchestration->getTokenId())->setTokenDesc($orchestration->getTokenDesc())->setTokenOwnerName($this->token->getOwnerName())->setProjectId($this->token->getProjectId())->setInitializedBy('manually')->setTaks($tasks)->setInitiatorTokenId($this->token->getId())->setInitiatorTokenDesc($this->token->getDescription())->setInitiatorUserAgent($this->getRequestUserAgent($request))->setNotificationsEmails($notificationsEmails);
     $job = $this->jobEsManager->saveJob($job, new StorageApi\UniqueManager($this->storageApi));
     $this->queue->enqueue($job->getId(), array('jobId' => $job->getId(), 'component' => KeboolaOrchestratorBundle::SYRUP_COMPONENT_NAME));
     // log event
     $this->logger->info(sprintf('Orchestration job %s created manually', $job->getId()));
     if ($async) {
         return $this->createJsonResponse($job->toApiArray(), 202);
     } else {
         $this->logger->debug(sprintf('Orchestration job %s created manually - sync', $job->getId()), array('orchestrationId' => $orchestration->getId(), 'orchestration' => $orchestration->getName(), 'projectId' => $this->token->getProjectId(), 'projectName' => $this->token->getOwnerName(), 'tokenId' => $this->token->getId(), 'token' => $this->token->getDescription()));
         return $this->createJsonResponse($job->toOldApiArray(), 201);
     }
 }
Example #4
0
 /**
  * @param JobResult $jobResult
  */
 protected function saveJobResult(JobResult $jobResult)
 {
     $this->jobEsManager->updateJobResult($this->job, $jobResult);
 }