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()); }
/** * @CommandHandler */ public function handleStrangeCommand(StrangeCommand $testCommand) { $aggregate = $this->repository->load($testCommand->getAggregateIdentifier(), null); $aggregate->doSomething(); $this->eventBus->publish(new GenericEventMessage(new MyApplicationEvent())); CurrentUnitOfWork::get()->publishEvent(new GenericEventMessage(new MyApplicationEvent()), $this->eventBus); throw new StrangeCommandReceivedException("Strange command received"); }
public function testSetSession() { $mockUnitOfWork = $this->getMock(UnitOfWorkInterface::class); CurrentUnitOfWork::set($mockUnitOfWork); $this->assertSame($mockUnitOfWork, CurrentUnitOfWork::get()); CurrentUnitOfWork::clear($mockUnitOfWork); $this->assertFalse(CurrentUnitOfWork::isStarted()); }
public function add(AggregateRootInterface $aggregateRoot) { if (null !== $aggregateRoot->getVersion()) { throw new \InvalidArgumentException("Only newly created (unpersisted) aggregates may be added."); } if (!$this->supportsClass(get_class($aggregateRoot))) { throw new \InvalidArgumentException(sprintf("This repository supports %s, but got %s", $this->className, get_class($aggregateRoot))); } CurrentUnitOfWork::get()->registerAggregate($aggregateRoot, $this->eventBus, $this->saveAggregateCallback); }
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 publish(array $events) { if (null === $this->connection) { throw new \RuntimeException("The AMQPTerminal has no connection configured."); } $channel = $this->connection->channel(); if ($this->isTransactional) { $channel->tx_select(); } try { if ($this->waitForAck) { $channel->confirm_select(); } foreach ($events as $event) { $amqpMessage = $this->messageConverter->createAmqpMessage($event); $this->doSendMessage($channel, $amqpMessage); } if (CurrentUnitOfWork::isStarted()) { CurrentUnitOfWork::get()->registerListener(new ChannelTransactionUnitOfWorkListener($this->logger, $channel, $this)); } elseif ($this->isTransactional) { $channel->tx_commit(); } elseif ($this->waitForAck) { $channel->wait_for_pending_acks($this->publisherAckTimeout); } } catch (\Exception $ex) { if ($this->isTransactional) { $this->tryRollback($channel); } throw new EventPublicationFailedException("Failed to dispatch Events to the Message Broker.", 0, $ex); } finally { if (!CurrentUnitOfWork::isStarted()) { $this->tryClose($channel); } } }
public function testDispatchCommand_ImplicitUnitOfWorkIsRolledBackOnException() { $command = new TestCommand("Say hi!"); $test = $this; $this->handlerRegistry->subscribe(TestCommand::class, new CallbackCommandHandler(function (CommandMessageInterface $commandMessage, UnitOfWorkInterface $unitOfWork) use($test) { $test->assertTrue(CurrentUnitOfWork::isStarted()); $test->assertNotNull(CurrentUnitOfWork::get()); throw new \RuntimeException("exception"); })); $callback = new ClosureCommandCallback(function ($result) use($command) { $this->fail("Did not expect exception"); }, function ($exception) { $this->assertEquals(\RuntimeException::class, get_class($exception)); }); $this->commandBus->dispatch(GenericCommandMessage::asCommandMessage($command), $callback); $this->assertFalse(CurrentUnitOfWork::isStarted()); }
public function tearDown() { while (CurrentUnitOfWork::isStarted()) { CurrentUnitOfWork::get()->rollback(); } }
public function testLoadAndSaveWithoutConflictingChanges() { $conflictResolver = $this->getMock('Governor\\Framework\\EventSourcing\\ConflictResolverInterface'); $identifier = Uuid::uuid1()->toString(); $event2 = new GenericDomainEventMessage($identifier, 2, new \stdClass(), MetaData::emptyInstance()); $event3 = new GenericDomainEventMessage($identifier, 3, new \stdClass(), MetaData::emptyInstance()); $this->mockEventStore->expects($this->once())->method('readEvents')->with($this->identicalTo("test"), $this->identicalTo($identifier))->will($this->returnValue(new SimpleDomainEventStream(array(new GenericDomainEventMessage($identifier, 1, new \stdClass()), $event2, $event3)))); $this->testSubject->setConflictResolver($conflictResolver); $actual = $this->testSubject->load($identifier, 3); $conflictResolver->expects($this->never())->method('resolveConflicts'); $actual->apply(new StubDomainEvent()); $conflictResolver->expects($this->never())->method('resolveConflicts'); CurrentUnitOfWork::commit(); }
public function testInnerUnitOfWorkCommittedBackWithOuter() { $isCommitted = false; $outer = DefaultUnitOfWork::startAndGet(); $inner = DefaultUnitOfWork::startAndGet(); $inner->registerListener(new AfterCommitTestAdapter(function (UnitOfWorkInterface $uow) use(&$isCommitted) { $isCommitted = true; })); $inner->commit(); $this->assertFalse($isCommitted, "The inner UoW was committed prematurely"); $outer->commit(); $this->assertTrue($isCommitted, "The inner UoW wasn't properly committed"); $this->assertFalse(CurrentUnitOfWork::isStarted(), "The UnitOfWork haven't been correctly cleared"); }
protected function doLoad($id, $expectedVersion) { try { $events = $this->eventStore->readEvents($this->getTypeIdentifier(), $id); } catch (EventStreamNotFoundException $ex) { throw new AggregateNotFoundException($id, "The aggregate was not found", $ex); } foreach ($this->eventStreamDecorators as $decorator) { $events = $decorator->decorateForRead($this->getTypeIdentifier(), $id, $events); } $aggregate = $this->factory->createAggregate($id, $events->peek()); $unseenEvents = array(); $aggregate->initializeState(new CapturingEventStream($events, $unseenEvents, $expectedVersion)); if ($aggregate->isDeleted()) { throw new AggregateDeletedException($id); } CurrentUnitOfWork::get()->registerListener(new ConflictResolvingListener($aggregate, $unseenEvents, $this->conflictResolver)); return $aggregate; }