Skip to content

Commit

Permalink
update event version by reconstituting from event
Browse files Browse the repository at this point in the history
  • Loading branch information
juliangut committed Sep 26, 2019
1 parent 4a1e8e6 commit 5acf19d
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 177 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,13 @@ Both of these methods will create an Aggregate Event that will be eventually per
### Aggregate Repository



### Event Store


#### Concurrency

### Snapshot Store

### Snapshot Store


## Contributing
Expand Down
2 changes: 0 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
"prefer-stable": true,
"require": {
"php": "^7.1",
"ext-json": "*",
"myclabs/deep-copy": "^1.8",
"phpgears/aggregate": "~0.2"
},
"require-dev": {
Expand Down
30 changes: 21 additions & 9 deletions src/Aggregate/AbstractAggregateRoot.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Gears\Aggregate\EventBehaviour;
use Gears\EventSourcing\Aggregate\Exception\AggregateException;
use Gears\EventSourcing\Aggregate\Exception\AggregateVersionException;
use Gears\EventSourcing\Event\AggregateEvent;
use Gears\EventSourcing\Event\AggregateEventIteratorStream;
use Gears\EventSourcing\Event\AggregateEventStream;
Expand Down Expand Up @@ -71,25 +72,25 @@ final public static function reconstituteFromEventStream(AggregateEventStream $e
/**
* {@inheritdoc}
*
* @throws AggregateException
* @throws AggregateVersionException
*/
final public function replayAggregateEventStream(AggregateEventStream $eventStream): void
{
foreach ($eventStream as $event) {
$aggregateVersion = $event->getAggregateVersion();

if (!$aggregateVersion->isEqualTo($this->version->getNext())) {
throw new AggregateException(\sprintf(
throw new AggregateVersionException(\sprintf(
'Aggregate event "%s" cannot be replayed, event version is "%s" and aggregate is "%s"',
\get_class($event),
$aggregateVersion->getValue(),
$this->version->getValue()
));
}

$this->version = $aggregateVersion;

$this->applyAggregateEvent($event);

$this->version = $aggregateVersion;
}
}

Expand All @@ -98,23 +99,34 @@ final public function replayAggregateEventStream(AggregateEventStream $eventStre
*
* @param AggregateEvent $event
*
* @throws AggregateException
* @throws AggregateVersionException
*/
final protected function recordAggregateEvent(AggregateEvent $event): void
{
if (!$event->getAggregateVersion()->isEqualTo(new AggregateVersion(0))) {
throw new AggregateException(\sprintf(
throw new AggregateVersionException(\sprintf(
'Only new aggregate events can be recorded, event "%s" with version "%s" given',
\get_class($event),
$event->getAggregateVersion()->getValue()
));
}

$this->version = $this->version->getNext();
$this->applyAggregateEvent($event);

$this->recordedAggregateEvents->append($event->withAggregateVersion($this->version));
$this->version = $this->version->getNext();

$this->applyAggregateEvent($event);
/** @var AggregateEvent $recordedEvent */
$recordedEvent = $event::reconstitute(
$event->getPayload(),
[
'aggregateId' => $event->getAggregateId(),
'aggregateVersion' => $this->version,
'metadata' => $event->getMetadata(),
'createdAt' => $event->getCreatedAt(),
]
);

$this->recordedAggregateEvents->append($recordedEvent);
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/Aggregate/AggregateVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Gears\EventSourcing\Aggregate;

use Gears\EventSourcing\Aggregate\Exception\AggregateException;
use Gears\EventSourcing\Aggregate\Exception\AggregateVersionException;

final class AggregateVersion
{
Expand All @@ -27,12 +27,12 @@ final class AggregateVersion
*
* @param int $value
*
* @throws AggregateException
* @throws AggregateVersionException
*/
public function __construct(int $value)
{
if ($value < 0) {
throw new AggregateException(\sprintf('Version value should be higher than 0, "%s" given', $value));
throw new AggregateVersionException(\sprintf('Version value should be higher than 0, "%s" given', $value));
}

$this->value = $value;
Expand Down Expand Up @@ -76,14 +76,14 @@ public function getNext(): self
/**
* Get previous version.
*
* @throws AggregateException
* @throws AggregateVersionException
*
* @return AggregateVersion
*/
public function getPrevious(): self
{
if ($this->value === 0) {
throw new AggregateException('Version value cannot be lowered below 0');
throw new AggregateVersionException('Version value cannot be lowered below 0');
}

$clone = clone $this;
Expand Down
18 changes: 18 additions & 0 deletions src/Aggregate/Exception/AggregateVersionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* event-sourcing (https://github.com/phpgears/event-sourcing).
* Event Sourcing base.
*
* @license MIT
* @link https://github.com/phpgears/event-sourcing
* @author Julián Gutiérrez <juliangut@gmail.com>
*/

declare(strict_types=1);

namespace Gears\EventSourcing\Aggregate\Exception;

class AggregateVersionException extends \RuntimeException
{
}
7 changes: 6 additions & 1 deletion src/Event/AbstractAggregateEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ final protected static function occurred(Identity $aggregateId, array $payload,
*/
final public static function reconstitute(array $payload, array $attributes = [])
{
$event = new static($attributes['aggregateId'], $payload, $attributes['metadata'], $attributes['createdAt']);
$event = new static(
$attributes['aggregateId'],
$payload,
$attributes['metadata'],
$attributes['createdAt']
);
$event->version = $attributes['aggregateVersion'];

return $event;
Expand Down
11 changes: 0 additions & 11 deletions src/Event/AggregateEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,4 @@ public function getAggregateId(): Identity;
* @return AggregateVersion
*/
public function getAggregateVersion(): AggregateVersion;

/**
* Get event with new aggregate version.
*
* @param AggregateVersion $aggregateVersion
*
* @throws \Gears\Event\Exception\EventException
*
* @return mixed|self
*/
public function withAggregateVersion(AggregateVersion $aggregateVersion);
}
36 changes: 0 additions & 36 deletions src/Event/AggregateEventBehaviour.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@
namespace Gears\EventSourcing\Event;

use Gears\Event\EventBehaviour;
use Gears\Event\Exception\EventException;
use Gears\EventSourcing\Aggregate\AggregateBehaviour;
use Gears\EventSourcing\Aggregate\AggregateVersion;
use Gears\Identity\Identity;

use function DeepCopy\deep_copy;

/**
* Aggregate event behaviour.
*/
Expand Down Expand Up @@ -50,37 +47,4 @@ final public function getAggregateVersion(): AggregateVersion
{
return $this->version;
}

/**
* Get event with new aggregate version.
*
* @param AggregateVersion $aggregateVersion
*
* @throws \Gears\Event\Exception\EventException
*
* @return mixed|self
*/
final public function withAggregateVersion(AggregateVersion $aggregateVersion)
{
if (!$this->version->isEqualTo(new AggregateVersion(0))) {
throw new EventException(\sprintf(
'Only new events can get a new version, event "%s" already at version "%s"',
\get_class($this),
$this->version->getValue()
));
}

if ($aggregateVersion->isEqualTo(new AggregateVersion(0))) {
throw new EventException(\sprintf(
'Aggregate events can not get version 0 set, version "0" given to event "%s"',
\get_class($this)
));
}

/* @var self $self */
$self = deep_copy($this);
$self->version = $aggregateVersion;

return $self;
}
}
11 changes: 4 additions & 7 deletions tests/EventSourcing/Aggregate/AbstractAggregateRootTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Gears\EventSourcing\Aggregate\AggregateVersion;
use Gears\EventSourcing\Aggregate\Exception\AggregateException;
use Gears\EventSourcing\Aggregate\Exception\AggregateVersionException;
use Gears\EventSourcing\Event\AggregateEvent;
use Gears\EventSourcing\Event\AggregateEventArrayStream;
use Gears\EventSourcing\Tests\Stub\AbstractAggregateEventStub;
Expand All @@ -29,7 +30,7 @@ class AbstractAggregateRootTest extends TestCase
{
public function testInvalidEventApply(): void
{
$this->expectException(AggregateException::class);
$this->expectException(AggregateVersionException::class);
$this->expectExceptionMessageRegExp(
'/^Only new aggregate events can be recorded, event .+ with version "10" given$/'
);
Expand All @@ -55,10 +56,6 @@ public function testNoApplyHandler(): void
$aggregateEvent->expects(static::any())
->method('getAggregateVersion')
->will(static::returnValue(new AggregateVersion(0)));
$aggregateEvent->expects(static::any())
->method('withAggregateVersion')
->will(static::returnSelf());

/* @var AggregateEvent $aggregateEvent */

AbstractAggregateRootStub::instantiateWithEvent($aggregateEvent);
Expand All @@ -84,7 +81,7 @@ public function testRecordedAggregateEvents(): void
static::assertCount(1, $recordedAggregateEvents);

static::assertEquals(
[$aggregateEvent->withAggregateVersion(new AggregateVersion(1))],
[AbstractAggregateEventStub::withVersion($aggregateEvent, new AggregateVersion(1))],
\iterator_to_array($recordedAggregateEvents)
);
}
Expand All @@ -101,7 +98,7 @@ public function testReconstituteFromEmptyStream(): void

public function testReconstituteFromInvalidEvent(): void
{
$this->expectException(AggregateException::class);
$this->expectException(AggregateVersionException::class);
$this->expectExceptionMessageRegExp(
'/^Aggregate event .+ cannot be replayed, event version is "10" and aggregate is "0"$/'
);
Expand Down
6 changes: 3 additions & 3 deletions tests/EventSourcing/Aggregate/AggregateVersionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace Gears\EventSourcing\Tests\Aggregate;

use Gears\EventSourcing\Aggregate\AggregateVersion;
use Gears\EventSourcing\Aggregate\Exception\AggregateException;
use Gears\EventSourcing\Aggregate\Exception\AggregateVersionException;
use PHPUnit\Framework\TestCase;

/**
Expand All @@ -24,7 +24,7 @@ class AggregateVersionTest extends TestCase
{
public function testInvalidValue(): void
{
$this->expectException(AggregateException::class);
$this->expectException(AggregateVersionException::class);
$this->expectExceptionMessage('Version value should be higher than 0, "-1" given');

new AggregateVersion(-1);
Expand All @@ -49,7 +49,7 @@ public function testGetNext(): void

public function testInvalidPrevious(): void
{
$this->expectException(AggregateException::class);
$this->expectException(AggregateVersionException::class);
$this->expectExceptionMessage('Version value cannot be lowered below 0');

$version = new AggregateVersion(0);
Expand Down
35 changes: 1 addition & 34 deletions tests/EventSourcing/Event/AbstractAggregateEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

namespace Gears\EventSourcing\Tests\Event;

use Gears\Event\Exception\EventException;
use Gears\EventSourcing\Aggregate\AggregateVersion;
use Gears\EventSourcing\Tests\Stub\AbstractAggregateEventStub;
use Gears\Identity\UuidIdentity;
Expand Down Expand Up @@ -69,45 +68,13 @@ public function testMetadata(): void
static::assertEquals(['userId' => '123456'], $newAggregateEvent->getMetadata());
}

public function testNoNewVersion(): void
{
$this->expectException(EventException::class);
$this->expectExceptionMessageRegExp(
'/^Only new events can get a new version, event ".+" already at version "10"$/'
);

$aggregateEvent = AbstractAggregateEventStub::instance(
UuidIdentity::fromString('3247cb6e-e9c7-4f3a-9c6c-0dec26a0353f')
);

$newAggregateEvent = $aggregateEvent->withAggregateVersion(new AggregateVersion(10));

static::assertEquals(10, $newAggregateEvent->getAggregateVersion()->getValue());

$newAggregateEvent->withAggregateVersion(new AggregateVersion(20));
}

public function testNoNewVersionZero(): void
{
$this->expectException(EventException::class);
$this->expectExceptionMessageRegExp(
'/^Aggregate events can not get version 0 set, version "0" given to event ".+"$/'
);

$aggregateEvent = AbstractAggregateEventStub::instance(
UuidIdentity::fromString('3247cb6e-e9c7-4f3a-9c6c-0dec26a0353f')
);

$aggregateEvent->withAggregateVersion(new AggregateVersion(0));
}

public function testNewVersion(): void
{
$aggregateEvent = AbstractAggregateEventStub::instance(
UuidIdentity::fromString('3247cb6e-e9c7-4f3a-9c6c-0dec26a0353f')
);

$newAggregateEvent = $aggregateEvent->withAggregateVersion(new AggregateVersion(10));
$newAggregateEvent = AbstractAggregateEventStub::withVersion($aggregateEvent, new AggregateVersion(10));

static::assertNotSame($aggregateEvent, $newAggregateEvent);
static::assertEquals(10, $newAggregateEvent->getAggregateVersion()->getValue());
Expand Down
Loading

0 comments on commit 5acf19d

Please sign in to comment.