/** * @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); }
/** * @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()); }
/** * @test */ public function it_translates_to_service_bus_message_and_back() { $subProcessDefinition = ["process_type" => Definition::PROCESS_LINEAR_MESSAGING, "tasks" => [["task_type" => Definition::TASK_COLLECT_DATA, "source" => 'test-case', "processing_type" => 'Prooph\\ProcessingTest\\Mock\\UserDictionary']]]; $parentTaskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1); $command = StartSubProcess::at($parentTaskListPosition, $subProcessDefinition, false, 'sub-processor'); $sbMessage = $command->toServiceBusMessage(); $this->assertInstanceOf('Prooph\\Common\\Messaging\\RemoteMessage', $sbMessage); $copyOfCommand = StartSubProcess::fromServiceBusMessage($sbMessage); $this->assertInstanceOf('Prooph\\Processing\\Processor\\Command\\StartSubProcess', $copyOfCommand); $this->assertTrue($parentTaskListPosition->equals($copyOfCommand->parentTaskListPosition())); $this->assertEquals($subProcessDefinition, $copyOfCommand->subProcessDefinition()); $this->assertFalse($copyOfCommand->syncLogMessages()); $this->assertEquals(NodeName::defaultName()->toString(), $copyOfCommand->origin()); $this->assertEquals('sub-processor', $copyOfCommand->target()); }
/** * This function returns a ready to use Prooph\Processing\Processor\WorkflowProcessor * * A workflow in processing is the definition of a process. Each Process contains * a task list. And each task on the list describes a single action that should be done. * The workflow processor manages running processes and logs their progress and status. * Processing makes use of a technique performed event sourcing. The model is based on events * which are persisted in a stream and used to reconstitute the model for further processing. * * @return \Prooph\Processing\Processor\WorkflowProcessor */ function set_up_workflow_environment() { //A process definition is a configuration based on a php array //We define a linear messaging process here ... $processDefinition = ["process_type" => \Prooph\Processing\Processor\Definition::PROCESS_LINEAR_MESSAGING, "tasks" => [["task_type" => \Prooph\Processing\Processor\Definition::TASK_PROCESS_DATA, "target" => "target-file-writer", "allowed_types" => ['Prooph\\ProcessingExample\\Type\\SourceUser']]]]; //... and map it to the name of the initial workflow message which will trigger the process //The process factory is capable of parsing a process definition and build a process object from it //which can be processed by a workflow processor $processFactory = new \Prooph\Processing\Processor\ProcessFactory([\Prooph\Processing\Message\MessageNameUtils::getDataCollectedEventName('Prooph\\ProcessingExample\\Type\\SourceUser') => $processDefinition]); //Here we set up the processor dependencies. Don't worry! //When you set up your own workflow system Prooph\Processing\Environment will //do the heavy lifting for you. We don't use it here cause you should //get an idea of the internal structure. //It's always a good thing to know the internals of a system not only the public API. //See comments in the set up functions to get more information about the individual components $eventStore = _set_up_event_store(); $workflowEngine = _set_up_workflow_engine(); $processRepository = new \Prooph\Processing\Processor\ProcessRepository($eventStore); //We need to create an empty stream for our process events. //The example uses in memory persistence //so we need to create the stream each time the script is running. //A production system should have a set up script and make use of a persistent adapter //available for ProophEventStore $eventStore->beginTransaction(); $eventStore->create(new \Prooph\EventStore\Stream\Stream(new \Prooph\EventStore\Stream\StreamName('prooph_processing_stream'), [])); $eventStore->commit(); /** * Summary of what we've learned: * The WorkflowProcessor is a so performed process manager. It triggers and receives messages with the help of * a WorkflowEngine, starts and updates processes and manages the persistence of recorded process events with the * help of an EventStore and a ProcessRepository. * New processes are derived from a ProcessFactory which is capable of parsing process definitions and set up * processes with a TaskList. * The node name provided as first argument identifies the system which runs the processor. For local processing * it is enough to use the default node name defined in the definition class but when working with * many processing nodes you should give each node a unique name and configure the workflow engine to * provide the correct bus for each node. */ $workflowProcessor = new \Prooph\Processing\Processor\WorkflowProcessor(\Prooph\Processing\Processor\NodeName::defaultName(), $eventStore, $processRepository, $workflowEngine, $processFactory); $eventBus = $workflowEngine->getEventChannelFor(\Prooph\Processing\Processor\Definition::SERVICE_WORKFLOW_PROCESSOR); //Processing provides a special ProophServiceBus plugin that can route all incoming messages to a single target //in this case we want to route every message to the workflow processor //Prooph\Processing\Environment attaches such a router to each service bus $eventBus->utilize(new \Prooph\Processing\Processor\ProophPlugin\SingleTargetMessageRouter($workflowProcessor)); //Prooph\Processing also provides a special invoke strategy for the workflow processor $eventBus->utilize(new \Prooph\Processing\Processor\ProophPlugin\WorkflowProcessorInvokeStrategy()); return $workflowProcessor; }
/** * @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()); }
/** * @test */ public function it_translates_to_service_bus_message_and_back() { $nodeName = NodeName::fromString('other_machine'); $subProcessId = ProcessId::generate(); $parentTaskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1); $wfMessage = $this->getUserDataCollectedTestMessage(); $wfMessage->connectToProcessTask(TaskListPosition::at(TaskListId::linkWith($nodeName, $subProcessId), 1)); $message = LogMessage::logDebugMsg("Processing finished", $wfMessage); $event = SubProcessFinished::record($nodeName, $subProcessId, true, $message, $parentTaskListPosition); $sbMessage = $event->toServiceBusMessage(); $this->assertInstanceOf('Prooph\\Common\\Messaging\\RemoteMessage', $sbMessage); $copyOfEvent = SubProcessFinished::fromServiceBusMessage($sbMessage); $this->assertInstanceOf('Prooph\\Processing\\Processor\\Event\\SubProcessFinished', $copyOfEvent); $this->assertTrue($nodeName->equals($copyOfEvent->processorNodeName())); $this->assertTrue($parentTaskListPosition->equals($copyOfEvent->parentTaskListPosition())); $this->assertEquals($parentTaskListPosition->taskListId()->nodeName()->toString(), $copyOfEvent->target()); $this->assertTrue($subProcessId->equals($copyOfEvent->subProcessId())); $this->assertTrue($copyOfEvent->succeed()); $this->assertEquals($message->technicalMsg(), $copyOfEvent->lastMessage()->technicalMsg()); }
/** * @test * @dataProvider provideStartScenarios */ function it_determines_one_start_task_managed_by_one_process_as_long_as_message_handler_is_located_on_the_same_processing_node(Workflow\Message $startMessage, MessageHandler $firstMessageHandler, ProcessingMetadata $taskMetadata, $expectedTaskType, $expectedProcessType) { $workflow = Workflow::locatedOn(NodeName::defaultName(), WorkflowId::generate(), 'Article Export'); //Pop the WorkflowWasCreatedEvent $this->extractRecordedEvents($workflow); $tasks = $workflow->determineFirstTasks($startMessage, $firstMessageHandler, $taskMetadata); $this->assertEquals(1, count($tasks)); $this->assertInstanceOf(Task::class, $tasks[0]); $this->assertEquals($expectedTaskType, $tasks[0]->type()->toString()); $this->assertTrue($firstMessageHandler->messageHandlerId()->equals($tasks[0]->messageHandlerId())); $domainEvents = $this->extractRecordedEvents($workflow); $this->assertEquals(3, count($domainEvents)); $this->assertInstanceOf(Workflow\StartMessageWasAssignedToWorkflow::class, $domainEvents[0]); $this->assertInstanceOf(Workflow\ProcessWasAddedToWorkflow::class, $domainEvents[1]); $this->assertInstanceOf(Workflow\TaskWasAddedToProcess::class, $domainEvents[2]); foreach ($domainEvents as $domainEvent) { if ($domainEvent instanceof Workflow\ProcessWasAddedToWorkflow) { $this->assertEquals($expectedProcessType, $domainEvent->processType()->toString()); } } }
/** * @test */ public function it_queues_incoming_messages_during_active_transaction_to_avoid_nested_transactions() { $wfMessage = $this->getUserDataCollectedTestMessage(); $eventBus = new EventBus(); $eventBus->utilize(new SingleTargetMessageRouter($this->getTestWorkflowProcessor())); $eventBus->utilize(new WorkflowProcessorInvokeStrategy()); $workflowEngine = new RegistryWorkflowEngine(); $workflowEngine->registerEventBus($eventBus, [NodeName::defaultName()->toString()]); $this->workflowMessageHandler->useWorkflowEngine($workflowEngine); $nextAnswer = $wfMessage->prepareDataProcessing(TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1), NodeName::defaultName())->answerWithDataProcessingCompleted(); $ref = new \ReflectionClass($nextAnswer); $refProp = $ref->getProperty('processTaskListPosition'); $refProp->setAccessible(true); $refProp->setValue($nextAnswer, null); $this->workflowMessageHandler->setNextAnswer($nextAnswer); //Without queueing incoming messages an exception will be thrown, cause the WorkflowMessageHandler answers //during active transaction and the WorkflowProcessor would try to load the not yet persisted process. $this->getTestWorkflowProcessor()->receiveMessage($wfMessage); $this->assertNotNull($this->lastPostCommitEvent); $recordedEvents = $this->lastPostCommitEvent->getRecordedEvents(); $eventNames = []; foreach ($recordedEvents as $recordedEvent) { $eventNames[] = $recordedEvent->messageName(); } $expectedEventNames = ['Prooph\\Processing\\Processor\\Task\\Event\\TaskEntryMarkedAsDone']; $this->assertEquals($expectedEventNames, $eventNames); }
/** * @test */ public function it_translates_itself_to_service_bus_message_and_back() { $wfMessage = WorkflowMessage::collectDataOf(UserDictionary::prototype(), 'test-case', NodeName::defaultName()->toString(), array('metadata' => true)); $sbMessage = $wfMessage->toServiceBusMessage(); $this->assertInstanceOf('Prooph\\Common\\Messaging\\RemoteMessage', $sbMessage); $copyOfWfMessage = WorkflowMessage::fromServiceBusMessage($sbMessage); $this->assertInstanceOf('Prooph\\Processing\\Message\\WorkflowMessage', $copyOfWfMessage); $this->assertEquals(MessageNameUtils::MESSAGE_NAME_PREFIX . 'proophprocessingtestmockuserdictionary-collect-data', $copyOfWfMessage->messageName()); $this->assertNull($copyOfWfMessage->payload()->extractTypeData()); $this->assertEquals(array('metadata' => true), $copyOfWfMessage->metadata()); $this->assertEquals(MessageNameUtils::COLLECT_DATA, $copyOfWfMessage->messageType()); $this->assertEquals('test-case', $copyOfWfMessage->origin()); $this->assertEquals(NodeName::defaultName()->toString(), $copyOfWfMessage->target()); }
/** * @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); }
/** * @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()); }
protected function getTestTaskListEntry() { $processId = ProcessId::generate(); $taskListId = TaskListId::linkWith(NodeName::defaultName(), $processId); $taskListPosition = TaskListPosition::at($taskListId, 1); $task = CollectData::from('test-crm', UserDictionary::prototype()); return TaskListEntry::newEntryAt($taskListPosition, $task); }
/** * @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; }
/** * @test */ public function it_creates_a_command_bus_that_dispatches_a_message_to_a_workflow_message_handler() { $env = Environment::setUp(["processing" => ["channels" => ['message_handler_channel' => ['targets' => ["test_command_handler"]]]]]); $messageHandler = new TestWorkflowMessageHandler(); $env->services()->set('test_command_handler', $messageHandler); $commandBus = $env->services()->get("processing.command_bus.test_command_handler"); $message = WorkflowMessage::collectDataOf(UserDictionary::prototype(), 'test-case', NodeName::defaultName()); $commandBus->dispatch($message); $this->assertSame($message, $messageHandler->lastWorkflowMessage()); }
/** * @param $dataDirection * @param null|string $handlerType * @param null|array $metadata * @return MessageHandler */ private function getMessageHandler($dataDirection, $handlerType = null, array $metadata = null) { if (!is_null($handlerType)) { $handlerType = MessageHandler\HandlerType::fromString($handlerType); } else { $handlerType = MessageHandler\HandlerType::connector(); } if (!is_null($metadata)) { $metadata = ProcessingMetadata::fromArray($metadata); } else { $metadata = ProcessingMetadata::noData(); } return MessageHandler::fromDefinition(MessageHandlerId::generate(), 'Article Export', NodeName::defaultName(), $handlerType, MessageHandler\DataDirection::fromString($dataDirection), MessageHandler\ProcessingTypes::support([ArticleCollection::prototype(), Article::prototype()]), $metadata, 'sqlconnector-pm-metadata', 'glyphicon-hdd', 'glyphicon', Article::prototype(), MessageHandler\ProcessingId::fromString('sqlconnector:::example')); }
/** * @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]]; }
/** * @test */ public function it_sends_a_sub_process_finished_event_via_message_dispatcher_to_a_handler() { $taskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1); $wfMessage = $this->getUserDataCollectedTestMessage(); $wfMessage->connectToProcessTask($taskListPosition); $logMessage = LogMessage::logDebugMsg("Just a fake event", $wfMessage); $subProcessFinished = SubProcessFinished::record(NodeName::defaultName(), $taskListPosition->taskListId()->processId(), true, $logMessage, $taskListPosition); $eventBus = new EventBus(); $eventRouter = new EventRouter(); $eventRouter->route(SubProcessFinished::MSG_NAME)->to($this->messageDispatcher); $eventBus->utilize($eventRouter); $eventBus->utilize(new ForwardToRemoteMessageDispatcherStrategy(new FromProcessingMessageTranslator())); $eventBus->dispatch($subProcessFinished); /** @var $receivedMessage SubProcessFinished */ $receivedMessage = $this->receivedMessage; $this->assertInstanceOf(get_class($subProcessFinished), $receivedMessage); $this->assertTrue($taskListPosition->taskListId()->processId()->equals($receivedMessage->subProcessId())); $this->assertTrue($taskListPosition->equals($receivedMessage->parentTaskListPosition())); $this->assertTrue($subProcessFinished->uuid()->equals($receivedMessage->uuid())); $this->assertTrue($logMessage->uuid()->equals($receivedMessage->lastMessage()->uuid())); $this->assertEquals($logMessage->technicalMsg(), $receivedMessage->lastMessage()->technicalMsg()); $this->assertEquals($subProcessFinished->createdAt()->format('Y-m-d H:i:s'), $receivedMessage->createdAt()->format('Y-m-d H:i:s')); }
/** * @return WorkflowProcessor */ protected function getTestWorkflowProcessor() { if (is_null($this->workflowProcessor)) { $this->workflowProcessor = new WorkflowProcessor(NodeName::defaultName(), $this->getTestEventStore(), $this->getTestProcessRepository(), $this->workflowEngine, $this->getTestProcessFactory()); } return $this->workflowProcessor; }
/** * @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()); }
/** * @test */ public function it_dispatches_a_sub_process_finished_event() { $taskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1); $wfMessage = $this->getUserDataCollectedTestMessage(); $wfMessage->connectToProcessTask($taskListPosition); $logMessage = LogMessage::logDebugMsg("Just a fake event", $wfMessage); $subProcessFinished = SubProcessFinished::record(NodeName::defaultName(), $taskListPosition->taskListId()->processId(), true, $logMessage, $taskListPosition); $this->workflowEngine->dispatch($subProcessFinished); $this->assertSame($subProcessFinished, $this->receivedMessage); }
/** * @test */ function it_installs_a_message_handler() { $messageHandler = ProcessingNode::initializeAs(NodeName::defaultName())->installMessageHandler(MessageHandlerId::generate(), 'Article Exporter', HandlerType::connector(), DataDirection::source(), ProcessingTypes::support([ArticleCollection::prototype()]), ProcessingMetadata::noData(), 'sqlconnector-pm-metadata', 'glyphicon-hdd', 'glyphicon', ArticleCollection::prototype(), ProcessingId::fromString('sqlconnector:::example')); $this->assertInstanceOf(MessageHandler::class, $messageHandler); }
/** * @param bool $singleItemMode * @return MessageHandler */ protected function getArticleImporterMessageHandler($singleItemMode = false) { $supportedProcessingType = $singleItemMode ? Article::prototype() : ArticleCollection::prototype(); return MessageHandler::fromDefinition(MessageHandlerId::generate(), 'Article Importer', NodeName::defaultName(), MessageHandler\HandlerType::connector(), MessageHandler\DataDirection::target(), MessageHandler\ProcessingTypes::support([$supportedProcessingType]), ProcessingMetadata::fromArray(['chunk_support' => true]), 'sqlconnector-pm-metadata', 'glyphicon-hdd', 'glyphicon'); }
/** * @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); }
/** * @return TaskList */ protected function getTestTaskList() { $task1 = CollectData::from('crm', UserDictionary::prototype()); $task2 = CollectData::from('online-shop', UserDictionary::prototype()); $task3 = CollectData::from('address-book', UserDictionary::prototype()); $processId = ProcessId::generate(); $taskListId = TaskListId::linkWith(NodeName::defaultName(), $processId); return TaskList::scheduleTasks($taskListId, [$task1, $task2, $task3]); }