/**
  * @param WorkflowMessage $workflowMessage
  * @return void
  */
 public function handleWorkflowMessage(WorkflowMessage $workflowMessage)
 {
     if (!MessageNameUtils::isProcessingCommand($workflowMessage->messageName())) {
         $this->workflowEngine->dispatch(LogMessage::logUnsupportedMessageReceived($workflowMessage));
     }
     try {
         if ($workflowMessage->messageType() === MessageNameUtils::COLLECT_DATA) {
             $processingMessage = $this->handleCollectData($workflowMessage);
             if (!$processingMessage instanceof ProcessingMessage) {
                 throw new \RuntimeException(sprintf("%s::handleCollectData method returned %s instead of a ProcessingMessage", get_called_class(), is_object($processingMessage) ? get_class($processingMessage) : gettype($processingMessage)));
             }
         } else {
             if ($workflowMessage->messageType() === MessageNameUtils::PROCESS_DATA) {
                 $processingMessage = $this->handleProcessData($workflowMessage);
                 if (!$processingMessage instanceof ProcessingMessage) {
                     throw new \RuntimeException(sprintf("%s::handleProcessData method returned %s instead of a ProcessingMessage", get_called_class(), is_object($processingMessage) ? get_class($processingMessage) : gettype($processingMessage)));
                 }
             } else {
                 $this->workflowEngine->dispatch(LogMessage::logUnsupportedMessageReceived($workflowMessage));
                 return;
             }
         }
         $this->workflowEngine->dispatch($processingMessage);
         return;
     } catch (\Exception $ex) {
         $this->workflowEngine->dispatch(LogMessage::logException($ex, $workflowMessage));
         return;
     }
 }
示例#2
0
 /**
  * @param WorkflowMessage $message
  * @param NodeName $nodeName
  * @throws \InvalidArgumentException If process definition for message is not defined
  * @return Process
  */
 public function deriveProcessFromMessage(WorkflowMessage $message, NodeName $nodeName)
 {
     if (isset($this->processDefinitions[$message->messageName()])) {
         return $this->createProcessFromDefinition($this->processDefinitions[$message->messageName()], $nodeName);
     }
     throw new \InvalidArgumentException(sprintf("Derive process from message failed due to unknown message: %s", $message->messageName()));
 }
示例#3
0
 /**
  * @param Task $task
  * @param WorkflowMessage $message
  * @return bool
  */
 private function isCorrectMessageFor(Task $task, WorkflowMessage $message)
 {
     if (MessageNameUtils::isProcessingCommand($message->messageName())) {
         if (!$task instanceof CollectData || $message->messageName() !== MessageNameUtils::getCollectDataCommandName($task->prototype()->of())) {
             return false;
         }
     }
     return true;
 }
 /**
  * @param WorkflowMessage $aWorkflowMessage
  * @return void
  */
 public function handleWorkflowMessage(WorkflowMessage $aWorkflowMessage)
 {
     $this->lastWorkflowMessage = $aWorkflowMessage;
     if ($this->nextAnswer && $this->workflowEngine) {
         if (is_null($this->nextAnswer->processTaskListPosition())) {
             $this->nextAnswer->connectToProcessTask($aWorkflowMessage->processTaskListPosition());
         }
         $this->workflowEngine->dispatch($this->nextAnswer);
         $this->nextAnswer = null;
     }
 }
示例#5
0
 /**
  * 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);
     }
 }
 public function create($data)
 {
     if (!array_key_exists("collect_data_trigger", $data)) {
         return new ApiProblemResponse(new ApiProblem(422, 'Root key collect_data_trigger missing in request data'));
     }
     $data = $data["collect_data_trigger"];
     if (!array_key_exists('processing_type', $data)) {
         return new ApiProblemResponse(new ApiProblem(422, 'Key processing_type is missing'));
     }
     $processingType = $data['processing_type'];
     if (!class_exists($processingType)) {
         return new ApiProblemResponse(new ApiProblem(422, 'Provided processing type is unknown'));
     }
     try {
         Assertion::implementsInterface($processingType, 'Prooph\\Processing\\Type\\Type');
     } catch (\InvalidArgumentException $ex) {
         return new ApiProblemResponse(new ApiProblem(422, 'Provided processing type is not valid'));
     }
     $wfMessage = WorkflowMessage::collectDataOf($processingType::prototype(), __CLASS__, $this->ProcessingConfig->getNodeName());
     $this->messageLogger->logIncomingMessage($wfMessage);
     $this->workflowEngine->dispatch($wfMessage);
     /** @var $response Response */
     $response = $this->getResponse();
     $response->getHeaders()->addHeaderLine('Location', $this->url()->fromRoute('prooph.link/processor_proxy/api/messages', ['id' => $wfMessage->uuid()->toString()]));
     $response->setStatusCode(201);
     return $response;
 }
