public function testNotCurrentUnitOfWorkCommitted() { $outerUoW = new DefaultUnitOfWork(); $outerUoW->start(); $other = new DefaultUnitOfWork(); $other->start(); try { $outerUoW->commit(); } catch (\Exception $ex) { $other->rollback(); $this->assertGreaterThanOrEqual(0, strpos($ex->getMessage(), "not the active")); } }
public function testLoadAndStoreAggregate() { DefaultUnitOfWork::startAndGet(); $aggregate = new StubAggregate(); $aggregate->doSomething(); /*$this->lockManager->expects($this->exactly(2)) ->method('obtainLock') ->with($this->equalTo($aggregate->getIdentifier())); $this->lockManager->expects($this->exactly(2)) ->method('releaseLock') ->with($this->equalTo($aggregate->getIdentifier()));*/ $this->testSubject->add($aggregate); CurrentUnitOfWork::commit(); DefaultUnitOfWork::startAndGet(); $loadedAggregate = $this->testSubject->load($aggregate->getIdentifier(), 0); //verify(lockManager).obtainLock(aggregate.getIdentifier()); $loadedAggregate->doSomething(); CurrentUnitOfWork::commit(); /* $lockManager = Phake::mock(get_class($this->lockManager)); \Phake::inOrder( \Phake::verify($lockManager)->validateLock(), \Phake::verify($lockManager)->releaseLock() );*/ //InOrder inOrder = inOrder(lockManager); // inOrder.verify(lockManager, atLeastOnce()).validateLock(loadedAggregate); // verify(mockEventBus, times(2)).publish(any(DomainEventMessage.class)); // inOrder.verify(lockManager).releaseLock(loadedAggregate.getIdentifier()); }
public function setUp() { $this->mockEntityManager = $this->getMock(EntityManager::class, array('find', 'flush', 'persist', 'remove'), array(), '', false); $this->mockEventBus = $this->getMock(EventBusInterface::class); $this->testSubject = new GenericOrmRepository(StubDoctrineAggregate::class, $this->mockEventBus, new NullLockManager(), $this->mockEntityManager); $this->aggregateId = "123"; $this->aggregate = new StubDoctrineAggregate($this->aggregateId); DefaultUnitOfWork::startAndGet(); }
public function setUp() { $this->mockEventStore = $this->getMock(SnapshotEventStoreInterface::class); $this->mockEventBus = $this->getMock(EventBusInterface::class); //, //array('publish', 'subscribe', 'unsubscribe')); $this->stubAggregateFactory = new StubAggregateFactory(); $this->testSubject = new EventSourcingRepository(TestAggregate::class, $this->mockEventBus, new NullLockManager(), $this->mockEventStore, $this->stubAggregateFactory); $this->unitOfWork = DefaultUnitOfWork::startAndGet(); }
public function testCommandHandlerLoadsSameAggregateTwice() { DefaultUnitOfWork::startAndGet(); $stubAggregate = new StubAggregate($this->aggregateIdentifier); $stubAggregate->doSomething(); $this->repository->add($stubAggregate); CurrentUnitOfWork::commit(); DefaultUnitOfWork::startAndGet(); $this->repository->load($this->aggregateIdentifier)->doSomething(); $this->repository->load($this->aggregateIdentifier)->doSomething(); CurrentUnitOfWork::commit(); $es = $this->mockEventStore->readEvents("", $this->aggregateIdentifier); $this->assertTrue($es->hasNext()); $this->assertEquals(0, $es->next()->getScn()); $this->assertTrue($es->hasNext()); $this->assertEquals(1, $es->next()->getScn()); $this->assertTrue($es->hasNext()); $this->assertEquals(2, $es->next()->getScn()); $this->assertFalse($es->hasNext()); }
public function testInterceptCommand_FailedExecution() { $exception = new \RuntimeException(); $this->mockInterceptorChain->expects($this->any())->method('proceed')->will($this->throwException($exception)); $uow = DefaultUnitOfWork::startAndGet(); $payload = new \stdClass(); $payload->value = "Command"; $command = new GenericCommandMessage($payload); try { $this->testSubject->handle($command, $uow, $this->mockInterceptorChain); } catch (\Exception $ex) { $this->assertSame($exception, $ex); } $aggregate = new StubAggregate(); $mockEventBus = $this->getMock(EventBusInterface::class); $mockCallback = $this->getMock(SaveAggregateCallbackInterface::class); $this->mockAuditDataProvider->expects($this->exactly(2))->method('provideAuditDataFor'); $this->mockAuditLogger->expects($this->never())->method('logSuccessful'); $this->mockAuditLogger->expects($this->any())->method('logFailed'); $uow->registerAggregate($aggregate, $mockEventBus, $mockCallback); $aggregate->doSomething(); $aggregate->doSomething(); try { $uow->rollback(new \RuntimeException()); } catch (\Exception $ex) { } }
private function detectIllegalStateChanges() { if (null !== $this->aggregateIdentifier && null !== $this->workingAggregate && $this->reportIllegalStateChange) { $uow = DefaultUnitOfWork::startAndGet(); try { $aggregate2 = $this->repository->load($this->aggregateIdentifier); if ($this->workingAggregate->isDeleted()) { throw new GovernorAssertionError("The working aggregate was considered deleted, " . "but the Repository still contains a non-deleted copy of " . "the aggregate. Make sure the aggregate explicitly marks " . "itself as deleted in an EventHandler."); } $this->assertValidWorkingAggregateState($aggregate2); } catch (AggregateNotFoundException $notFound) { if (!$this->workingAggregate->isDeleted()) { throw new GovernorAssertionError("The working aggregate was not considered deleted, " . "but the Repository cannot recover the state of the " . "aggregate, as it is considered deleted there."); } } catch (\Exception $ex) { $this->logger->warn("An Exception occurred while detecting illegal state changes in {class}.", array('class' => get_class($this->workingAggregate)), $ex); } finally { // rollback to prevent changes bing pushed to event store $uow->rollback(); } } }
/** * * @param TransactionManagerInterface $transactionManager * @return UnitOfWorkInterface */ public static function startAndGet(TransactionManagerInterface $transactionManager = null) { $uow = new DefaultUnitOfWork($transactionManager); $uow->start(); return $uow; }
$logger->pushHandler(new StreamHandler('php://stdout', Logger::DEBUG)); // 1. create a command bus and command gateway $commandBus = new SimpleCommandBus(); $commandBus->setLogger($logger); $commandGateway = new DefaultCommandGateway($commandBus); $rootDirectory = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'CommandHandlerExample'; @mkdir($rootDirectory); echo sprintf("Initializing FileSystemEventStore in %s\n", $rootDirectory); // 2. initialize the event store $eventStore = new FilesystemEventStore(new SimpleEventFileResolver($rootDirectory), new JMSSerializer()); // 3. create the event bus $eventBus = new SimpleEventBus(); $eventBus->setLogger($logger); // 4. create an event sourcing repository $repository = new EventSourcingRepository(User::class, $eventBus, new NullLockManager(), $eventStore, new GenericAggregateFactory(User::class)); //5. create and register our commands $commandHandler = new UserCommandHandler($repository); $commandBus->subscribe('CommandHandlerExample\\CreateUserCommand', $commandHandler); $commandBus->subscribe('CommandHandlerExample\\ChangeUserEmailCommand', $commandHandler); //6. create and register the eventlistener $eventListener = new UserEventListener(); $eventBus->subscribe($eventListener); //7. send commands $aggregateIdentifier = Uuid::uuid1()->toString(); $commandGateway->send(new CreateUserCommand($aggregateIdentifier, '*****@*****.**')); $commandGateway->send(new ChangeUserEmailCommand($aggregateIdentifier, '*****@*****.**')); //8. read back aggregate from store $uow = DefaultUnitOfWork::startAndGet($logger); $aggregate = $repository->load($aggregateIdentifier); echo sprintf("\n\nUser identifier:%s, email:%s, version:%s\n\n", $aggregate->getIdentifier(), $aggregate->getEmail(), $aggregate->getVersion()); $uow->rollback();
public function testUnitOfWorkCleanupDelayedUntilOuterUnitOfWorkIsCleanedUp_InnerCommit_OuterRollback() { $outerListener = \Phake::mock(UnitOfWorkListenerInterface::class); $innerListener = \Phake::mock(UnitOfWorkListenerInterface::class); $outer = DefaultUnitOfWork::startAndGet(); $inner = DefaultUnitOfWork::startAndGet(); $inner->registerListener($innerListener); $outer->registerListener($outerListener); $inner->commit(); \Phake::verify($innerListener, \Phake::never())->afterCommit(\Phake::anyParameters()); \Phake::verify($innerListener, \Phake::never())->onCleanup(\Phake::anyParameters()); $outer->rollback(); \Phake::verify($outerListener, \Phake::never())->onPrepareCommit(\Phake::anyParameters()); \Phake::inOrder(\Phake::verify($innerListener)->onPrepareCommit(\Phake::anyParameters()), \Phake::verify($innerListener)->onRollback(\Phake::anyParameters()), \Phake::verify($outerListener)->onRollback(\Phake::anyParameters()), \Phake::verify($innerListener)->onCleanup(\Phake::anyParameters()), \Phake::verify($outerListener)->onCleanup(\Phake::anyParameters())); }
public function setUp() { $this->mockEventBus = $this->getMock(EventBusInterface::class); $this->testSubject = new MockAbstractRepository(MockAggregateRoot::class, $this->mockEventBus); DefaultUnitOfWork::startAndGet(); }
public function testSendMessageWithPublisherAck_UnitOfWorkCommitted() { $this->testSubject->setTransactional(false); $this->testSubject->setWaitForPublisherAck(true); $this->testSubject->setPublisherAckTimeout(123); $channel = \Phake::mock(AMQPChannel::class); \Phake::when($channel)->wait_for_pending_acks()->thenReturn(null); \Phake::when($this->connection)->channel()->thenReturn($channel); $message = new GenericEventMessage(new Payload("Message")); \Phake::when($this->serializer)->serialize(\Phake::equalTo($message->getPayload()))->thenReturn(new SimpleSerializedObject(json_encode($message->getPayload()), new SimpleSerializedType(Payload::class))); \Phake::when($this->serializer)->serialize(\Phake::equalTo($message->getMetaData()))->thenReturn(new SimpleSerializedObject(json_encode(array('metadata' => array())), new SimpleSerializedType(MetaData::class))); $uow = DefaultUnitOfWork::startAndGet(); $this->testSubject->publish(array($message)); \Phake::verify($channel, \Phake::never())->wait_for_pending_acks(); $uow->commit(); \Phake::verify($channel)->confirm_select(); \Phake::verify($channel)->basic_publish(\Phake::anyParameters()); \Phake::verify($channel)->wait_for_pending_acks(123); }