/** * @return void */ public function run() { $logger = new Logger('default'); $sagaFactory = new GenericSagaFactory(); $sagaStorage = new MemorySagaStorage(); $sagaRepository = new SagaRepository($sagaStorage, new JsonSerializer()); $resolver = new SimpleAssociationValueResolver(); $sagaManager = new SimpleSagaManager([ToDoSaga::class], $sagaRepository, $resolver, $sagaFactory); $eventBus = new SimpleEventBus([]); $eventBus->setLogger(new EventLogger($logger)); $eventBus->addHandler(Event::class, $sagaManager); $eventStore = new EventStore($eventBus, new MemoryEventStorage(), new JsonSerializer(), new EventClassMap([ToDoItemCreated::class, ToDoItemDone::class, DeadlineExpired::class])); $factory = new GenericAggregateFactory(ToDoItem::class); $repository = new EventSourcingRepository($factory, $eventStore); $commandHandler = new ToDoCommandHandler($repository); $commandBus = new SimpleCommandBus([CreateToDoItem::class => $commandHandler, MarkItemDone::class => $commandHandler]); $loggingCommandInterceptor = new LoggingInterceptor(new CommandLogger($logger)); $commandGateway = new DefaultCommandGateway($commandBus, [$loggingCommandInterceptor]); $toCompleteId = Identity::createNew(); $commandGateway->send(new CreateToDoItem($toCompleteId, "Item to complete", PHP_INT_MAX)); $sagaIds = $sagaRepository->find(ToDoSaga::class, new AssociationValue('identity', $toCompleteId->getValue())); $logger->debug("Active sagas found:", ['count' => count($sagaIds), 'saga' => !empty($sagaIds) ? $sagaStorage->findById($sagaIds[0]->getValue()) : '']); $commandGateway->send(new MarkItemDone($toCompleteId)); $sagaIds = $sagaRepository->find(ToDoSaga::class, new AssociationValue('identity', $toCompleteId->getValue())); $logger->debug("Active sagas found:", ['count' => count($sagaIds), 'saga' => !empty($sagaIds) ? $sagaStorage->findById($sagaIds[0]->getValue())['serialized'] : '']); }
/** * @param Event $event */ public function on(Event $event) { $handled = false; /* @var $sagaType string */ foreach ($this->sagaTypes as $sagaType) { $associationValues = $this->extractAssociationValues($sagaType, $event); /* @var $associationValue AssociationValue */ foreach ($associationValues->getIterator() as $associationValue) { $sagaIdentities = $this->repository->find($sagaType, $associationValue); /* @var $identity Identity */ foreach ($sagaIdentities as $identity) { $saga = $this->repository->load($identity, $sagaType); $saga->on($event); $this->commit($saga); $handled = true; } } if ($this->getSagaCreationPolicy($sagaType, $event) == SagaCreationPolicy::ALWAYS || !$handled && $this->getSagaCreationPolicy($sagaType, $event) == SagaCreationPolicy::IF_NONE_FOUND) { $saga = $this->factory->createSaga($sagaType, Identity::createNew(), $associationValues); $saga->on($event); $this->commit($saga); } } }
/** * @test */ public function findReturnsIdentitiesForGivenSagaTypeAndAssociationValues() { $storage = $this->createStorage(); $serializer = $this->createSerializer(); $sagaIdentity = Identity::createNew(); $associationValues = new AssociationValues([new AssociationValue('foo', 'bar')]); $saga = $this->getMockBuilder(Saga::class)->setConstructorArgs([$sagaIdentity, $associationValues])->getMock(); $storage->expects(self::once())->method('find')->with(get_class($saga), $this->associationValuesToArray($saga->getAssociationValues()))->willReturn([$sagaIdentity->getValue()]); $repository = new SagaRepository($storage, $serializer); $identities = $repository->find(get_class($saga), new AssociationValue('foo', 'bar')); self::assertCount(1, $identities); self::assertEquals($sagaIdentity->getValue(), $identities[0]); }