Exemplo n.º 1
0
 /**
  * @param StoryName $storyName
  * @param StoryTeller $storyTeller
  * @throws \Prooph\Done\Shared\Exception\StoryTeller
  */
 public function registerStoryTeller(StoryName $storyName, StoryTeller $storyTeller)
 {
     if (isset($this->storyTellers[$storyName->toString()])) {
         throw Exception\StoryTeller::alreadyRegisteredForStoryName($storyName);
     }
     $this->storyTellers[$storyName->toString()] = $storyTeller;
 }
Exemplo n.º 2
0
 /**
  * @test
  */
 public function it_can_be_started_with_a_message_and_provides_next_commands()
 {
     $startMessage = new FileWasUploaded();
     $story = Story::start(StoryName::fromString('Test Story'), $startMessage, $this->getTestChapterTemplates(), new NoOpMessageConverter());
     $events = $this->popRecordedEvents($story);
     $this->assertEquals(2, count($events));
     /** @var $storyWasStarted Story\Event\StoryWasStarted */
     $storyWasStarted = $events[0];
     $this->assertInstanceOf(Story\Event\StoryWasStarted::class, $storyWasStarted);
     $this->assertEquals('Test Story', $storyWasStarted->storyName()->toString());
     //StoryId should be the uuid of the start message
     $this->assertEquals($startMessage->uuid()->toString(), $storyWasStarted->storyId()->toString());
     /** @var $chapterWasStarted Story\Event\ChapterWasStarted */
     $chapterWasStarted = $events[1];
     $this->assertInstanceOf(Story\Event\ChapterWasStarted::class, $chapterWasStarted);
     $this->assertTrue($storyWasStarted->storyId()->equals($chapterWasStarted->chapterStatus()->chapterNumber()->storyId()));
     $this->assertEquals(Story\ChapterStatus::STATUS_RUNNING, $chapterWasStarted->chapterStatus()->status());
     $this->assertEquals(1, $chapterWasStarted->chapterStatus()->chapterNumber()->number());
     $nextCommands = $story->getNextCommands();
     $this->assertEquals(1, count($nextCommands));
     $this->assertInstanceOf(ProcessFile::class, $nextCommands[0]);
     //Next commands can only be requested once
     $this->assertEquals(0, count($story->getNextCommands()));
     $this->applyPendingEvents($story, $events);
     return [$story, $nextCommands[0]];
 }
Exemplo n.º 3
0
 /**
  * @return StoryName
  */
 public function storyName()
 {
     if (null === $this->storyName) {
         $this->storyName = StoryName::fromString($this->payload['story_name']);
     }
     return $this->storyName;
 }
Exemplo n.º 4
0
 /**
  * @test
  */
 public function it_starts_a_new_chapter_by_providing_the_chapter_command()
 {
     $fileWasUploaded = new FileWasUploaded();
     $startCondition = $this->prophesize(MessageCondition::class);
     $startCondition->isTrueFor($fileWasUploaded)->willReturn(true);
     $isDoneCondition = $this->prophesize(MessageCondition::class);
     $payloadGenerator = $this->prophesize(PayloadGenerator::class);
     $payloadGenerator->__invoke(Argument::any(), Argument::any(), Argument::any())->will(function ($args) {
         list($previousMessage, $payload, $metadata) = $args;
         $payload['filename'] = $previousMessage->payload()['filename'];
     });
     $commandTemplate = new MessageTemplate(ProcessFile::class, new FQCNMessageFactory(), [], [], $payloadGenerator->reveal());
     $chapterTemplate = new ChapterTemplate(ChapterName::fromString('File Processor'), $commandTemplate, $startCondition->reveal(), $isDoneCondition->reveal());
     $storyId = StoryId::generateNew();
     $chapterNumber = ChapterNumber::withNumber($storyId, 2);
     $chapterCommand = $chapterTemplate->startChapter(StoryName::fromString('Test Story'), $chapterNumber, $fileWasUploaded);
     $this->assertInstanceOf(ProcessFile::class, $chapterCommand);
     $this->assertEquals('some-file.csv', $chapterCommand->payload()['filename']);
     $this->assertEquals($chapterNumber->toString(), $chapterCommand->metadata()[Metadata::STORY_CHAPTER]);
     $this->assertEquals('Test Story', $chapterCommand->metadata()[Metadata::STORY_NAME]);
 }
