/** * @param EventStore $eventStore * @param AggregateType $aggregateType * @param AggregateTranslator $aggregateTranslator * @param StreamStrategy|null $streamStrategy */ public function __construct(EventStore $eventStore, AggregateType $aggregateType, AggregateTranslator $aggregateTranslator, StreamStrategy $streamStrategy = null) { $this->eventStore = $eventStore; $this->eventStore->getActionEventEmitter()->attachListener('commit.pre', $this); $this->aggregateType = $aggregateType; $this->aggregateTranslator = $aggregateTranslator; if (null === $streamStrategy) { $streamStrategy = new SingleStreamStrategy($this->eventStore); } $this->streamStrategy = $streamStrategy; }
/** * @param array $data * @return array */ public function run(array $data) { switch ($data['adapter']) { case 'mysql': $connection = DriverManager::getConnection($data['options']); $connection->executeQuery('DROP TABLE IF EXISTS user_stream'); $adapter = new DoctrineEventStoreAdapter($connection, new FQCNMessageFactory(), new NoOpMessageConverter(), new JsonPayloadSerializer()); break; case 'postgres': $connection = DriverManager::getConnection($data['options']); $connection->executeQuery('DROP TABLE IF EXISTS user_stream'); $adapter = new DoctrineEventStoreAdapter($connection, new FQCNMessageFactory(), new NoOpMessageConverter(), new JsonPayloadSerializer()); break; case 'mongodb': $connection = new \MongoClient($data['options']['server']); $connection->selectDB('event_store_adapter_benchmarks')->selectCollection('user_stream')->drop(); $adapter = new MongoDbEventStoreAdapter(new FQCNMessageFactory(), new NoOpMessageConverter(), $connection, $data['options']['db_name']); break; default: throw new \InvalidArgumentException('invalid adapter given'); break; } $eventStore = new EventStore($adapter, new ProophActionEventEmitter()); $result = []; foreach ($data['batchSizes'] as $batchSize) { for ($i = 0; $i < $this->repeats; $i++) { $events = []; $start = microtime(true); for ($b = 1; $b <= $batchSize * 2; $b++) { $v1 = $b; $b++; $v2 = $b; $events[] = UserCreated::with(['name' => 'Max Mustermann ' . $i . '-' . $b, 'email' => 'contact' . $i . '-' . $b . '@prooph.de'], $v1); $events[] = UsernameChanged::with(['name' => 'John Doe ' . $i . '-' . $b], $v2); } $eventStore->beginTransaction(); $eventStore->create(new Stream(new StreamName('user_stream'), new \ArrayIterator($events))); $eventStore->commit(); $end = microtime(true); if ($connection instanceof Connection) { $connection->executeQuery('DROP TABLE IF EXISTS user_stream'); } else { $connection->selectDB('event_store_adapter_benchmarks')->selectCollection('user_stream')->drop(); } $diff = $end - $start; $result[$data['adapter'] . ' with batch size ' . $batchSize] = $diff; } } return $result; }
/** * @test */ public function it_translates_aggregate_back_and_forth() { $this->eventStore->beginTransaction(); $user = User::nameNew('John Doe'); $this->repository->addAggregateRoot($user); $this->eventStore->commit(); $this->eventStore->beginTransaction(); //Simulate a normal program flow by fetching the AR before modifying it $user = $this->repository->getAggregateRoot($user->id()); $user->changeName('Max Mustermann'); $this->eventStore->commit(); $this->resetRepository(); $loadedUser = $this->repository->getAggregateRoot($user->id()); $this->assertEquals('Max Mustermann', $loadedUser->name()); return $loadedUser; }
/** * Save a Chapter event to the chapter history. * * @param Message $domainMessage * @throws \Prooph\Done\Shared\Exception\StoryName * @throws \Exception */ public function logChapterEvent(Message $domainMessage) { $storyName = Metadata::getStoryNameFromMessage($domainMessage); if (!isset($this->storyTellers[$storyName->toString()])) { throw Exception\StoryName::isNotLinkedWithStoryTeller($storyName); } $storyTeller = $this->storyTellers[$storyName->toString()]; try { $this->eventStore->beginTransaction(); $storyTeller($domainMessage); $this->eventStore->commit(); } catch (\Exception $ex) { $this->eventStore->rollback(); throw $ex; } }
private function rollbackTransaction() { if ($this->inTransaction) { $this->eventStore->rollback(); } $this->inTransaction = false; $this->checkMessageQueue(); }
/** * Check if exception an exception was thrown. If so rollback event store transaction * otherwise commit it. * * @param ActionEvent $actionEvent */ public function onFinalize(ActionEvent $actionEvent) { if ($this->eventStore->isInTransaction()) { if ($actionEvent->getParam(CommandBus::EVENT_PARAM_EXCEPTION)) { $this->eventStore->rollback(); } else { $this->eventStore->commit(); } } $this->currentCommand = null; }
/** * @param string $aggregateId * @return null|object */ protected function loadFromSnapshotStore($aggregateId) { $snapshot = $this->snapshotStore->get($this->aggregateType, $aggregateId); if (!$snapshot) { return; } $aggregateRoot = $snapshot->aggregateRoot(); $streamName = $this->determineStreamName($aggregateId); $streamEvents = $this->eventStore->loadEventsByMetadataFrom($streamName, ['aggregate_type' => $this->aggregateType->toString(), 'aggregate_id' => $aggregateId], $snapshot->lastVersion() + 1); if (!$streamEvents->valid()) { return $aggregateRoot; } $this->aggregateTranslator->replayStreamEvents($aggregateRoot, $streamEvents); return $aggregateRoot; }
/** * @test */ public function it_publishes_take_snapshot_commands_by_event_name() { $this->eventStore->beginTransaction(); $user = User::create('Alex', '*****@*****.**'); $this->repository->addAggregateRoot($user); $this->eventStore->commit(); $this->eventStore->beginTransaction(); $user = $this->repository->getAggregateRoot($user->getId()->toString()); $user->changeName('Jim'); $this->eventStore->commit(); $this->eventStore->beginTransaction(); $eventWithoutMetadata1 = UsernameChanged::with(['new_name' => 'John Doe'], 5); $this->eventStore->appendTo(new StreamName('event_stream'), new \ArrayIterator([$eventWithoutMetadata1])); $this->eventStore->commit(); $this->assertCount(1, $this->result); $this->assertArrayHasKey('aggregate_type', $this->result[0]); $this->assertArrayHasKey('aggregate_id', $this->result[0]); $this->assertEquals(User::class, $this->result[0]['aggregate_type']); }
/** * @test * @expectedException Prooph\EventStore\Exception\StreamNotFoundException */ public function it_throws_stream_not_found_exception_if_adapter_loads_nothing() { $stream = $this->getTestStream(); $adapter = $this->prophesize(Adapter::class); $eventStore = new EventStore($adapter->reveal(), new ProophActionEventEmitter()); $eventStore->beginTransaction(); $eventStore->create($stream); $eventStore->commit(); $eventStore->load($stream->streamName()); }
*/ public function get(Uuid $uuid) { return $this->getAggregateRoot($uuid->toString()); } } } namespace { //Set up an EventStore with an InMemoryAdapter (Only useful for testing, persistent adapters for ProophEventStore are available) use My\Infrastructure\UserRepositoryImpl; use My\Model\User; use Prooph\Common\Event\ActionEvent; use Prooph\Common\Event\ProophActionEventEmitter; use Prooph\EventStore\Adapter\InMemoryAdapter; use Prooph\EventStore\EventStore; $eventStore = new EventStore(new InMemoryAdapter(), new ProophActionEventEmitter()); //Now we set up our user repository and inject the EventStore //Normally this should be done in an IoC-Container and the receiver of the repository should require My\Model\UserRepository $userRepository = new UserRepositoryImpl($eventStore); //Ok lets start a new transaction and create a user $eventStore->beginTransaction(); $user = User::nameNew('John Doe'); $userRepository->add($user); //Before we commit the transaction let's attach a listener to check that the UserWasCreated event is published after commit $eventStore->getActionEventEmitter()->attachListener('commit.post', function (ActionEvent $event) { foreach ($event->getParam('recordedEvents', new \ArrayIterator()) as $streamEvent) { echo sprintf("Event with name %s was recorded. It occurred on %s UTC /// ", $streamEvent->messageName(), $streamEvent->createdAt()->format('Y-m-d H:i:s')); } }); $eventStore->commit(); $userId = $user->userId();
* file that was distributed with this source code. */ require __DIR__ . '/../vendor/autoload.php'; use Prooph\Common\Event\ProophActionEventEmitter; use Prooph\Common\Messaging\FQCNMessageFactory; use Prooph\Common\Messaging\NoOpMessageConverter; use Prooph\EventStore\Adapter\Flywheel\FlywheelEventStoreAdapter; use Prooph\EventStore\EventStore; use Prooph\EventStore\Stream\Stream; use Prooph\EventStore\Stream\StreamName; use ProophTest\EventStore\Mock\UserCreated; use ProophTest\EventStore\Mock\UsernameChanged; $rootDir = __DIR__ . '/event_store'; $adapter = new FlywheelEventStoreAdapter($rootDir, new FQCNMessageFactory(), new NoOpMessageConverter()); $actionEmitter = new ProophActionEventEmitter(); $eventStore = new EventStore($adapter, $actionEmitter); $streamName = new StreamName('event_stream'); $stream = new Stream($streamName, new \ArrayIterator([])); // // Persist some events in the event store // $eventStore->beginTransaction(); $eventStore->create($stream); $eventStore->appendTo($streamName, new \ArrayIterator([UserCreated::with(['name' => 'Max Mustermann'], 1)->withAddedMetadata('tag', 'person'), UsernameChanged::with(['name' => 'John Doe'], 2)->withAddedMetadata('tag', 'person')])); $eventStore->commit(); // // Load all the stored events // $persistedEventStream = $eventStore->load($streamName); foreach ($persistedEventStream->streamEvents() as $event) { echo $event->payload()['name'] . PHP_EOL;
/** * @param string $processId * @param int $minVersion * @return DomainEvent[] */ public function getStreamOfProcess($processId, $minVersion = 0) { Assertion::uuid($processId); return $this->eventStore->loadEventsByMetadataFrom(new StreamName('prooph_processing_stream'), ['aggregate_id' => $processId], $minVersion); }
/** * @return EventStore */ protected function getOtherMachineEventStore() { if (is_null($this->otherMachineEventStore)) { $inMemoryAdapter = new InMemoryAdapter(); $config = new Configuration(); $config->setAdapter($inMemoryAdapter); $this->otherMachineEventStore = new EventStore($config); $this->otherMachineEventStore->getActionEventDispatcher()->attachListener("commit.post", function (PostCommitEvent $postCommitEvent) { $this->otherMachineLastPostCommitEvent = $postCommitEvent; foreach ($postCommitEvent->getRecordedEvents() as $event) { $this->otherMachineEventNameLog[] = $event->messageName(); } }); $this->otherMachineEventStore->beginTransaction(); $this->otherMachineEventStore->create(new Stream(new StreamName('prooph_processing_stream'), [])); $this->otherMachineEventStore->commit(); } return $this->otherMachineEventStore; }
/** * @param AggregateType $aggregateType * @param string $aggregateId * @param null|int $minVersion * @return Message[] */ public function read(AggregateType $aggregateType, $aggregateId, $minVersion = null) { $stream = $this->eventStore->load($this->buildStreamName($aggregateType, $aggregateId), $minVersion); return $stream->streamEvents(); }
/** * @param EventStore $eventStore * @return void */ public function setUp(EventStore $eventStore) { $eventStore->getActionEventEmitter()->attachListener('commit.post', [$this, "onPostCommit"]); }
/** * @param EventStore $eventStore * @return void */ public function setUp(EventStore $eventStore) { $eventStore->getActionEventEmitter()->attachListener('commit.post', [$this, 'onEventStoreCommitPost'], -1000); }
/** * @param EventStore $eventStore */ public function setUp(EventStore $eventStore) { $eventEmitter = $eventStore->getActionEventEmitter(); $eventEmitter->attachListener('create.pre', [$this, 'onEventStoreCreateStream'], -1000); $eventEmitter->attachListener('appendTo.pre', [$this, 'onEventStoreAppendToStream'], -1000); }
/** * @param AggregateType $repositoryAggregateType * @param string $aggregateId * @param null|int $minVersion * @return Message[] */ public function read(AggregateType $repositoryAggregateType, $aggregateId, $minVersion = null) { Assertion::string($aggregateId, 'AggregateId needs to be string'); return $this->eventStore->loadEventsByMetadataFrom($this->streamName, ['aggregate_id' => $aggregateId], $minVersion); }
/** * @param ProcessId $processId * @param int $minVersion * @return DomainEvent[] */ public function getStreamOfProcess(ProcessId $processId, $minVersion = 0) { return $this->eventStore->loadEventsByMetadataFrom(new StreamName('prooph_processing_stream'), ['aggregate_id' => $processId->toString()], $minVersion); }