Completed
Push — v4.0 ( d88c1e...d1a754 )
by Masiukevich
03:36
created

EventSourcingModule::withSqlStorage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Event Sourcing implementation module.
5
 *
6
 * @author  Maksim Masiukevich <[email protected]>
7
 * @license MIT
8
 * @license https://opensource.org/licenses/MIT
9
 */
10
11
declare(strict_types = 1);
12
13
namespace ServiceBus\EventSourcingModule;
14
15
use ServiceBus\Common\Module\ServiceBusModule;
16
use ServiceBus\EventSourcing\EventStream\EventStreamRepository;
17
use ServiceBus\EventSourcing\EventStream\Serializer\DefaultEventSerializer;
18
use ServiceBus\EventSourcing\EventStream\Serializer\EventSerializer;
19
use ServiceBus\EventSourcing\EventStream\Store\EventStreamStore;
20
use ServiceBus\EventSourcing\EventStream\Store\SqlEventStreamStore;
21
use ServiceBus\EventSourcing\Indexes\Store\IndexStore;
22
use ServiceBus\EventSourcing\Indexes\Store\SqlIndexStore;
23
use ServiceBus\EventSourcing\Snapshots\Snapshotter;
24
use ServiceBus\EventSourcing\Snapshots\Store\SnapshotStore;
25
use ServiceBus\EventSourcing\Snapshots\Store\SqlSnapshotStore;
26
use ServiceBus\EventSourcing\Snapshots\Triggers\SnapshotTrigger;
27
use ServiceBus\EventSourcing\Snapshots\Triggers\SnapshotVersionTrigger;
28
use ServiceBus\Mutex\InMemory\InMemoryMutexFactory;
29
use ServiceBus\Mutex\MutexFactory;
30
use Symfony\Component\DependencyInjection\ContainerBuilder;
31
use Symfony\Component\DependencyInjection\Definition;
32
use Symfony\Component\DependencyInjection\Reference;
33
34
/**
35
 * @todo: custom store initialization
36
 */