Exemplo n.º 5
0
$storyLog = new \Prooph\Done\Infrastructure\EventStoreStoryLog($eventStore);
$commandRouter = new \Prooph\ServiceBus\Plugin\Router\CommandRouter();
$commandBus = new \Prooph\ServiceBus\CommandBus();
$commandBus->utilize($commandRouter);
//Enable transaction handling based on command dispatch
$transactionManager = new \Prooph\EventStoreBusBridge\TransactionManager($eventStore);
$commandBus->utilize($transactionManager);
$delayedCommandBus = new \Prooph\Done\Infrastructure\DelayedCommandBus($commandBus);
//The delayed command bus queues commands until next EventStore.commit.post event occurs
$delayedCommandBus->setUp($eventStore);
//As a Story can handle and dispatch any message implementing Prooph\Common\Messaging\Message
//it requires a message factory and message converter to be able to create and log  messages correctly
$messageFactory = new \Prooph\Common\Messaging\FQCNMessageFactory();
$messageConverter = new \Prooph\Common\Messaging\NoOpMessageConverter();
//Set up the story
$storyName = \Prooph\Done\Shared\StoryName::fromString('Json to CSV Conversion');
//Set up the StoryTeller - basically a StoryTeller is a generic message handler but specifically
//designed to handle a single Story configured with so called ChapterTemplates
$jsonToCSVStoryTeller = new \Prooph\Done\Story\StoryTeller($storyName, [new \Prooph\Done\Story\ChapterTemplate(\Prooph\Done\Story\ChapterName::fromString('Merge Json Files'), new \Prooph\Done\Message\MessageTemplate(\ProophExample\Done\JsonToCSVStory\MergeJsonFilesChapter\MergeJsonFiles::class, $messageFactory, ['json_files_directory' => __DIR__ . DIRECTORY_SEPARATOR . 'data', 'to_filename' => 'users.json', 'file_pattern' => '/^user[\\d]{1,}\\.json$/']), new \ProophExample\Done\JsonToCSVStory\IsStartStoryCommand(), new \ProophExample\Done\JsonToCSVStory\IsInfoSuccessEvent()), new \Prooph\Done\Story\ChapterTemplate(\Prooph\Done\Story\ChapterName::fromString('Convert Json to CSV'), new \Prooph\Done\Message\MessageTemplate(\ProophExample\Done\JsonToCSVStory\JsonToCSVChapter\ConvertJsonToCSV::class, $messageFactory, [], [], function (\Prooph\Done\ChapterLogger\Event\Info $previousMessage, \ArrayObject $payload, \ArrayObject $metadata) {
    //We extract the generated filename from the previous event
    //to use it as input file for the next chapter command
    $inputFile = $previousMessage->payload()['context']['to_file_path'];
    $outputFile = str_replace('.json', '.csv', $inputFile);
    //Payload and metadata for the next chapter command are passed as \ArrayObjects
    //to the PayloadGenerator callback so that the callback can manipulate them both
    $payload['input_file'] = $inputFile;
    $payload['output_file'] = $outputFile;
}), new \ProophExample\Done\JsonToCSVStory\IsInfoSuccessEvent(), new \ProophExample\Done\JsonToCSVStory\IsInfoSuccessEvent())], $storyLog, $delayedCommandBus, $messageFactory, $messageConverter);
//We route the start command of the story to the responsible story teller
$commandRouter->route(\ProophExample\Done\JsonToCSVStory\StartStory::class)->to($jsonToCSVStoryTeller);
//As we perform the chapter in the same process as handling the Story
Exemplo n.º 6
0
 /**
  * @param \Prooph\Done\Story\ChapterName $chapterName
  * @param StoryName $storyName
  * @return ChapterName
  */
 public static function isDuplicateForStory(\Prooph\Done\Story\ChapterName $chapterName, StoryName $storyName)
 {
     return new self(sprintf('Duplicate Chapter name %s for story %s detected', $chapterName->toString(), $storyName->toString()));
 }
Exemplo n.º 7
0
 /**
  * @param StoryName $storyName
  * @param ChapterNumber $chapterNumber
  * @param Message $previousMessage
  * @return Message
  */
 public function startChapter(StoryName $storyName, ChapterNumber $chapterNumber, Message $previousMessage)
 {
     $command = $this->chapterCommandTemplate->createMessageFromPreviousMessage($previousMessage);
     $command = $command->withAddedMetadata(Metadata::STORY_CHAPTER, $chapterNumber->toString());
     return $command->withAddedMetadata(Metadata::STORY_NAME, $storyName->toString());
 }
Exemplo n.º 8
0
 /**
  * @param ChapterName $chapterName
  * @param StoryName $storyName
  * @return Story
  */
 public static function cannotFindMatchingTemplateForChapterName(ChapterName $chapterName, StoryName $storyName)
 {
     return new self(sprintf('Story %s cannot find matching template for chapter name %s', $storyName->toString(), $chapterName->toString()));
 }