/** * If workflow message handler receives a process-data message it forwards the message to this * method and uses the returned ProcessingMessage as response * * @param WorkflowMessage $workflowMessage * @return ProcessingMessage */ protected function handleProcessData(WorkflowMessage $workflowMessage) { if (array_key_exists($workflowMessage->payload()->getTypeClass(), $this->getSupportedMessagesByTypeMap())) { $dataAsJsonString = json_encode($workflowMessage->payload()); $answer = $workflowMessage->answerWithDataProcessingCompleted(); try { \Zend\Stdlib\ErrorHandler::start(); if (!file_put_contents(__DIR__ . '/../../data/target-data.txt', $dataAsJsonString)) { \Zend\Stdlib\ErrorHandler::stop(true); } } catch (\Exception $ex) { $answer = \Prooph\Processing\Message\LogMessage::logException($ex, $workflowMessage); } return $answer; } else { return LogMessage::logErrorMsg(sprintf('%s: Unknown type %s received', __CLASS__, $workflowMessage->payload()->getTypeClass()), $workflowMessage); } }
/** * If workflow message handler receives a collect-data message it forwards the message to this * method and uses the returned ProcessingMessage as response * * @param WorkflowMessage $workflowMessage * @return ProcessingMessage */ protected function handleCollectData(WorkflowMessage $workflowMessage) { if ($workflowMessage->payload()->getTypeClass() === 'Prooph\\ProcessingExample\\Type\\SourceUser') { $userData = (include __DIR__ . '/../../data/user-source-data.php'); if (!$userData) { return LogMessage::logErrorMsg("Could not read user data from examples/data/user-source-data.php. Please check the permissions", $workflowMessage); } $sourceUser = SourceUser::fromNativeValue($userData); return $workflowMessage->answerWith($sourceUser); } else { return LogMessage::logErrorMsg(sprintf('%s: Unknown type %s received', __CLASS__, $workflowMessage->payload()->getTypeClass()), $workflowMessage); } }
/** * @param WorkflowMessage $message * @param bool $forceInsert * @return LogMessage|WorkflowMessage */ private function updateOrInsertPayload(WorkflowMessage $message, $forceInsert = false) { $processingType = $message->payload()->getTypeClass(); /** @var $desc Description */ $desc = $processingType::buildDescription(); $successful = 0; $failed = 0; $failedMessages = []; if ($desc->nativeType() == NativeType::COLLECTION) { /** @var $prototype Prototype */ $prototype = $processingType::prototype(); $itemProto = $prototype->typeProperties()['item']->typePrototype(); $typeObj = $message->payload()->toType(); if ($typeObj) { $this->connection->beginTransaction(); $insertStmt = null; /** @var $tableRow TableRow */ foreach ($typeObj as $i => $tableRow) { if (!$tableRow instanceof TableRow) { return LogMessage::logUnsupportedMessageReceived($message); } try { $insertStmt = $this->updateOrInsertTableRow($tableRow, $forceInsert, $insertStmt); $successful++; } catch (\Exception $e) { $datasetIndex = $tableRow->description()->hasIdentifier() ? $tableRow->description()->identifierName() . " = " . $tableRow->property($tableRow->description()->identifierName())->value() : $i; $failed++; $failedMessages[] = sprintf('Dataset %s: %s', $datasetIndex, $e->getMessage()); } } $this->connection->commit(); } $report = [MessageMetadata::SUCCESSFUL_ITEMS => $successful, MessageMetadata::FAILED_ITEMS => $failed, MessageMetadata::FAILED_MESSAGES => $failedMessages]; if ($failed > 0) { return LogMessage::logItemsProcessingFailed($successful, $failed, $failedMessages, $message); } else { return $message->answerWithDataProcessingCompleted($report); } } else { $tableRow = $message->payload()->toType(); if (!$tableRow instanceof TableRow) { return LogMessage::logUnsupportedMessageReceived($message); } $this->updateOrInsertTableRow($tableRow, $forceInsert); return $message->answerWithDataProcessingCompleted(); } }
/** * @param WorkflowMessage $workflowMessage * @throws \InvalidArgumentException */ private function processData(WorkflowMessage $workflowMessage) { $metadata = $workflowMessage->metadata(); if (isset($metadata[self::META_LOCATION]) && !isset($metadata[self::META_PATH])) { $metadata[self::META_PATH] = $this->locationTranslator->getPathFor($metadata[self::META_LOCATION]); } if (!isset($metadata[self::META_FILENAME_TEMPLATE])) { throw new \InvalidArgumentException("Missing filename_pattern in metadata"); } if (!isset($metadata[self::META_FILE_TYPE])) { throw new \InvalidArgumentException("Missing file_type in metadata"); } if (!isset($metadata[self::META_PATH])) { throw new \InvalidArgumentException("Missing path in metadata"); } $metadata[self::META_PATH] = $this->sanitizePath($metadata[self::META_PATH]); if (!is_dir($metadata[self::META_PATH])) { throw new \InvalidArgumentException(sprintf('Directory %s is invalid', $metadata[self::META_PATH])); } if (!is_writable($metadata[self::META_PATH])) { throw new \InvalidArgumentException(sprintf('Directory %s is not writable', $metadata[self::META_PATH])); } $type = $workflowMessage->payload()->toType(); $fileTypeAdapter = $this->fileTypeAdapters->get($metadata[self::META_FILE_TYPE]); if ($type->description()->nativeType() === NativeType::COLLECTION && isset($metadata[self::META_WRITE_MULTI_FILES]) && $metadata[self::META_WRITE_MULTI_FILES]) { foreach ($type as $index => $item) { $this->writeTypeToFile($item, $metadata, $fileTypeAdapter, $index); } } else { $this->writeTypeToFile($type, $metadata, $fileTypeAdapter); } return $workflowMessage->answerWithDataProcessingCompleted($metadata); }
/** * @param WorkflowMessage $workflowMessage * @param WorkflowEngine $workflowEngine */ private function startSubProcessForEachChunk(WorkflowMessage $workflowMessage, WorkflowEngine $workflowEngine) { $taskListEntry = $this->taskList->getNextNotStartedTaskListEntry(); $this->recordThat(TaskEntryMarkedAsRunning::at($taskListEntry->taskListPosition())); $this->processingCollection = true; /** @var $task RunSubProcess */ $task = $taskListEntry->task(); $metadata = $workflowMessage->metadata(); $currentOffset = 0; $currentLimit = (int) $metadata[self::META_LIMIT]; $totalItems = (int) $metadata[self::META_TOTAL_ITEMS]; //May start message was performed as a count only message so we unset this instruction to tell //the workflow message handler that it should collect the data now. unset($metadata[self::META_COUNT_ONLY]); do { $typeClass = $workflowMessage->payload()->getTypeClass(); $metadata[self::META_OFFSET] = $currentOffset; $metadata[self::META_LIMIT] = $currentLimit; $collectChunk = WorkflowMessage::collectDataOf($typeClass::prototype(), $this->taskList->taskListId()->nodeName(), $task->targetNodeName(), $metadata); $collectChunk->connectToProcessTask($taskListEntry->taskListPosition()); $this->recordThat(MultiPerformTaskWasStarted::at($taskListEntry->taskListPosition())); $this->performRunSubProcess($task, $taskListEntry->taskListPosition(), $workflowEngine, $collectChunk); $currentOffset = $currentOffset + $currentLimit; } while ($currentOffset + $currentLimit <= $totalItems); $this->processingCollection = false; }