示例#7
0
 /**
  * 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);
     }
 }
 /**
  * @test
  */
 public function it_injects_target_handler_to_event_dispatch_when_event_is_a_workflow_message()
 {
     $message = WorkflowMessage::newDataCollected(UserDictionary::fromNativeValue(['id' => 1, 'name' => 'John Doe', 'address' => ['street' => 'Main Street', 'streetNumber' => 10, 'zip' => '12345', 'city' => 'Test City']]), 'test-case', NodeName::defaultName());
     $eventDispatch = new EventDispatch();
     $eventDispatch->setEvent($message);
     $router = new SingleTargetMessageRouter($this->getTestWorkflowProcessor());
     $router->onRouteEvent($eventDispatch);
     $this->assertSame($this->getTestWorkflowProcessor(), $eventDispatch->getEventListeners()[0]);
 }
 /**
  * @test
  */
 public function it_handles_a_process_data_message()
 {
     $taskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 2);
     $wfMessage = WorkflowMessage::newDataCollected(UserDictionary::fromNativeValue(['id' => 1, 'name' => 'John Doe', 'address' => ['street' => 'Main Street', 'streetNumber' => 10, 'zip' => '12345', 'city' => 'Test City']]), 'test-case', NodeName::defaultName());
     $wfMessage->connectToProcessTask($taskListPosition);
     $wfMessage = $wfMessage->prepareDataProcessing($taskListPosition, 'message-handler');
     $this->workflowMessageHandler->handleWorkflowMessage($wfMessage);
     $this->assertSame($wfMessage, $this->workflowMessageHandler->lastProcessDataMessage());
     $this->assertInstanceOf('Prooph\\Processing\\Message\\LogMessage', $this->lastProcessingMessage);
 }
示例#10
0
 /**
  * @test
  */
 public function it_returns_start_sub_process_command_including_previous_message()
 {
     $subProcessDefinition = ["process_type" => Definition::PROCESS_LINEAR_MESSAGING, "tasks" => [["task_type" => Definition::TASK_COLLECT_DATA, "source" => 'test-case', "processing_type" => 'Prooph\\ProcessingTest\\Mock\\UserDictionary']]];
     $task = RunSubProcess::setUp(NodeName::defaultName(), $subProcessDefinition);
     $parentTaskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1);
     $previousMessage = WorkflowMessage::newDataCollected(UserDictionary::fromNativeValue(['id' => 1, 'name' => 'John Doe', 'address' => ['street' => 'Main Street', 'streetNumber' => 10, 'zip' => '12345', 'city' => 'Test City']]), 'test-case', NodeName::defaultName());
     $startSubProcess = $task->generateStartCommandForSubProcess($parentTaskListPosition, $previousMessage);
     $this->assertTrue($parentTaskListPosition->equals($startSubProcess->parentTaskListPosition()));
     $this->assertEquals($subProcessDefinition, $startSubProcess->subProcessDefinition());
     $this->assertEquals($previousMessage->messageName(), $startSubProcess->previousWorkflowMessage()->messageName());
 }
 /**
  * @test
  */
 public function it_invokes_processing_event_on_workflow_message_handler()
 {
     $userData = array('id' => 1, 'name' => 'Alex', 'address' => array('street' => 'Main Street', 'streetNumber' => 10, 'zip' => '12345', 'city' => 'Test City'));
     $user = UserDictionary::fromNativeValue($userData);
     $wfEvent = WorkflowMessage::newDataCollected($user, 'test-case', NodeName::defaultName());
     $eventBus = new EventBus();
     $eventRouter = new EventRouter();
     $eventRouter->route($wfEvent->messageName())->to($this->workflowMessageHandler);
     $eventBus->utilize($eventRouter);
     $eventBus->utilize(new HandleWorkflowMessageInvokeStrategy());
     $eventBus->dispatch($wfEvent);
     $this->assertSame($wfEvent, $this->workflowMessageHandler->lastWorkflowMessage());
 }
