Skip to content

Commit bbf0fd4

Browse files
committed
Scheduling the same command multiple times for multiple handlers
1 parent aee4875 commit bbf0fd4

File tree

5 files changed

+144
-0
lines changed

5 files changed

+144
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\Ecotone\EventSourcing\Fixture\MultipleAsyncHandlersForOneMessage;
6+
7+
final class ActionCalled
8+
{
9+
public function __construct(public string $id)
10+
{
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\Ecotone\EventSourcing\Fixture\MultipleAsyncHandlersForOneMessage;
6+
7+
final class ActionCommand
8+
{
9+
public function __construct(public string $id)
10+
{
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\Ecotone\EventSourcing\Fixture\MultipleAsyncHandlersForOneMessage;
6+
7+
use Ecotone\Messaging\Attribute\Converter;
8+
9+
final class EventConverter
10+
{
11+
#[Converter]
12+
public function convertFromEvent(ActionCalled $event): array
13+
{
14+
return ['id' => $event->id];
15+
}
16+
17+
#[Converter]
18+
public function convertToEvent(array $payload): ActionCalled
19+
{
20+
return new ActionCalled($payload['id']);
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\Ecotone\EventSourcing\Fixture\MultipleAsyncHandlersForOneMessage;
6+
7+
use Ecotone\Messaging\Attribute\Asynchronous;
8+
use Ecotone\Modelling\Attribute\CommandHandler;
9+
use Ecotone\Modelling\Attribute\EventSourcingAggregate;
10+
use Ecotone\Modelling\Attribute\EventSourcingHandler;
11+
use Ecotone\Modelling\Attribute\Identifier;
12+
use Ecotone\Modelling\WithAggregateVersioning;
13+
14+
#[Asynchronous('testAggregate')]
15+
#[EventSourcingAggregate]
16+
final class TestAggregate
17+
{
18+
use WithAggregateVersioning;
19+
20+
#[Identifier]
21+
private string $id;
22+
23+
private int $counter = 0;
24+
25+
#[CommandHandler(endpointId: 'testAggregate.staticAction')]
26+
public static function staticAction(ActionCommand $command): array
27+
{
28+
return [new ActionCalled($command->id)];
29+
}
30+
31+
#[CommandHandler(endpointId: 'testAggregate.action')]
32+
public function action(ActionCommand $command): array
33+
{
34+
return [new ActionCalled($command->id)];
35+
}
36+
37+
#[EventSourcingHandler]
38+
public function applyActionCalled(ActionCalled $event): void
39+
{
40+
$this->id = $event->id;
41+
++$this->counter;
42+
}
43+
44+
public function counter(): int
45+
{
46+
return $this->counter;
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\Ecotone\EventSourcing\Integration;
6+
7+
use Ecotone\Dbal\Configuration\DbalConfiguration;
8+
use Ecotone\Dbal\DbalBackedMessageChannelBuilder;
9+
use Ecotone\EventSourcing\EventSourcingConfiguration;
10+
use Ecotone\Lite\EcotoneLite;
11+
use Ecotone\Messaging\Config\ModulePackageList;
12+
use Ecotone\Messaging\Config\ServiceConfiguration;
13+
use Ecotone\Messaging\Endpoint\ExecutionPollingMetadata;
14+
use Enqueue\Dbal\DbalConnectionFactory;
15+
use Test\Ecotone\EventSourcing\EventSourcingMessagingTestCase;
16+
use Test\Ecotone\EventSourcing\Fixture\MultipleAsyncHandlersForOneMessage\ActionCommand;
17+
use Test\Ecotone\EventSourcing\Fixture\MultipleAsyncHandlersForOneMessage\EventConverter;
18+
use Test\Ecotone\EventSourcing\Fixture\MultipleAsyncHandlersForOneMessage\TestAggregate;
19+
20+
final class MultipleAsyncHandlersForOneMessageTest extends EventSourcingMessagingTestCase
21+
{
22+
public function test_handling_multiple_same_messages(): void
23+
{
24+
$ecotone = EcotoneLite::bootstrapFlowTestingWithEventStore(
25+
classesToResolve: [TestAggregate::class, EventConverter::class],
26+
containerOrAvailableServices: [
27+
new EventConverter(),
28+
DbalConnectionFactory::class => self::getConnectionFactory(),
29+
],
30+
configuration: ServiceConfiguration::createWithDefaults()
31+
->withSkippedModulePackageNames(ModulePackageList::allPackagesExcept([ModulePackageList::EVENT_SOURCING_PACKAGE, ModulePackageList::ASYNCHRONOUS_PACKAGE]))
32+
->withNamespaces(['Test\Ecotone\Modelling\Fixture\MultipleAsyncHandlersForOneMessage'])
33+
->withExtensionObjects([
34+
DbalConfiguration::createWithDefaults(),
35+
EventSourcingConfiguration::createWithDefaults(),
36+
DbalBackedMessageChannelBuilder::create("testAggregate"),
37+
]),
38+
runForProductionEventStore: true
39+
);
40+
41+
$ecotone->sendCommand(new ActionCommand('123'));
42+
$ecotone->sendCommand(new ActionCommand('123'));
43+
44+
$ecotone->run('testAggregate', ExecutionPollingMetadata::createWithTestingSetup());
45+
self::assertEquals(1, $ecotone->getAggregate(TestAggregate::class, '123')->counter());
46+
47+
$ecotone->run('testAggregate', ExecutionPollingMetadata::createWithTestingSetup());
48+
self::assertEquals(2, $ecotone->getAggregate(TestAggregate::class, '123')->counter());
49+
}
50+
}

0 commit comments

Comments
 (0)