/** * @test * @expectedException \Prooph\Snapshotter\Exception\RuntimeException * @expectedExceptionMessage Could not find aggregate root */ public function it_throws_exception_when_aggregate_root_not_found() { $repository = $this->prophesize(AggregateRepository::class); $snapshotStore = $this->prophesize(SnapshotStore::class); $snapshotter = new Snapshotter($snapshotStore->reveal(), ['ProophTest\\EventStore\\Mock\\User' => $repository->reveal()]); $snapshotter(TakeSnapshot::withData('ProophTest\\EventStore\\Mock\\User', 'invalid id')); }
/** * @param TakeSnapshot $command * @throws Exception\RuntimeException */ public function __invoke(TakeSnapshot $command) { $aggregateType = $command->aggregateType(); if (!isset($this->aggregateRepositories[$aggregateType])) { throw new Exception\RuntimeException(sprintf('No repository for aggregate type %s configured', $command->aggregateType())); } $repository = $this->aggregateRepositories[$aggregateType]; $aggregateRoot = $repository->getAggregateRoot($command->aggregateId()); if (null === $aggregateRoot) { throw new RuntimeException(sprintf('Could not find aggregate root %s with id %s', $aggregateType, $command->aggregateId())); } $this->snapshotStore->save(new Snapshot(AggregateType::fromAggregateRootClass($aggregateType), $command->aggregateId(), $aggregateRoot, $repository->extractAggregateVersion($aggregateRoot), $command->createdAt())); }
/** * Take snapshots on event-store::commit.post * * @param ActionEvent $actionEvent */ public function onEventStoreCommitPost(ActionEvent $actionEvent) { $recordedEvents = $actionEvent->getParam('recordedEvents', []); $snapshots = []; foreach ($recordedEvents as $recordedEvent) { if ($recordedEvent->version() % $this->versionStep !== 0) { continue; } $metadata = $recordedEvent->metadata(); if (!isset($metadata['aggregate_type']) || !isset($metadata['aggregate_id'])) { continue; } $snapshots[$metadata['aggregate_type']][] = $metadata['aggregate_id']; } foreach ($snapshots as $aggregateType => $aggregateIds) { foreach ($aggregateIds as $aggregateId) { $command = TakeSnapshot::withData($aggregateType, $aggregateId); $this->commandBus->dispatch($command); } } }
/** * Take snapshots on event-store::commit.post * * @param ActionEvent $actionEvent */ public function onEventStoreCommitPost(ActionEvent $actionEvent) { $recordedEvents = $actionEvent->getParam('recordedEvents', new \ArrayIterator()); $snapshots = []; /* @var $recordedEvent \Prooph\Common\Messaging\Message */ foreach ($recordedEvents as $recordedEvent) { $doSnapshot = $recordedEvent->version() % $this->versionStep === 0; if (false === $doSnapshot && false === $this->hasEventNames) { continue; } $metadata = $recordedEvent->metadata(); if (!isset($metadata['aggregate_type'], $metadata['aggregate_id']) || false === $doSnapshot && !in_array($recordedEvent->messageName(), $this->eventNames, true)) { continue; } $snapshots[$metadata['aggregate_type']][] = $metadata['aggregate_id']; } foreach ($snapshots as $aggregateType => $aggregateIds) { foreach ($aggregateIds as $aggregateId) { $command = TakeSnapshot::withData($aggregateType, $aggregateId); $this->commandBus->dispatch($command); } } }
/** * @param TakeSnapshot $command */ public function __invoke(TakeSnapshot $command) { $repository = $this->aggregateRepositories[$command->aggregateType()]; $aggregateRoot = $repository->getAggregateRoot($command->aggregateId()); $this->snapshotAdapter->add(new Snapshot(AggregateType::fromAggregateRootClass($command->aggregateType()), $command->aggregateId(), $aggregateRoot, $command->version(), $command->createdAt())); }