示例#12
0
 /**
  * @test
  */
 public function it_collects_information_for_the_sub_process()
 {
     $subProcessDefinition = ["process_type" => Definition::PROCESS_LINEAR_MESSAGING, "tasks" => [["task_type" => Definition::TASK_COLLECT_DATA, "source" => 'test-case', "processing_type" => 'Prooph\\ProcessingTest\\Mock\\UserDictionary']]];
     $previousMessage = WorkflowMessage::newDataCollected(UserDictionary::fromNativeValue(['id' => 1, 'name' => 'John Doe', 'address' => ['street' => 'Main Street', 'streetNumber' => 10, 'zip' => '12345', 'city' => 'Test City']]), 'test-case', 'processor');
     $parentTaskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1);
     $command = StartSubProcess::at($parentTaskListPosition, $subProcessDefinition, true, 'sub-processor', $previousMessage);
     $this->assertTrue($parentTaskListPosition->equals($command->parentTaskListPosition()));
     $this->assertTrue($command->syncLogMessages());
     $this->assertEquals($subProcessDefinition, $command->subProcessDefinition());
     $this->assertEquals($previousMessage->messageName(), $command->previousWorkflowMessage()->messageName());
     $this->assertEquals(NodeName::defaultName()->toString(), $command->origin());
     $this->assertEquals('sub-processor', $command->target());
 }
示例#13
0
 /**
  * @test
  * @dataProvider provideStringCollection
  */
 public function it_performs_a_sub_process_for_each_chunk_of_a_collection(StringCollection $stringCollection)
 {
     $processDefinition = ['process_type' => Definition::PROCESS_PARALLEL_CHUNK, 'tasks' => [["task_type" => Definition::TASK_RUN_SUB_PROCESS, "target_node_name" => NodeName::defaultName()->toString(), "process_definition" => ["process_type" => Definition::PROCESS_LINEAR_MESSAGING, "tasks" => [["task_type" => Definition::TASK_PROCESS_DATA, "target" => 'test-target', "allowed_types" => ['Prooph\\Processing\\Type\\String']]]]]]];
     $processFactory = new ProcessFactory();
     $chunkProcess = $processFactory->createProcessFromDefinition($processDefinition, NodeName::defaultName());
     $this->assertInstanceOf('Prooph\\Processing\\Processor\\ChunkProcess', $chunkProcess);
     $message = WorkflowMessage::newDataCollected($stringCollection, 'test-case', NodeName::defaultName(), [ChunkProcess::META_OFFSET => 0, ChunkProcess::META_LIMIT => 2, ChunkProcess::META_TOTAL_ITEMS => 6, ChunkProcess::META_COUNT_ONLY => true]);
     $chunkProcess->perform($this->workflowEngine, $message);
     $this->assertEquals(3, count($this->startSubProcessCommands));
     $this->assertFalse($chunkProcess->isFinished());
     foreach ($this->startSubProcessCommands as $i => $command) {
         $mockedMessage = WorkflowMessage::newDataCollected(String::fromNativeValue("Fake message"), 'test-case', NodeName::defaultName());
         $mockedMessage->connectToProcessTask($command->parentTaskListPosition());
         $chunkProcess->receiveMessage($mockedMessage, $this->workflowEngine);
     }
     $this->assertTrue($chunkProcess->isSuccessfulDone());
 }
 /**
  * @param RemoteMessage $message
  * @return LogMessage|WorkflowMessage|StartSubProcess|SubProcessFinished
  * @throws \InvalidArgumentException
  */
 public function translateToProcessingMessage(RemoteMessage $message)
 {
     if (MessageNameUtils::isWorkflowMessage($message->name())) {
         return WorkflowMessage::fromServiceBusMessage($message);
     } else {
         if (MessageNameUtils::isProcessingLogMessage($message->name())) {
             return LogMessage::fromServiceBusMessage($message);
         } else {
             if (StartSubProcess::MSG_NAME === $message->name()) {
                 return StartSubProcess::fromServiceBusMessage($message);
             } else {
                 if (SubProcessFinished::MSG_NAME === $message->name()) {
                     return SubProcessFinished::fromServiceBusMessage($message);
                 }
             }
         }
     }
     throw new \InvalidArgumentException(sprintf('Message with name %s can not be translated. Unknown type provided.', $message->name()));
 }