37
final class EventSourcingModule implements ServiceBusModule
38
{
39
    /** @var string  */
40
    private $eventStoreServiceId;
41
42
    /** @var string  */
43
    private $snapshotStoreServiceId;
44
45
    /** @var string  */
46
    private $indexerStore;
47
48
    /** @var string|null  */
49
    private $databaseAdapterServiceId= null;
50
51
    /** @var string|null  */
52
    private $customEventSerializerServiceId= null;
53
54
    /** @var string|null  */
55
    private $customSnapshotStrategyServiceId = null;
56
57 1
    public static function withSqlStorage(string $databaseAdapterServiceId): self
58
    {
59 1
        $self = new self(
60 1
            EventStreamStore::class,
61 1
            SnapshotStore::class,
62 1
            IndexStore::class
63
        );
64
65 1
        $self->databaseAdapterServiceId = $databaseAdapterServiceId;
66
67 1
        return $self;
68
    }
69
70
    public function withCustomEventSerializer(string $eventSerializerServiceId): self
71
    {
72
        $this->customEventSerializerServiceId = $eventSerializerServiceId;
73
74
        return $this;
75
    }
76
77
    public function withCustomSnapshotStrategy(string $snapshotStrategyServiceId): self
78
    {
79
        $this->customSnapshotStrategyServiceId = $snapshotStrategyServiceId;
80
81
        return $this;
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87 1
    public function boot(ContainerBuilder $containerBuilder): void
88
    {
89
        /** Default configuration used */
90 1
        if (null !== $this->databaseAdapterServiceId)
91
        {
92 1
            $storeArguments = [new Reference($this->databaseAdapterServiceId)];
93
94 1
            $containerBuilder->addDefinitions([
95 1
                $this->eventStoreServiceId    => (new Definition(SqlEventStreamStore::class))->setArguments($storeArguments),
96 1
                $this->snapshotStoreServiceId => (new Definition(SqlSnapshotStore::class))->setArguments($storeArguments),
97 1
                $this->indexerStore           => (new Definition(SqlIndexStore::class))->setArguments($storeArguments),
98
            ]);
99
        }
100
101 1
        $this->registerMutexFactory($containerBuilder);
102 1
        $this->registerSnapshotter($containerBuilder);
103 1
        $this->registerEventSourcingProvider($containerBuilder);
104 1
        $this->registerIndexer($containerBuilder);
105 1
    }
106
107 1
    private function registerMutexFactory(ContainerBuilder $containerBuilder): void
108
    {
109 1
        if (false === $containerBuilder->hasDefinition(MutexFactory::class))
110
        {
111 1
            $containerBuilder->addDefinitions([
112 1
                MutexFactory::class => new Definition(InMemoryMutexFactory::class),
113
            ]);
114
        }
115 1
    }
116
117 1
    private function registerIndexer(ContainerBuilder $containerBuilder): void
118
    {
119
        /** @psalm-suppress PossiblyNullArgument */
120 1
        $containerBuilder->addDefinitions([
121 1
            $this->indexerStore  => (new Definition(SqlIndexStore::class))->setArguments([new Reference((string) $this->databaseAdapterServiceId)]),
122 1
            IndexProvider::class => (new Definition(IndexProvider::class))->setArguments(
123
                [
124 1
                    new Reference($this->indexerStore),
125 1
                    new Reference(MutexFactory::class)
126
                ]
127
            ),
128
        ]);
129 1
    }
130
131 1
    private function registerEventSourcingProvider(ContainerBuilder $containerBuilder): void
132
    {
133 1
        $serializer = null;
134
135 1
        if (null !== $this->customEventSerializerServiceId)
136
        {
137
            $serializer = new Reference($this->customEventSerializerServiceId);
138
        }
139
        else
140
        {
141 1
            $containerBuilder->addDefinitions(
142
                [
143 1
                    EventSerializer::class => (new Definition(DefaultEventSerializer::class))->setArguments([
144 1
                        new Reference('service_bus.decoder.default_handler'),
145
                    ]),
146
                ]
147
            );
148
149 1
            $serializer = new Reference(EventSerializer::class);
150
        }
151
152
        $arguments = [
153 1
            new Reference($this->eventStoreServiceId),
154 1
            new Reference(Snapshotter::class),
155 1
            $serializer,
156 1
            new Reference('service_bus.logger'),
157
        ];
158
159 1
        $containerBuilder->addDefinitions([
160 1
            EventStreamRepository::class => (new Definition(EventStreamRepository::class))->setArguments($arguments),
161 1
            EventSourcingProvider::class => (new Definition(EventSourcingProvider::class))->setArguments(
162
                [
163 1
                    new Reference(EventStreamRepository::class),
164 1
                    new Reference(MutexFactory::class)
165
                ]
166
            ),
167
        ]);
168 1
    }
169
170 1
    private function registerSnapshotter(ContainerBuilder $containerBuilder): void
171
    {
172 1
        if (null === $this->customSnapshotStrategyServiceId)
173
        {
174 1
            $containerBuilder->addDefinitions([
175 1
                SnapshotTrigger::class => new Definition(SnapshotVersionTrigger::class, [30]),
176
            ]);
177
178 1
            $this->customSnapshotStrategyServiceId = SnapshotTrigger::class;
179
        }
180
181
        $arguments = [
182 1
            new Reference($this->snapshotStoreServiceId),
183 1
            new Reference($this->customSnapshotStrategyServiceId),
184 1
            new Reference('service_bus.logger'),
185
        ];
186
187 1
        $containerBuilder->addDefinitions([
188 1
            Snapshotter::class => (new Definition(Snapshotter::class))->setArguments($arguments),
189
        ]);
190 1
    }
191
192
    /**
193
     * @param string $eventStoreServiceId
194
     * @param string $snapshotStoreServiceId
195
     * @param string $indexerStore
196
     */
197 1
    private function __construct(string $eventStoreServiceId, string $snapshotStoreServiceId, string $indexerStore)
198
    {
199 1
        $this->eventStoreServiceId    = $eventStoreServiceId;
200 1
        $this->snapshotStoreServiceId = $snapshotStoreServiceId;
201 1
        $this->indexerStore           = $indexerStore;
202 1
    }
203
}
204