/** * @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_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']); }
*/ 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; }
/** * @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 */ public function it_replays_in_correct_order_with_same_date_time() { $sameDate = new \DateTimeImmutable('now', new \DateTimeZone('UTC')); $streamEvent1 = UserCreated::withPayloadAndSpecifiedCreatedAt(['name' => 'Alex', 'email' => '*****@*****.**'], 1, $sameDate); $streamEvent2 = UsernameChanged::withPayloadAndSpecifiedCreatedAt(['new_name' => 'John Doe'], 2, $sameDate); $streamEvent3 = PostCreated::withPayloadAndSpecifiedCreatedAt(['text' => 'some text'], 1, $sameDate); $stream1 = new Stream(new StreamName('user'), new ArrayIterator([$streamEvent1])); $stream2 = new Stream(new StreamName('post'), new ArrayIterator([$streamEvent3])); $this->eventStore->beginTransaction(); $this->eventStore->create($stream1); $this->eventStore->commit(); $this->eventStore->beginTransaction(); $this->eventStore->create($stream2); $this->eventStore->commit(); $this->eventStore->beginTransaction(); $this->eventStore->appendTo(new StreamName('user'), new ArrayIterator([$streamEvent2])); $this->eventStore->commit(); $iterator = $this->eventStore->replay([new StreamName('user'), new StreamName('post')]); $count = 0; foreach ($iterator as $key => $event) { $count += 1; if (1 === $count) { $this->assertInstanceOf(UserCreated::class, $event); } if (2 === $count) { $this->assertInstanceOf(UsernameChanged::class, $event); } if (3 === $count) { $this->assertInstanceOf(PostCreated::class, $event); } } $this->assertEquals(3, $count); }
/** * @test */ public function it_replays_events_of_two_aggregates_in_a_single_stream_in_correct_order() { // Create stream $stream = $this->createStream(); $this->adapter->create($stream); // Append new event $newEvent1 = UsernameChanged::with(['name' => 'John Doe'], 2)->withAddedMetadata('tag', 'person'); $this->adapter->appendTo(new StreamName('user_stream'), new \ArrayIterator([$newEvent1])); // Append new event for different aggragate $newEvent2 = UserCreated::with(['name' => 'Jane Doe', 'email' => '*****@*****.**'], 1)->withAddedMetadata('tag', 'person'); $this->adapter->appendTo(new StreamName('user_stream'), new \ArrayIterator([$newEvent2])); // Load events with replay $streamEvents = $this->adapter->replay(new StreamName('user_stream'), null, ['tag' => 'person']); $replayedPayloads = []; foreach ($streamEvents as $event) { $replayedPayloads[] = $event->payload(); } $expectedPayloads = [['name' => 'Max Mustermann', 'email' => '*****@*****.**'], ['name' => 'John Doe'], ['name' => 'Jane Doe', 'email' => '*****@*****.**']]; $this->assertEquals($expectedPayloads, $replayedPayloads); }
/** * @test * @expectedException \Prooph\EventStore\Exception\ConcurrencyException */ public function it_fails_to_write_with_duplicate_aggregate_id_and_version() { $streamEvent = UserCreated::with(['name' => 'Max Mustermann', 'email' => '*****@*****.**'], 1); $streamEvent = $streamEvent->withAddedMetadata('aggregate_id', 'one'); $streamEvent = $streamEvent->withAddedMetadata('aggregate_type', 'user'); $this->adapter->create(new Stream(new StreamName('Prooph\\Model\\User'), new \ArrayIterator([$streamEvent]))); $streamEvent = UsernameChanged::with(['name' => 'John Doe'], 1); $streamEvent = $streamEvent->withAddedMetadata('aggregate_id', 'one'); $streamEvent = $streamEvent->withAddedMetadata('aggregate_type', 'user'); $this->adapter->appendTo(new StreamName('Prooph\\Model\\User'), new \ArrayIterator([$streamEvent])); }