示例#15
0
 public function __invoke(Route $route, AdapterInterface $console)
 {
     $consoleWriter = new ConsoleWriter($console);
     $consoleWriter->deriveVerbosityLevelFrom($route);
     $processingType = $route->getMatchedParam('type');
     if (!class_exists($processingType)) {
         $consoleWriter->writeError(sprintf('Class %s not found', $processingType));
         exit(self::INVALID_PROCESSING_TYPE);
     }
     try {
         $env = $this->loadEnvironment($route, $consoleWriter);
         $message = WorkflowMessage::collectDataOf($processingType::prototype(), __CLASS__, $env->getNodeName());
         $consoleWriter->writeInfo('Start workflow with message: ' . $message->messageName());
         $env->getWorkflowProcessor()->receiveMessage($message);
         $consoleWriter->writeSuccess('Message successfully processed');
         return 0;
     } catch (\Exception $ex) {
         $consoleWriter->writeException($ex);
         return self::MESSAGE_PROCESSING_FAILED;
     }
 }
示例#16
0
 /**
  * @return WorkflowMessage
  */
 protected function getUserDataCollectedTestMessage()
 {
     $userData = array('id' => 1, 'name' => 'Alex', 'address' => array('street' => 'Main Street', 'streetNumber' => 10, 'zip' => '12345', 'city' => 'Test City'));
     $user = UserDictionary::fromNativeValue($userData);
     return WorkflowMessage::newDataCollected($user, 'test-case', NodeName::defaultName()->toString());
 }
示例#17
0
 /**
  * @test
  */
 public function it_sets_wf_message_target_to_target_defined_in_the_process_task()
 {
     $task = ProcessData::address('test-target', ['Prooph\\ProcessingTest\\Mock\\TargetUserDictionary']);
     $process = LinearProcess::setUp(NodeName::defaultName(), [$task]);
     $wfm = WorkflowMessage::collectDataOf(UserDictionary::prototype(), 'test-case', NodeName::defaultName());
     $answer = $wfm->answerWith(UserDictionary::fromNativeValue(['id' => 1, 'name' => 'John Doe', 'address' => ['street' => 'Main Street', 'streetNumber' => 10, 'zip' => '12345', 'city' => 'Test City']]));
     $this->commandRouter->route(MessageNameUtils::getProcessDataCommandName('Prooph\\ProcessingTest\\Mock\\TargetUserDictionary'))->to($this->workflowMessageHandler);
     $process->perform($this->workflowEngine, $answer);
     $receivedMessage = $this->workflowMessageHandler->lastWorkflowMessage();
     $this->assertEquals('test-target', $receivedMessage->target());
 }
示例#18
0
 /**
  * @test
  */
 function it_creates_linear_messaging_process_with_manipulate_payload_task_from_definition()
 {
     $definition = ["process_type" => Definition::PROCESS_LINEAR_MESSAGING, "tasks" => [["task_type" => Definition::TASK_MANIPULATE_PAYLOAD, 'manipulation_script' => __DIR__ . '/../Mock/manipulation/append_world.php']]];
     $processFactory = new ProcessFactory();
     $process = $processFactory->createProcessFromDefinition($definition, NodeName::defaultName());
     $this->assertInstanceOf('Prooph\\Processing\\Processor\\LinearProcess', $process);
     $message = WorkflowMessage::newDataCollected(String::fromString('Hello'), 'test-case', NodeName::defaultName());
     $process->perform($this->workflowEngine, $message);
     $this->assertTrue($process->isSuccessfulDone());
     $this->assertEquals('Hello World', $message->payload()->extractTypeData());
 }
 /**
  * @test
  */
 public function it_dispatches_a_service_bus_message()
 {
     $wfMessage = WorkflowMessage::collectDataOf(UserDictionary::prototype(), 'test-case', 'test-target', []);
     $sbMessage = $wfMessage->toServiceBusMessage();
     $this->workflowEngine->dispatch($sbMessage);
     $this->assertInstanceOf(get_class($wfMessage), $this->receivedMessage);
 }
