-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
remove the headers once they are propagated
in case of asynchronous projection when first event has a header which does not exist in the next one, header will remain
- Loading branch information
1 parent
97e54e8
commit 94d09f4
Showing
10 changed files
with
255 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
packages/PdoEventSourcing/tests/Fixture/MetadataPropagationWithAsyncProjection/Order.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection; | ||
|
||
use Ecotone\Modelling\Attribute\AggregateIdentifier; | ||
use Ecotone\Modelling\Attribute\CommandHandler; | ||
use Ecotone\Modelling\Attribute\EventSourcingAggregate; | ||
use Ecotone\Modelling\Attribute\EventSourcingHandler; | ||
use Ecotone\Modelling\WithAggregateVersioning; | ||
|
||
#[EventSourcingAggregate] | ||
final class Order | ||
{ | ||
use WithAggregateVersioning; | ||
|
||
#[AggregateIdentifier] | ||
private int $id; | ||
|
||
#[CommandHandler(routingKey: 'order.create')] | ||
public static function create(int $id): array | ||
{ | ||
return [new OrderCreated($id), new ProductAddedToOrder($id)]; | ||
} | ||
|
||
#[EventSourcingHandler] | ||
public function applyOrderCreated(OrderCreated $event): void | ||
{ | ||
$this->id = $event->id; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...es/PdoEventSourcing/tests/Fixture/MetadataPropagationWithAsyncProjection/OrderCreated.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection; | ||
|
||
use Ecotone\Modelling\Attribute\NamedEvent; | ||
|
||
#[NamedEvent('order.created')] | ||
final class OrderCreated | ||
{ | ||
public function __construct(public int $id) | ||
{ | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
...entSourcing/tests/Fixture/MetadataPropagationWithAsyncProjection/OrderEventsConverter.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection; | ||
|
||
use Ecotone\Messaging\Attribute\Converter; | ||
|
||
final class OrderEventsConverter | ||
{ | ||
#[Converter] | ||
public function convertFromOrderCreated(OrderCreated $event): array | ||
{ | ||
return ['id' => $event->id]; | ||
} | ||
|
||
#[Converter] | ||
public function convertToOrderCreated(array $payload): OrderCreated | ||
{ | ||
return new OrderCreated($payload['id']); | ||
} | ||
|
||
#[Converter] | ||
public function convertFromProductAddedToOrder(ProductAddedToOrder $event): array | ||
{ | ||
return ['id' => $event->id]; | ||
} | ||
|
||
#[Converter] | ||
public function convertToProductAddedToOrder(array $payload): ProductAddedToOrder | ||
{ | ||
return new ProductAddedToOrder($payload['id']); | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
...PdoEventSourcing/tests/Fixture/MetadataPropagationWithAsyncProjection/OrderProjection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection; | ||
|
||
use Doctrine\DBAL\Connection; | ||
use Ecotone\EventSourcing\Attribute\Projection; | ||
use Ecotone\EventSourcing\Attribute\ProjectionInitialization; | ||
use Ecotone\Messaging\Attribute\Asynchronous; | ||
use Ecotone\Modelling\Attribute\EventHandler; | ||
use Ecotone\Modelling\Attribute\QueryHandler; | ||
|
||
#[Asynchronous(channelName: self::CHANNEL)] | ||
#[Projection(name: self::NAME, fromStreams: [Order::class])] | ||
final class OrderProjection | ||
{ | ||
public const CHANNEL = 'projection_channel'; | ||
public const NAME = 'order_projection'; | ||
public const TABLE = 'foo_orders'; | ||
|
||
public function __construct(private Connection $connection) | ||
{ | ||
} | ||
|
||
#[ProjectionInitialization] | ||
public function initialization(): void | ||
{ | ||
$this->connection->executeStatement(sprintf('CREATE TABLE IF NOT EXISTS %s (id INT PRIMARY KEY, foo INT DEFAULT 0)', self::TABLE)); | ||
} | ||
|
||
#[EventHandler(listenTo: 'order.created', endpointId: 'foo_orders.order_created')] | ||
public function whenOrderCreated(OrderCreated $event, array $metadata): void | ||
{ | ||
$data = ['id' => $event->id]; | ||
if (array_key_exists('foo', $metadata)) { | ||
$data['foo'] = 1; | ||
} | ||
|
||
$this->connection->insert(self::TABLE, $data); | ||
} | ||
|
||
#[EventHandler(listenTo: 'order.product_added', endpointId: 'foo_orders.product_added')] | ||
public function whenProductAddedToOrder(ProductAddedToOrder $event, array $metadata): void | ||
{ | ||
if (array_key_exists('foo', $metadata)) { | ||
$this->connection->executeStatement(sprintf('UPDATE %s SET foo = foo + 1 WHERE id = ?', self::TABLE), [$event->id]); | ||
} | ||
} | ||
|
||
#[QueryHandler(routingKey: 'foo_orders.count')] | ||
public function fooOrdersCount(): int | ||
{ | ||
return (int) $this->connection->fetchOne(sprintf('SELECT SUM(foo) FROM %s', self::TABLE)); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
...ntSourcing/tests/Fixture/MetadataPropagationWithAsyncProjection/OrderProjectionConfig.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection; | ||
|
||
use Ecotone\EventSourcing\ProjectionRunningConfiguration; | ||
use Ecotone\Messaging\Attribute\ServiceContext; | ||
use Ecotone\Messaging\Channel\SimpleMessageChannelBuilder; | ||
use Prooph\EventStore\Pdo\Projection\PdoEventStoreReadModelProjector; | ||
use Prooph\EventStore\Projection\ReadModelProjector; | ||
|
||
class OrderProjectionConfig | ||
{ | ||
#[ServiceContext] | ||
public function eventDrivenAuditPlanActionLogProjection(): ProjectionRunningConfiguration | ||
{ | ||
return ProjectionRunningConfiguration::createEventDriven(OrderProjection::NAME) | ||
->withOption(PdoEventStoreReadModelProjector::OPTION_LOAD_COUNT, 100) | ||
->withOption(ReadModelProjector::OPTION_PERSIST_BLOCK_SIZE, 100) | ||
; | ||
} | ||
|
||
#[ServiceContext] | ||
public function simpleAuditPlanActionLogProjectionChannel(): SimpleMessageChannelBuilder | ||
{ | ||
return SimpleMessageChannelBuilder::createQueueChannel(OrderProjection::CHANNEL); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...ventSourcing/tests/Fixture/MetadataPropagationWithAsyncProjection/ProductAddedToOrder.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection; | ||
|
||
use Ecotone\Modelling\Attribute\NamedEvent; | ||
|
||
#[NamedEvent('order.product_added')] | ||
final class ProductAddedToOrder | ||
{ | ||
public function __construct(public int $id) | ||
{ | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
packages/PdoEventSourcing/tests/Integration/AsyncProjectionMetadataPropagationTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Test\Ecotone\EventSourcing\Integration; | ||
|
||
use Ecotone\Lite\EcotoneLite; | ||
use Ecotone\Messaging\Config\ModulePackageList; | ||
use Ecotone\Messaging\Config\ServiceConfiguration; | ||
use Ecotone\Messaging\Endpoint\ExecutionPollingMetadata; | ||
use Enqueue\Dbal\DbalConnectionFactory; | ||
use Ramsey\Uuid\Uuid; | ||
use Test\Ecotone\EventSourcing\EventSourcingMessagingTest; | ||
use Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection\OrderEventsConverter; | ||
use Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection\OrderProjection; | ||
|
||
final class AsyncProjectionMetadataPropagationTest extends EventSourcingMessagingTest | ||
{ | ||
public function test_metadata_propagation_with_async_projection(): void | ||
{ | ||
/** @var DbalConnectionFactory $connectionFactory */ | ||
$connectionFactory = $this->getConnectionFactory(); | ||
$connection = $connectionFactory->createContext()->getDbalConnection(); | ||
$schemaManager = $connection->createSchemaManager(); | ||
if ($schemaManager->tablesExist(names: OrderProjection::TABLE)) { | ||
$schemaManager->dropTable(name: OrderProjection::TABLE); | ||
} | ||
|
||
$ecotoneLite = EcotoneLite::bootstrapFlowTesting( | ||
containerOrAvailableServices: [new OrderProjection($connection), new OrderEventsConverter(), DbalConnectionFactory::class => $connectionFactory], | ||
configuration: ServiceConfiguration::createWithDefaults() | ||
->withSkippedModulePackageNames(ModulePackageList::allPackagesExcept([ModulePackageList::EVENT_SOURCING_PACKAGE, ModulePackageList::DBAL_PACKAGE, ModulePackageList::ASYNCHRONOUS_PACKAGE])) | ||
->withNamespaces(['Test\Ecotone\EventSourcing\Fixture\MetadataPropagationWithAsyncProjection']), | ||
pathToRootCatalog: __DIR__ . "/../../", | ||
addEventSourcedRepository: false | ||
); | ||
|
||
$ecotoneLite->sendCommandWithRoutingKey(routingKey: 'order.create', command: 1, metadata: ['foo' => 'bar']); | ||
$ecotoneLite->sendCommandWithRoutingKey(routingKey: 'order.create', command: 2); | ||
$ecotoneLite->sendCommandWithRoutingKey(routingKey: 'order.create', command: 3, metadata: ['foo' => 'baz']); | ||
|
||
$ecotoneLite->run(name: OrderProjection::CHANNEL, executionPollingMetadata: ExecutionPollingMetadata::createWithTestingSetup()->withHandledMessageLimit(2)); | ||
|
||
self::assertEquals(expected: 4, actual: $ecotoneLite->sendQueryWithRouting('foo_orders.count')); | ||
} | ||
} |