/**
  * Process and validate form
  *
  * @return true if form is valid
  * @throws \Symfony\Component\HttpKernel\Exception\HttpException on invalid form
  */
 public function process()
 {
     $this->form->submit($this->getPostJsonData());
     // collection errors
     foreach ($this->form->get('tasks') as $key => $child) {
         if ($child->isValid()) {
             continue;
         }
         try {
             $this->throwFirstError($child);
         } catch (HttpException $e) {
             throw new HttpException(400, sprintf("[Task %s] %s", $key, $e->getMessage()));
         }
     }
     // retry task validation
     $data = $this->getPostJsonData();
     if (array_key_exists('tasks', $data)) {
         if ($this->form->isValid()) {
             $orchestrationTasks = $this->orchestration->getTasks();
             $requestTasks = $this->getTaskList();
             if (count($requestTasks) !== count($orchestrationTasks)) {
                 $this->form->addError(new FormError('Job specification must containts all orchestrations tasks'));
             }
             foreach ($requestTasks as $key => $requestTask) {
                 if (!array_key_exists($key, $orchestrationTasks)) {
                     $this->form->addError(new FormError('Job specification must containts all orchestrations tasks'));
                     break;
                 }
                 $compareRequest = $requestTask->toCompareArray();
                 $compare = $orchestrationTasks[$key]->toCompareArray();
                 if (serialize($compareRequest) !== serialize($compare)) {
                     $message = "Job task is different from orchestration task";
                     $this->logger->notice($message, array('taskPosition' => $key, 'old' => $compare, 'new' => $compareRequest));
                     $this->form->addError(new FormError(sprintf("[Task %s] %s", $key, $message)));
                     break;
                 }
             }
         }
     }
     // other form errors
     if (!$this->form->isValid()) {
         $this->throwFirstError($this->form);
     }
     $this->success = true;
     return true;
 }
 /**
  * @param Orchestration $orchestration
  * @param Client $storageApi
  * @return bool
  * @throws StorageApi\InvalidStateException
  */
 private function validateConfiguration(Orchestration $orchestration, Client $storageApi)
 {
     $components = new Components($storageApi);
     $configuration = $components->getConfiguration(KeboolaOrchestratorBundle::SYRUP_COMPONENT_NAME, $orchestration->getId());
     // same name
     if ($configuration['name'] !== $orchestration->getName()) {
         throw new StorageApi\InvalidStateException('Orchestration names are different');
     }
     if (count($configuration['configuration']['tasks']) !== count($orchestration->getTasks())) {
         throw new StorageApi\InvalidStateException('Orchestration has same tasks count');
     }
     $configurationTasks = $configuration['configuration']['tasks'];
     foreach ($orchestration->getTasks() as $i => $task) {
         $task = $task->toApiArray();
         foreach ($task as $key => $value) {
             if ($configurationTasks[$i][$key] != $value) {
                 throw new StorageApi\InvalidStateException(sprintf('Task %s is different: %s||%s', $task['id'], json_encode($task), $configurationTasks[$i]));
             }
         }
     }
     return true;
 }