示例#20
0
        $dataAsJsonString = json_encode($message->payload());
        $answer = $message->answerWithDataProcessingCompleted();
        try {
            \Zend\Stdlib\ErrorHandler::start();
            if (!file_put_contents('data/target-data.txt', $dataAsJsonString)) {
                \Zend\Stdlib\ErrorHandler::stop(true);
            }
        } catch (\Exception $ex) {
            $answer = \Prooph\Processing\Message\LogMessage::logException($ex, $message);
        }
        $eventBus->dispatch($answer);
    });
    $commandBus->utilize($commandRouter);
    $commandBus->utilize(new \Prooph\ServiceBus\InvokeStrategy\CallbackStrategy());
    $workflowEngine = new \Prooph\Processing\Processor\RegistryWorkflowEngine();
    $workflowEngine->registerCommandBus($commandBus, ['target-file-writer']);
    $workflowEngine->registerEventBus($eventBus, [\Prooph\Processing\Processor\Definition::SERVICE_WORKFLOW_PROCESSOR]);
    return $workflowEngine;
}
//Let's start the example
$workflowProcessor = set_up_workflow_environment();
//Step 1: Read source data
$userData = (include 'data/user-source-data.php');
//Step 2: Use implementation of Prooph\Processing\Type\Type to validate source data
$user = \Prooph\ProcessingExample\Type\SourceUser::fromNativeValue($userData);
//Step 3: Prepare WorkflowMessage
$userDataCollected = \Prooph\Processing\Message\WorkflowMessage::newDataCollected($user, 'example-script', \Prooph\Processing\Processor\NodeName::defaultName());
//Step 4: Start processing by sending a "data-collected" event to the WorkflowProcessor (simplified step without using an EventBus)
$workflowProcessor->receiveMessage($userDataCollected);
//Done: Check examples/data/target-data.txt. You should see the json representation of user data. If not please check
//output of your console window. The script prints the log of the process on the screen
 /**
  * @test
  */
 function it_does_not_perform_the_delete_query_when_no_listener_adds_a_condition()
 {
     $taskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1);
     $metadata = [DoctrineTableGateway::META_TRY_UPDATE => true];
     $users = TestUserCollection::fromNativeValue([['id' => null, 'name' => 'John Doe', 'age' => 29], ['id' => null, 'name' => 'Maxi Mustermann', 'age' => 41]]);
     $message = WorkflowMessage::newDataCollected($users, 'test-case', 'localhost');
     $message->connectToProcessTask($taskListPosition);
     $message = $message->prepareDataProcessing($taskListPosition, 'localhost', $metadata);
     $this->tableGateway->handleWorkflowMessage($message);
     $this->assertInstanceOf('Prooph\\Processing\\Message\\WorkflowMessage', $this->messageReceiver->getLastReceivedMessage());
     /** @var $message WorkflowMessage */
     $message = $this->messageReceiver->getLastReceivedMessage();
     $metadata = $message->metadata();
     $this->assertTrue(isset($metadata[MessageMetadata::SUCCESSFUL_ITEMS]));
     $this->assertEquals(2, $metadata[MessageMetadata::SUCCESSFUL_ITEMS]);
     $this->assertTrue(isset($metadata[MessageMetadata::FAILED_ITEMS]));
     $this->assertEquals(0, $metadata[MessageMetadata::FAILED_ITEMS]);
     $this->assertTrue(isset($metadata[MessageMetadata::FAILED_MESSAGES]));
     $this->assertEmpty($metadata[MessageMetadata::FAILED_MESSAGES]);
     $query = $this->getDbalConnection()->createQueryBuilder();
     $userResultSet = $query->select('*')->from(self::TEST_TABLE)->execute()->fetchAll();
     $this->assertEquals(5, count($userResultSet));
     $expectedUsers = [['id' => '1', 'name' => 'John Doe', 'age' => '34'], ['id' => '2', 'name' => 'Max Mustermann', 'age' => '41'], ['id' => '3', 'name' => 'Donald Duck', 'age' => '57'], ['id' => '4', 'name' => 'John Doe', 'age' => '29'], ['id' => '5', 'name' => 'Maxi Mustermann', 'age' => '41']];
     $this->assertEquals($expectedUsers, $userResultSet);
 }
 /**
  * @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();
     }
 }
 /**
  * @return array
  */
 public function provideEntries()
 {
     $wfStartMessage = WorkflowMessage::collectDataOf(TestUser::prototype(), 'test-case', 'localhost');
     $startMessageLogEntry = MessageLogEntry::logMessage($wfStartMessage);
     $startMessageLogEntryWithAssignedProcessId = MessageLogEntry::logMessage($wfStartMessage);
     $startMessageLogEntryWithAssignedProcessId->assignIdOfStartedProcess(ProcessId::generate());
     $startMessageLogEntryWithAssignedProcessIdSucceed = MessageLogEntry::logMessage($wfStartMessage);
     $startMessageLogEntryWithAssignedProcessIdSucceed->assignIdOfStartedProcess(ProcessId::generate());
     $startMessageLogEntryWithAssignedProcessIdFailed = MessageLogEntry::logMessage($wfStartMessage);
     $startMessageLogEntryWithAssignedProcessIdFailed->markAsFailed("Starting process failed");
     $wfMessage = WorkflowMessage::collectDataOf(TestUser::prototype(), 'test-case', 'localhost');
     $taskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1);
     $wfMessage->connectToProcessTask($taskListPosition);
     $normalMessageLogEntryPending = MessageLogEntry::logMessage($wfMessage);
     $normalMessageLogEntrySucceed = MessageLogEntry::logMessage($wfMessage);
     $normalMessageLogEntrySucceed->markAsSucceed();
     $normalMessageLogEntryFailed = MessageLogEntry::logMessage($wfMessage);
     $normalMessageLogEntryFailed->markAsFailed("Processing failed");
     return [[$startMessageLogEntry], [$startMessageLogEntryWithAssignedProcessId], [$startMessageLogEntryWithAssignedProcessIdSucceed], [$startMessageLogEntryWithAssignedProcessIdFailed], [$normalMessageLogEntryPending], [$normalMessageLogEntrySucceed], [$normalMessageLogEntryFailed]];
 }
