@@ 24-125 (lines=102) @@ | ||
21 | use Gica\Cqrs\Scheduling\ScheduledCommand; |
|
22 | use Gica\Types\Guid; |
|
23 | ||
24 | class DefaultCommandTester implements CommandTester |
|
25 | { |
|
26 | /** |
|
27 | * @var CommandSubscriber |
|
28 | */ |
|
29 | private $commandSubscriber; |
|
30 | /** |
|
31 | * @var CommandApplier |
|
32 | */ |
|
33 | private $commandApplier; |
|
34 | /** |
|
35 | * @var AggregateRepository |
|
36 | */ |
|
37 | private $aggregateRepository; |
|
38 | /** |
|
39 | * @var EventsApplierOnAggregate |
|
40 | */ |
|
41 | private $eventsApplierOnAggregate; |
|
42 | /** |
|
43 | * @var EventMetadataFactory |
|
44 | */ |
|
45 | private $eventMetadataFactory; |
|
46 | /** |
|
47 | * @var CommandMetadataFactory |
|
48 | */ |
|
49 | private $commandMetadataFactory; |
|
50 | ||
51 | public function __construct( |
|
52 | CommandSubscriber $commandSubscriber, |
|
53 | CommandApplier $commandApplier, |
|
54 | AggregateRepository $aggregateRepository, |
|
55 | EventsApplierOnAggregate $eventsApplier, |
|
56 | EventMetadataFactory $eventMetadataFactory, |
|
57 | CommandMetadataFactory $commandMetadataFactory |
|
58 | ) |
|
59 | { |
|
60 | $this->commandSubscriber = $commandSubscriber; |
|
61 | $this->commandApplier = $commandApplier; |
|
62 | $this->aggregateRepository = $aggregateRepository; |
|
63 | $this->eventsApplierOnAggregate = $eventsApplier; |
|
64 | $this->eventMetadataFactory = $eventMetadataFactory; |
|
65 | $this->commandMetadataFactory = $commandMetadataFactory; |
|
66 | } |
|
67 | ||
68 | public function canExecuteCommand(Command $command): bool |
|
69 | { |
|
70 | try { |
|
71 | $command = $this->commandMetadataFactory->wrapCommandWithMetadata($command, null); |
|
72 | $this->applyCommand($command, $this->loadCommandHandlerAndAggregate($command)); |
|
73 | return true; |
|
74 | } catch (\Exception $exception) { |
|
75 | return false; |
|
76 | } |
|
77 | } |
|
78 | ||
79 | private function loadCommandHandlerAndAggregate(CommandWithMetadata $command): CommandHandlerAndAggregate |
|
80 | { |
|
81 | return new CommandHandlerAndAggregate( |
|
82 | $this->commandSubscriber->getHandlerForCommand($command->getCommand()), |
|
83 | $this->aggregateRepository->loadAggregate($this->commandSubscriber->getHandlerForCommand($command->getCommand())->getHandlerClass(), $command->getAggregateId()) |
|
84 | ); |
|
85 | } |
|
86 | ||
87 | private function decorateEventWithMetaData($event, MetaData $metaData): EventWithMetaData |
|
88 | { |
|
89 | return new EventWithMetaData($event, $metaData->withEventId(Guid::generate())); |
|
90 | } |
|
91 | ||
92 | /** |
|
93 | * @param CommandWithMetadata $command |
|
94 | * @param CommandHandlerAndAggregate $handlerAndAggregate |
|
95 | * @return void |
|
96 | */ |
|
97 | private function applyCommand(CommandWithMetadata $command, CommandHandlerAndAggregate $handlerAndAggregate) |
|
98 | { |
|
99 | $aggregate = $handlerAndAggregate->getAggregate(); |
|
100 | $handler = $handlerAndAggregate->getCommandHandler(); |
|
101 | ||
102 | $metaData = $this->eventMetadataFactory->factoryEventMetadata($command, $aggregate); |
|
103 | ||
104 | $newMessageGenerator = $this->commandApplier->applyCommand($aggregate, $command->getCommand(), $handler->getMethodName()); |
|
105 | ||
106 | foreach ($newMessageGenerator as $message) { |
|
107 | if (!$this->isScheduledCommand($message)) { |
|
108 | $eventWithMetaData = $this->decorateEventWithMetaData($message, $metaData); |
|
109 | if (!$this->isScheduledEvent($message)) { |
|
110 | $this->eventsApplierOnAggregate->applyEventsOnAggregate($aggregate, [$eventWithMetaData]); |
|
111 | } |
|
112 | } |
|
113 | } |
|
114 | } |
|
115 | ||
116 | private function isScheduledEvent($event): bool |
|
117 | { |
|
118 | return $event instanceof ScheduledEvent; |
|
119 | } |
|
120 | ||
121 | private function isScheduledCommand($message): bool |
|
122 | { |
|
123 | return $message instanceof ScheduledCommand; |
|
124 | } |
|
125 | } |
@@ 24-124 (lines=101) @@ | ||
21 | use Gica\Cqrs\Scheduling\ScheduledCommand; |
|
22 | use Gica\Types\Guid; |
|
23 | ||
24 | class DefaultCommandTesterWithSideEffect implements CommandTesterWithSideEffect |
|
25 | { |
|
26 | /** |
|
27 | * @var CommandSubscriber |
|
28 | */ |
|
29 | private $commandSubscriber; |
|
30 | /** |
|
31 | * @var CommandApplier |
|
32 | */ |
|
33 | private $commandApplier; |
|
34 | /** |
|
35 | * @var AggregateRepository |
|
36 | */ |
|
37 | private $aggregateRepository; |
|
38 | /** |
|
39 | * @var EventsApplierOnAggregate |
|
40 | */ |
|
41 | private $eventsApplierOnAggregate; |
|
42 | /** |
|
43 | * @var EventMetadataFactory |
|
44 | */ |
|
45 | private $eventMetadataFactory; |
|
46 | /** |
|
47 | * @var CommandMetadataFactory |
|
48 | */ |
|
49 | private $commandMetadataFactory; |
|
50 | ||
51 | public function __construct( |
|
52 | CommandSubscriber $commandSubscriber, |
|
53 | CommandApplier $commandApplier, |
|
54 | AggregateRepository $aggregateRepository, |
|
55 | EventsApplierOnAggregate $eventsApplier, |
|
56 | EventMetadataFactory $eventMetadataFactory, |
|
57 | CommandMetadataFactory $commandMetadataFactory |
|
58 | ) |
|
59 | { |
|
60 | $this->commandSubscriber = $commandSubscriber; |
|
61 | $this->commandApplier = $commandApplier; |
|
62 | $this->aggregateRepository = $aggregateRepository; |
|
63 | $this->eventsApplierOnAggregate = $eventsApplier; |
|
64 | $this->eventMetadataFactory = $eventMetadataFactory; |
|
65 | $this->commandMetadataFactory = $commandMetadataFactory; |
|
66 | } |
|
67 | ||
68 | public function shouldExecuteCommand(Command $command): bool |
|
69 | { |
|
70 | $command = $this->commandMetadataFactory->wrapCommandWithMetadata($command, null); |
|
71 | return $this->applyCommand($command, $this->loadCommandHandlerAndAggregate($command)); |
|
72 | } |
|
73 | ||
74 | private function loadCommandHandlerAndAggregate(CommandWithMetadata $command): CommandHandlerAndAggregate |
|
75 | { |
|
76 | return new CommandHandlerAndAggregate( |
|
77 | $this->commandSubscriber->getHandlerForCommand($command->getCommand()), |
|
78 | $this->aggregateRepository->loadAggregate($this->commandSubscriber->getHandlerForCommand($command->getCommand())->getHandlerClass(), $command->getAggregateId()) |
|
79 | ); |
|
80 | } |
|
81 | ||
82 | private function decorateEventWithMetaData($event, MetaData $metaData): EventWithMetaData |
|
83 | { |
|
84 | return new EventWithMetaData($event, $metaData->withEventId(Guid::generate())); |
|
85 | } |
|
86 | ||
87 | /** |
|
88 | * @param CommandWithMetadata $command |
|
89 | * @param CommandHandlerAndAggregate $handlerAndAggregate |
|
90 | * @return bool |
|
91 | */ |
|
92 | private function applyCommand(CommandWithMetadata $command, CommandHandlerAndAggregate $handlerAndAggregate): bool |
|
93 | { |
|
94 | $aggregate = $handlerAndAggregate->getAggregate(); |
|
95 | $handler = $handlerAndAggregate->getCommandHandler(); |
|
96 | ||
97 | $metaData = $this->eventMetadataFactory->factoryEventMetadata($command, $aggregate); |
|
98 | ||
99 | $newMessageGenerator = $this->commandApplier->applyCommand($aggregate, $command->getCommand(), $handler->getMethodName()); |
|
100 | ||
101 | foreach ($newMessageGenerator as $message) { |
|
102 | if (!$this->isScheduledCommand($message)) { |
|
103 | $eventWithMetaData = $this->decorateEventWithMetaData($message, $metaData); |
|
104 | if (!$this->isScheduledEvent($message)) { |
|
105 | $this->eventsApplierOnAggregate->applyEventsOnAggregate($aggregate, [$eventWithMetaData]); |
|
106 | } |
|
107 | } |
|
108 | ||
109 | return true; |
|
110 | } |
|
111 | ||
112 | return false; |
|
113 | } |
|
114 | ||
115 | private function isScheduledEvent($event): bool |
|
116 | { |
|
117 | return $event instanceof ScheduledEvent; |
|
118 | } |
|
119 | ||
120 | private function isScheduledCommand($message): bool |
|
121 | { |
|
122 | return $message instanceof ScheduledCommand; |
|
123 | } |
|
124 | } |