/**
  * @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]);
 }
 /**
  * Handles a POST request that want to change the node name
  */
 public function changeNodeNameAction()
 {
     $nodeName = $this->bodyParam('node_name');
     if (!is_string($nodeName) || strlen($nodeName) < 3) {
         return new ApiProblemResponse(new ApiProblem(422, $this->translator->translate('The node name must be at least 3 characters long')));
     }
     $this->commandBus->dispatch(ChangeNodeName::to(NodeName::fromString($nodeName), ConfigLocation::fromPath(Definition::getSystemConfigDir())));
     return ['success' => true];
 }
 /**
  * @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);
 }
Esempio n. 4
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());
 }
Esempio n. 6
0
 /**
  * @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());
 }
Esempio n. 7
0
/**
 * 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;
}
Esempio n. 8
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());
 }
Esempio n. 9
0
 /**
  * @param string $taskListIdStr
  * @throws \InvalidArgumentException
  * @return TaskListId
  */
 public static function fromString($taskListIdStr)
 {
     if (!is_string($taskListIdStr)) {
         throw new \InvalidArgumentException("TaskListIdStr must be string");
     }
     $parts = explode(':TASK_LIST_ID:', $taskListIdStr);
     if (count($parts) != 2) {
         throw new \InvalidArgumentException(sprintf("Invalid taskLIstIdStr %s provided. Needs to have the format: node-name:PROCESS_ID:process-uuid:TASK_LIST_ID:task-list-uuid", $taskListIdStr));
     }
     $envParts = explode(':PROCESS_ID:', $parts[0]);
     if (count($envParts) != 2) {
         throw new \InvalidArgumentException(sprintf("Invalid taskLIstIdStr %s provided. Needs to have the format: node-name:PROCESS_ID:process-uuid:TASK_LIST_ID:task-list-uuid", $taskListIdStr));
     }
     $nodeName = NodeName::fromString($envParts[0]);
     $processId = ProcessId::fromString($envParts[1]);
     return new self($nodeName, $processId, Uuid::fromString($parts[1]));
 }
Esempio n. 10
0
 /**
  * @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());
 }
Esempio n. 11
0
 /**
  * @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());
         }
     }
 }
Esempio n. 12
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_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 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_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());
 }
 /**
  * @test
  */
 function it_is_equal_to_a_node_with_the_same_name()
 {
     $processingNode1 = ProcessingNode::initializeAs(NodeName::fromString('localhost'));
     $processingNode2 = ProcessingNode::initializeAs(NodeName::fromString('localhost'));
     $this->assertTrue($processingNode1->sameNodeAs($processingNode2));
 }
Esempio n. 17
0
 /**
  * @return NodeName
  */
 public function newNodeName()
 {
     return NodeName::fromString($this->payload['node_name']);
 }
Esempio n. 18
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;
 }
Esempio n. 19
0
 /**
  * @param NodeName $newNodeName
  * @param ConfigWriter $configWriter
  */
 public function changeNodeName(NodeName $newNodeName, ConfigWriter $configWriter)
 {
     $oldNodeName = NodeName::fromString($this->config['processing']['node_name']);
     $this->config['processing']['node_name'] = $newNodeName->toString();
     $oldNodeNameAsString = $oldNodeName->toString();
     foreach ($this->config['processing']['channels'] as &$channelConfig) {
         foreach ($channelConfig['targets'] as $i => $target) {
             if ($target === $oldNodeNameAsString) {
                 $channelConfig['targets'][$i] = $newNodeName->toString();
             }
         }
         if (isset($channelConfig['origin']) && $channelConfig['origin'] === $oldNodeNameAsString) {
             $channelConfig['origin'] = $newNodeName->toString();
         }
         if (isset($channelConfig['sender']) && $channelConfig['sender'] === $oldNodeNameAsString) {
             $channelConfig['sender'] = $newNodeName->toString();
         }
     }
     $this->writeConfig($configWriter);
     $this->recordThat(NodeNameWasChanged::to($newNodeName, $oldNodeName));
 }
 /**
  * @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);
 }
Esempio n. 21
0
 /**
  * @return array
  */
 public function getArrayCopy()
 {
     return ['target_node_name' => $this->targetNodeName->toString(), 'process_definition' => $this->processDefinition, 'sync_log_messages' => $this->syncLogMessages];
 }
Esempio n. 22
0
 /**
  * @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_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);
 }
Esempio n. 24
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());
 }
Esempio n. 25
0
 /**
  * @return WorkflowProcessor
  */
 protected function getOtherMachineWorkflowProcessor()
 {
     if (is_null($this->otherMachineWorkflowProcessor)) {
         $this->otherMachineWorkflowProcessor = new WorkflowProcessor(NodeName::fromString('other_machine'), $this->getOtherMachineEventStore(), $this->getOtherMachineProcessRepository(), $this->otherMachineWorkflowEngine, $this->getTestProcessFactory());
         $this->otherMachineCommandRouter->route(StartSubProcess::MSG_NAME)->to($this->otherMachineWorkflowProcessor);
     }
     return $this->otherMachineWorkflowProcessor;
 }
Esempio n. 26
0
 /**
  * @param array $taskDefinition
  * @return RunSubProcess
  */
 private function createRunSubProcessTaskFromDefinition(array $taskDefinition)
 {
     Assertion::keyExists($taskDefinition, "target_node_name");
     Assertion::keyExists($taskDefinition, "process_definition");
     Assertion::isArray($taskDefinition["process_definition"]);
     return RunSubProcess::setUp(NodeName::fromString($taskDefinition['target_node_name']), $taskDefinition["process_definition"]);
 }
 /**
  * @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);
 }
Esempio n. 28
0
 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);
 }
Esempio n. 29
0
 /**
  * @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);
 }
Esempio n. 30
0
 /**
  * @return NodeName
  */
 public function getNodeName()
 {
     return NodeName::fromString($this->getConfig()->stringValue('node_name'));
 }