示例#24
0
 /**
  * @param TaskListPosition $taskListPosition
  * @param WorkflowMessage|LogMessage $lastAnswer
  * @throws \RuntimeException If process cannot be found
  * @throws \Exception If error occurs during processing
  */
 private function continueProcessAt(TaskListPosition $taskListPosition, $lastAnswer)
 {
     $process = $this->processRepository->get($taskListPosition->taskListId()->processId());
     if (is_null($process)) {
         throw new \RuntimeException(sprintf("Last received message %s (%s) contains unknown processId. A process with id %s cannot be found!", $lastAnswer->getMessageName(), $lastAnswer->uuid()->toString(), $taskListPosition->taskListId()->processId()->toString()));
     }
     $this->beginTransaction();
     try {
         $process->receiveMessage($lastAnswer, $this->workflowEngine);
         $this->commitTransaction();
     } catch (\Exception $ex) {
         $this->rollbackTransaction();
         throw $ex;
     }
     if ($process->isFinished()) {
         $this->processorEventQueue->enqueue($this->events()->getNewActionEvent('process_did_finish', $this, ['process_id' => $process->processId()->toString(), 'finished_at' => $lastAnswer->createdAt()->format(\DateTime::ISO8601), 'succeed' => $process->isSuccessfulDone()]));
     }
     if ($process->isSubProcess() && $process->isFinished()) {
         if ($process->isSuccessfulDone()) {
             $this->informParentProcessAboutSubProcess($process, true, $lastAnswer);
         } else {
             if (!$lastAnswer instanceof LogMessage) {
                 $lastAnswer = LogMessage::logException(new \RuntimeException("Sub process failed but last message was not a LogMessage"), $process->parentTaskListPosition());
             }
             if (!$lastAnswer->isError()) {
                 $lastAnswer = LogMessage::logErrorMsg($lastAnswer->technicalMsg(), $lastAnswer);
             }
             $this->informParentProcessAboutSubProcess($process, false, $lastAnswer);
         }
     }
 }
 /**
  * @test
  */
 public function it_writes_each_string_of_the_collection_to_a_separate_file_and_the_value_is_available_in_the_filename_template_to_create_unique_file_names()
 {
     $taskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1);
     $strings = StringCollection::fromNativeValue(["first", "second", "third"]);
     $metadata = [FileGateway::META_FILE_TYPE => 'json', FileGateway::META_PATH => $this->tempPath, FileGateway::META_FILENAME_TEMPLATE => 'string-{{value}}.json', FileGateway::META_WRITE_MULTI_FILES => true];
     $this->tempFiles[] = 'string-first.json';
     $this->tempFiles[] = 'string-second.json';
     $this->tempFiles[] = 'string-third.json';
     $workflowMessage = WorkflowMessage::newDataCollected($strings, NodeName::defaultName()->toString(), 'file-connector');
     $workflowMessage->connectToProcessTask($taskListPosition);
     $workflowMessage = $workflowMessage->prepareDataProcessing($taskListPosition, NodeName::defaultName()->toString(), $metadata);
     $this->fileGateway->handleWorkflowMessage($workflowMessage);
     $this->assertInstanceOf('Prooph\\Processing\\Message\\WorkflowMessage', $this->messageReceiver->getLastReceivedMessage());
     $this->assertTrue(file_exists($this->tempPath . $this->tempFiles[0]));
     $this->assertTrue(file_exists($this->tempPath . $this->tempFiles[1]));
     $this->assertTrue(file_exists($this->tempPath . $this->tempFiles[2]));
     $second = json_decode(file_get_contents($this->tempPath . $this->tempFiles[1]));
     $this->assertEquals('second', $second);
 }
