protected function setUp() { parent::setUp(); $eventBus = new EventBus(); $commandBus = new CommandBus(); $commandRouter = new CommandRouter(); $commandRouter->route(StartSubProcess::MSG_NAME)->to(function (StartSubProcess $command) { $this->receivedMessage = $command; }); $commandRouter->route('processing-message-proophprocessingtestmockuserdictionary-collect-data')->to(function (WorkflowMessage $message) { $this->receivedMessage = $message; }); $commandBus->utilize($commandRouter); $commandBus->utilize(new ToProcessingMessageTranslator()); $commandBus->utilize(new CallbackStrategy()); $eventRouter = new EventRouter(); $eventRouter->route('processing-message-proophprocessingtestmockuserdictionary-data-collected')->to(function (WorkflowMessage $workflowMessage) { $this->receivedMessage = $workflowMessage; }); $eventRouter->route('processing-log-message')->to(function (LogMessage $logMessage) { $this->receivedMessage = $logMessage; }); $eventRouter->route(SubProcessFinished::MSG_NAME)->to(function (SubProcessFinished $event) { $this->receivedMessage = $event; }); $eventBus->utilize($eventRouter); $eventBus->utilize(new ToProcessingMessageTranslator()); $eventBus->utilize(new CallbackStrategy()); $this->workflowEngine = new RegistryWorkflowEngine(); $this->workflowEngine->registerCommandBus($commandBus, [NodeName::defaultName()->toString(), 'test-target', 'sub-processor']); $this->workflowEngine->registerEventBus($eventBus, [NodeName::defaultName()->toString()]); }
/** * @test */ public function it_sends_remove_file_command_to_file_remover_via_php_resque() { $this->assertTrue(file_exists($this->testFile)); $commandBus = new CommandBus(); $commandRouter = new CommandRouter(); $messageDispatcher = new MessageDispatcher(['track_job_status' => true, 'queue' => 'php-resque-test-queue']); $commandRouter->route('Prooph\\ServiceBusTest\\Mock\\RemoveFileCommand')->to($messageDispatcher); $commandBus->utilize($commandRouter); $commandBus->utilize(new ForwardToRemoteMessageDispatcherStrategy(new ProophDomainMessageToRemoteMessageTranslator())); $jobId = null; $messageDispatcher->events()->attach('dispatch.post', function (EventInterface $e) use(&$jobId) { $jobId = $e->getParam('jobId'); }); $removeFile = RemoveFileCommand::fromPayload($this->testFile); $commandBus->dispatch($removeFile); $this->assertNotNull($jobId); $status = new \Resque_Job_Status($jobId); $this->assertEquals(\Resque_Job_Status::STATUS_WAITING, $status->get()); $worker = new \Resque_Worker(array('php-resque-test-queue')); $worker->logLevel = 1; $worker->work(0); $worker->shutdown(); $this->assertEquals(\Resque_Job_Status::STATUS_COMPLETE, $status->get()); $this->assertFalse(file_exists($this->testFile)); }
/** * @test */ public function it_invokes_processing_command_on_workflow_message_handler() { $wfCommand = WorkflowMessage::collectDataOf(UserDictionary::prototype(), 'test-case', NodeName::defaultName()); $commandBus = new CommandBus(); $commandRouter = new CommandRouter(); $commandRouter->route($wfCommand->messageName())->to($this->workflowMessageHandler); $commandBus->utilize($commandRouter); $commandBus->utilize(new HandleWorkflowMessageInvokeStrategy()); $commandBus->dispatch($wfCommand); $this->assertSame($wfCommand, $this->workflowMessageHandler->lastWorkflowMessage()); }
protected function setUp() { $commandBus = new CommandBus(); $commandRouter = new CommandRouter(); $commandRouter->route(StartSubProcess::MSG_NAME)->to(function ($command) { $this->startSubProcessCommands[] = $command; }); $commandBus->utilize($commandRouter); $commandBus->utilize(new CallbackStrategy()); $this->workflowEngine = new RegistryWorkflowEngine(); $this->workflowEngine->registerCommandBus($commandBus, [NodeName::defaultName()->toString()]); }
protected function setUp() { UsersFixture::createTableAndInsertUsers($this->getDbalConnection()); $this->messageReceiver = new StupidWorkflowProcessorMock(); $this->commandBus = new CommandBus(); $this->commandBus->utilize(new SingleTargetMessageRouter($this->messageReceiver)); $this->commandBus->utilize(new WorkflowProcessorInvokeStrategy()); $this->eventBus = new EventBus(); $this->eventBus->utilize(new SingleTargetMessageRouter($this->messageReceiver)); $this->eventBus->utilize(new WorkflowProcessorInvokeStrategy()); $this->tableGateway = new DoctrineTableGateway($this->getDbalConnection(), self::TEST_TABLE); $this->workflowEngine = new RegistryWorkflowEngine(); $this->workflowEngine->registerCommandBus($this->commandBus, [NodeName::defaultName()->toString(), 'test-case']); $this->workflowEngine->registerEventBus($this->eventBus, [NodeName::defaultName()->toString(), 'test-case']); $this->tableGateway->useWorkflowEngine($this->workflowEngine); }
protected function setUp() { $this->messageReceiver = new StupidWorkflowProcessorMock(); $this->commandBus = new CommandBus(); $this->commandBus->utilize(new SingleTargetMessageRouter($this->messageReceiver)); $this->commandBus->utilize(new WorkflowProcessorInvokeStrategy()); $this->eventBus = new EventBus(); $this->eventBus->utilize(new SingleTargetMessageRouter($this->messageReceiver)); $this->eventBus->utilize(new WorkflowProcessorInvokeStrategy()); $locationTranslator = new LocationTranslator(['temp' => sys_get_temp_dir(), 'testdata' => $this->getTestDataPath()]); $this->fileGateway = new FileGateway(Bootstrap::getServiceManager()->get('prooph.link.fileconnector.file_type_adapter_manager'), Bootstrap::getServiceManager()->get('prooph.link.fileconnector.filename_renderer'), $locationTranslator); $workflowEngine = new RegistryWorkflowEngine(); $workflowEngine->registerCommandBus($this->commandBus, [NodeName::defaultName()->toString(), 'file-connector']); $workflowEngine->registerEventBus($this->eventBus, [NodeName::defaultName()->toString(), 'file-connector']); $this->fileGateway->useWorkflowEngine($workflowEngine); $this->tempPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR; }
/** * @test */ public function it_passes_queued_commands_to_command_dispatch_exception_in_case_of_an_error() { $messageHandler = new MessageHandler(); $this->commandBus->utilize((new CommandRouter())->route(CustomMessage::class)->to($messageHandler)->route('initial message')->to(function () use($messageHandler) { $delayedMessage = new CustomMessage("delayed message"); $this->commandBus->dispatch($delayedMessage); throw new \Exception("Ka Boom"); })); $commandDispatchException = null; try { $this->commandBus->dispatch('initial message'); } catch (CommandDispatchException $ex) { $commandDispatchException = $ex; } $this->assertInstanceOf(CommandDispatchException::class, $commandDispatchException); $this->assertSame(1, count($commandDispatchException->getPendingCommands())); $this->assertSame(CustomMessage::class, get_class($commandDispatchException->getPendingCommands()[0])); }
public function setUp() { $inMemoryAdapter = new InMemoryAdapter(); $eventEmitter = new ProophActionEventEmitter(); $this->eventStore = new EventStore($inMemoryAdapter, $eventEmitter); $this->repository = new AggregateRepository($this->eventStore, AggregateType::fromAggregateRootClass('ProophTest\\EventStore\\Mock\\User'), new ConfigurableAggregateTranslator()); $this->result = []; $self = $this; $router = new CommandRouter(); $router->route(TakeSnapshot::class)->to(function (TakeSnapshot $command) use($self) { $self->result[] = ['aggregate_type' => $command->aggregateType(), 'aggregate_id' => $command->aggregateId()]; }); $commandBus = new CommandBus(); $commandBus->utilize($router); $plugin = new SnapshotPlugin($commandBus, 2); $plugin->setUp($this->eventStore); $this->eventStore->beginTransaction(); $this->eventStore->create(new Stream(new StreamName('event_stream'), new \ArrayIterator())); $this->eventStore->commit(); }
/** * @test */ public function it_publishes_take_snapshot_commands_for_all_known_aggregates() { $inMemoryAdapter = new InMemoryAdapter(); $eventEmitter = new ProophActionEventEmitter(); $eventStore = new EventStore($inMemoryAdapter, $eventEmitter); $repository = new AggregateRepository($eventStore, AggregateType::fromAggregateRootClass('ProophTest\\EventStore\\Mock\\User'), new ConfigurableAggregateTranslator()); $result = []; $router = new CommandRouter(); $router->route(TakeSnapshot::class)->to(function (TakeSnapshot $command) use(&$result) { $result[] = ['aggregate_type' => $command->aggregateType(), 'aggregate_id' => $command->aggregateId()]; }); $commandBus = new CommandBus(); $commandBus->utilize($router); $plugin = new SnapshotPlugin($commandBus, 2); $plugin->setUp($eventStore); $eventStore->beginTransaction(); $eventStore->create(new Stream(new StreamName('event_stream'), new \ArrayIterator())); $eventStore->commit(); $eventStore->beginTransaction(); $user = User::create('Alex', '*****@*****.**'); $repository->addAggregateRoot($user); $eventStore->commit(); $eventStore->beginTransaction(); $user = $repository->getAggregateRoot($user->getId()->toString()); $user->changeName('John'); $user->changeName('Jane'); $user->changeName('Jim'); $eventStore->commit(); $eventStore->beginTransaction(); $eventWithoutMetadata1 = UsernameChanged::with(['new_name' => 'John Doe'], 5); $eventWithoutMetadata2 = UsernameChanged::with(['new_name' => 'Jane Doe'], 6); $eventStore->appendTo(new StreamName('event_stream'), new \ArrayIterator([$eventWithoutMetadata1, $eventWithoutMetadata2])); $eventStore->commit(); $this->assertCount(2, $result); $this->assertArrayHasKey('aggregate_type', $result[0]); $this->assertArrayHasKey('aggregate_id', $result[0]); $this->assertArrayHasKey('aggregate_type', $result[1]); $this->assertArrayHasKey('aggregate_id', $result[1]); $this->assertEquals(User::class, $result[0]['aggregate_type']); $this->assertEquals(User::class, $result[1]['aggregate_type']); }
/** * @test */ public function it_sends_a_command_to_queue_pulls_it_with_consumer_and_forwards_it_to_command_bus() { $command = new DoSomething(['data' => 'test command']); //The message dispatcher works with a ready-to-use bernard producer and one queue $messageProducer = new BernardMessageProducer($this->bernardProducer, 'test-queue'); //Normally you would send the command on a command bus. We skip this step here cause we are only //interested in the function of the message dispatcher $messageProducer($command); //Set up command bus which will receive the command message from the bernard consumer $consumerCommandBus = new CommandBus(); $doSomethingHandler = new MessageHandler(); $consumerCommandBus->utilize(new CommandRouter([$command->messageName() => $doSomethingHandler])); //We use a special bernard router which forwards all messages to a command bus or event bus depending on the //Prooph\ServiceBus\Message\MessageHeader::TYPE $bernardRouter = new BernardRouter($consumerCommandBus, new EventBus()); $bernardConsumer = new Consumer($bernardRouter, new EventDispatcher()); //We use the same queue name here as we've defined for the message dispatcher above $bernardConsumer->tick($this->persistentFactory->create('test-queue')); $this->assertNotNull($doSomethingHandler->getLastMessage()); $this->assertEquals($command->payload(), $doSomethingHandler->getLastMessage()->payload()); }
protected function setUpOtherMachine() { $this->otherMachineWorkflowMessageHandler = new TestWorkflowMessageHandler(); $commandBus = new CommandBus(); $this->otherMachineCommandRouter = new CommandRouter(); $this->otherMachineCommandRouter->route(MessageNameUtils::getCollectDataCommandName('Prooph\\ProcessingTest\\Mock\\UserDictionaryS2'))->to($this->otherMachineWorkflowMessageHandler); $this->otherMachineCommandRouter->route(MessageNameUtils::getProcessDataCommandName('Prooph\\ProcessingTest\\Mock\\TargetUserDictionary'))->to($this->otherMachineWorkflowMessageHandler); $commandBus->utilize($this->otherMachineCommandRouter); $commandBus->utilize(new HandleWorkflowMessageInvokeStrategy()); $commandBus->utilize(new WorkflowProcessorInvokeStrategy()); $commandBus->utilize(new ToProcessingMessageTranslator()); $this->otherMachineWorkflowEngine = new RegistryWorkflowEngine(); $this->otherMachineWorkflowEngine->registerCommandBus($commandBus, ['test-case', 'test-target', 'other_machine']); //Add second command bus to local workflow engine to forward StartSubProcess command to message dispatcher $this->otherMachineMessageDispatcher = new InMemoryRemoteMessageDispatcher($commandBus, new EventBus()); $parentNodeCommandBus = new CommandBus(); $parentCommandRouter = new CommandRouter(); $parentCommandRouter->route(StartSubProcess::MSG_NAME)->to($this->otherMachineMessageDispatcher); $parentNodeCommandBus->utilize($parentCommandRouter); $parentNodeCommandBus->utilize(new ForwardToRemoteMessageDispatcherStrategy(new FromProcessingMessageTranslator())); $this->workflowEngine->registerCommandBus($parentNodeCommandBus, ['other_machine']); $this->getOtherMachineWorkflowProcessor(); //Add event buses to handle SubProcessFinished event $parentNodeEventBus = new EventBus(); $parentNodeEventRouter = new EventRouter(); $parentNodeEventBus->utilize(new SingleTargetMessageRouter($this->getTestWorkflowProcessor())); $parentNodeEventBus->utilize(new ToProcessingMessageTranslator()); $parentNodeEventBus->utilize(new WorkflowProcessorInvokeStrategy()); $otherMachineEventBus = new EventBus(); $toParentNodeMessageDispatcher = new InMemoryRemoteMessageDispatcher(new CommandBus(), $parentNodeEventBus); $otherMachineEventBus->utilize(new SingleTargetMessageRouter($toParentNodeMessageDispatcher)); $otherMachineEventBus->utilize(new ForwardToRemoteMessageDispatcherStrategy(new FromProcessingMessageTranslator())); $this->otherMachineWorkflowEngine->registerEventBus($otherMachineEventBus, [Definition::DEFAULT_NODE_NAME]); }
} /** * This method is called when message is instantiated named constructor fromArray * * @param array $payload * @return void */ protected function setPayload(array $payload) { $this->text = $payload['text']; } } } namespace { use Prooph\ServiceBus\CommandBus; use Prooph\ServiceBus\Example\Command\EchoText; use Prooph\ServiceBus\Plugin\Router\CommandRouter; $commandBus = new CommandBus(); $router = new CommandRouter(); //Register a callback as CommandHandler for the EchoText command $router->route('Prooph\\ServiceBus\\Example\\Command\\EchoText')->to(function (EchoText $aCommand) { echo $aCommand->getText(); }); //Expand command bus with the router plugin $commandBus->utilize($router); //We create a new Command $echoText = new EchoText('It works'); //... and dispatch it $commandBus->dispatch($echoText); //Output should be: It works }
/** * @test */ public function it_creates_process_with_run_sub_process_task_from_definition() { $subProcessDefinition = ["process_type" => Definition::PROCESS_LINEAR_MESSAGING, "tasks" => [["task_type" => Definition::TASK_COLLECT_DATA, "source" => 'test-case', "processing_type" => 'Prooph\\ProcessingTest\\Mock\\UserDictionary']]]; $runSubProcessTaskDefinition = ["target_node_name" => 'other_machine', "task_type" => Definition::TASK_RUN_SUB_PROCESS, "process_definition" => $subProcessDefinition]; $parentProcessDefinition = ["process_type" => Definition::PROCESS_LINEAR_MESSAGING, "tasks" => [$runSubProcessTaskDefinition]]; $processFactory = new ProcessFactory(); $parentProcess = $processFactory->createProcessFromDefinition($parentProcessDefinition, NodeName::defaultName()); /** @var $startSubProcess StartSubProcess */ $startSubProcess = null; $otherMachineCommandBus = new CommandBus(); $otherMachineCommandRouter = new CommandRouter(); $otherMachineCommandRouter->route(StartSubProcess::MSG_NAME)->to(function (StartSubProcess $command) use(&$startSubProcess) { $startSubProcess = $command; }); $otherMachineCommandBus->utilize($otherMachineCommandRouter); $otherMachineCommandBus->utilize(new CallbackStrategy()); $this->workflowEngine->registerCommandBus($otherMachineCommandBus, ['other_machine']); $parentProcess->perform($this->workflowEngine); $this->assertNotNull($startSubProcess); $this->assertEquals($subProcessDefinition, $startSubProcess->subProcessDefinition()); }
/** * @test */ public function it_sends_a_start_sub_process_command_via_message_dispatcher_to_a_handler() { $taskListPosition = TaskListPosition::at(TaskListId::linkWith(NodeName::defaultName(), ProcessId::generate()), 1); $startSupProcess = StartSubProcess::at($taskListPosition, ['process_type' => 'faked'], true, 'sub-processor'); $commandBus = new CommandBus(); $commandRouter = new CommandRouter(); $commandRouter->route(StartSubProcess::MSG_NAME)->to($this->messageDispatcher); $commandBus->utilize($commandRouter); $commandBus->utilize(new ForwardToRemoteMessageDispatcherStrategy(new FromProcessingMessageTranslator())); $commandBus->dispatch($startSupProcess); /** @var $receivedMessage StartSubProcess */ $receivedMessage = $this->receivedMessage; $this->assertInstanceOf(get_class($startSupProcess), $receivedMessage); $this->assertTrue($taskListPosition->equals($receivedMessage->parentTaskListPosition())); $this->assertTrue($startSupProcess->uuid()->equals($receivedMessage->uuid())); $this->assertEquals($startSupProcess->payload(), $receivedMessage->payload()); $this->assertEquals($startSupProcess->createdAt()->format('Y-m-d H:i:s'), $receivedMessage->createdAt()->format('Y-m-d H:i:s')); $this->assertEquals($startSupProcess->target(), $receivedMessage->target()); }
error_reporting(E_ALL); ini_set('display_errors', 1); include 'classes.php'; use Prooph\ServiceBus\CommandBus; use Prooph\ServiceBus\Example\Resque\FileWriter; use Prooph\ServiceBus\Example\Resque\WriteLine; use Prooph\ServiceBus\InvokeStrategy\ForwardToRemoteMessageDispatcherStrategy; use Prooph\ServiceBus\Message\PhpResque\MessageDispatcher; use Prooph\ServiceBus\Message\ProophDomainMessageToRemoteMessageTranslator; use Prooph\ServiceBus\Router\RegexRouter; use Zend\EventManager\EventInterface; if (isset($_GET['write'])) { //We are on the write side, so the resque-sample-bus needs information of how to send a message $commandBus = new CommandBus(); $messageDispatcher = new MessageDispatcher(['track_job_status' => true, 'queue' => 'resque-sample']); $commandBus->utilize(new RegexRouter([RegexRouter::ALL => $messageDispatcher])); $commandBus->utilize(new ForwardToRemoteMessageDispatcherStrategy(new ProophDomainMessageToRemoteMessageTranslator())); //The PhpResqueMessageDispatcher uses a Redis-Server to manage background jobs //We want to track the status of the job and therefor we use the event system of MessageDispatcher to capture the JobId //of a new created Job $jobId = null; //After the MessageDispatcher has done it's work, we capture the JobId with an EventListener $messageDispatcher->events()->attach('dispatch.post', function (EventInterface $e) use(&$jobId) { $jobId = $e->getParam('jobId'); }); //Prepare the Command $writeLine = WriteLine::fromPayload($_GET['write']); //...and send it to the message dispatcher via CommandBus $commandBus->dispatch($writeLine); echo 'Message is sent with JobId: ' . $jobId . '. You can check the status with ' . strtok($_SERVER["REQUEST_URI"], '?') . '<b>?status=' . $jobId . '</b>'; } elseif (isset($_GET['status'])) {