示例#26
0
 /**
  * @param ManipulatePayload $task
  * @param TaskListPosition $taskListPosition
  * @param WorkflowEngine $workflowEngine
  * @param WorkflowMessage $previousMessage
  */
 protected function performManipulatePayload(ManipulatePayload $task, TaskListPosition $taskListPosition, WorkflowEngine $workflowEngine, WorkflowMessage $previousMessage)
 {
     if (!MessageNameUtils::isProcessingEvent($previousMessage->messageName())) {
         $this->receiveMessage(LogMessage::logWrongMessageReceivedFor($task, $taskListPosition, $previousMessage), $workflowEngine);
         return;
     }
     $payload = $previousMessage->payload();
     try {
         $task->performManipulationOn($payload);
     } catch (\Exception $ex) {
         $this->receiveMessage(LogMessage::logException($ex, $taskListPosition), $workflowEngine);
         return;
     }
     $newEvent = $previousMessage->prepareDataProcessing($taskListPosition, $this->taskList->taskListId()->nodeName())->answerWithDataProcessingCompleted();
     $this->receiveMessage($newEvent, $workflowEngine);
 }
示例#27
0
 /**
  * @return WorkflowMessage
  */
 private function getTestWorkflowMessage()
 {
     $taskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1);
     $wfMessage = WorkflowMessage::collectDataOf(UserDictionary::prototype(), 'test-case', 'message-handler');
     $wfMessage->connectToProcessTask($taskListPosition);
     return $wfMessage;
 }
示例#28
0
 /**
  * @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 $message
  * @return MessageLogEntry
  */
 public static function logWorkflowMessage(WorkflowMessage $message)
 {
     return self::createFromMessageProps($message->uuid(), $message->messageName(), $message->version(), $message->processTaskListPosition());
 }
示例#30
0
 /**
  * @param CollectionType $collection
  * @param WorkflowEngine $workflowEngine
  */
 private function startSubProcessForEachItem(CollectionType $collection, WorkflowEngine $workflowEngine)
 {
     $taskListEntry = $this->taskList->getNextNotStartedTaskListEntry();
     $this->recordThat(TaskEntryMarkedAsRunning::at($taskListEntry->taskListPosition()));
     $this->processingCollection = true;
     /** @var $task RunSubProcess */
     $task = $taskListEntry->task();
     foreach ($collection as $item) {
         $message = WorkflowMessage::newDataCollected($item, $this->taskList->taskListId()->nodeName(), $task->targetNodeName());
         $message->connectToProcessTask($taskListEntry->taskListPosition());
         $this->recordThat(MultiPerformTaskWasStarted::at($taskListEntry->taskListPosition()));
         $this->performRunSubProcess($task, $taskListEntry->taskListPosition(), $workflowEngine, $message);
     }
     $this->processingCollection = false;
 }