synapse-core 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/synapse.rb +3 -0
- data/lib/synapse/command/simple_command_bus.rb +2 -2
- data/lib/synapse/common/concurrency/identifier_lock.rb +71 -0
- data/lib/synapse/common/concurrency/public_lock.rb +96 -0
- data/lib/synapse/event_bus/simple_event_bus.rb +1 -1
- data/lib/synapse/event_bus/wiring.rb +0 -4
- data/lib/synapse/event_sourcing/member.rb +0 -4
- data/lib/synapse/event_sourcing/snapshot/count_trigger.rb +2 -2
- data/lib/synapse/event_store.rb +1 -9
- data/lib/synapse/partitioning.rb +0 -2
- data/lib/synapse/process_manager.rb +12 -0
- data/lib/synapse/process_manager/lock_manager.rb +22 -0
- data/lib/synapse/process_manager/pessimistic_lock_manager.rb +23 -0
- data/lib/synapse/process_manager/process.rb +2 -0
- data/lib/synapse/process_manager/process_factory.rb +52 -0
- data/lib/synapse/process_manager/process_manager.rb +170 -0
- data/lib/synapse/process_manager/process_repository.rb +53 -0
- data/lib/synapse/process_manager/repository/in_memory.rb +63 -0
- data/lib/synapse/process_manager/resource_injector.rb +12 -0
- data/lib/synapse/process_manager/simple_process_manager.rb +48 -0
- data/lib/synapse/process_manager/wiring/process.rb +27 -0
- data/lib/synapse/process_manager/wiring/process_manager.rb +72 -0
- data/lib/synapse/repository.rb +1 -0
- data/lib/synapse/repository/locking.rb +1 -1
- data/lib/synapse/repository/optimistic_lock_manager.rb +128 -0
- data/lib/synapse/repository/pessimistic_lock_manager.rb +4 -37
- data/lib/synapse/serialization.rb +1 -1
- data/lib/synapse/serialization/{converter/factory.rb → converter_factory.rb} +0 -0
- data/lib/synapse/serialization/serializer.rb +5 -3
- data/lib/synapse/uow/listener_collection.rb +59 -1
- data/lib/synapse/version.rb +1 -1
- data/lib/synapse/wiring/message_wiring.rb +7 -3
- data/lib/synapse/wiring/wire.rb +7 -2
- data/test/common/concurrency/identifier_lock_test.rb +36 -0
- data/test/common/concurrency/public_lock_test.rb +83 -0
- data/test/partitioning/packing/json_test.rb +2 -1
- data/test/process_manager/in_memory_test.rb +57 -0
- data/test/process_manager/process_factory_test.rb +31 -0
- data/test/process_manager/simple_process_manager_test.rb +130 -0
- data/test/process_manager/wiring/fixtures.rb +42 -0
- data/test/process_manager/wiring/process_manager_test.rb +73 -0
- data/test/process_manager/wiring/process_test.rb +35 -0
- data/test/repository/optimistic_test.rb +41 -0
- data/test/repository/pessimistic_test.rb +20 -0
- data/test/serialization/converter/chain_test.rb +31 -0
- data/test/serialization/lazy_object_test.rb +1 -1
- data/test/serialization/message/serialization_aware_message_test.rb +4 -2
- data/test/serialization/message/serialized_message_builder_test.rb +1 -1
- data/test/serialization/message/serialized_message_test.rb +3 -2
- data/test/serialization/serializer/marshal_test.rb +1 -1
- data/test/serialization/serializer/oj_test.rb +1 -1
- data/test/serialization/serializer/ox_test.rb +1 -1
- data/test/serialization/serializer_test.rb +1 -1
- data/test/test_ext.rb +5 -2
- data/test/wiring/wire_registry_test.rb +10 -10
- data/test/wiring/wire_test.rb +5 -5
- metadata +29 -16
- data/lib/synapse/event_store/mongo.rb +0 -8
- data/lib/synapse/event_store/mongo/cursor_event_stream.rb +0 -63
- data/lib/synapse/event_store/mongo/event_store.rb +0 -86
- data/lib/synapse/event_store/mongo/per_commit_strategy.rb +0 -253
- data/lib/synapse/event_store/mongo/per_event_strategy.rb +0 -143
- data/lib/synapse/event_store/mongo/storage_strategy.rb +0 -113
- data/lib/synapse/event_store/mongo/template.rb +0 -73
- data/lib/synapse/partitioning/amqp.rb +0 -3
- data/lib/synapse/partitioning/amqp/amqp_queue_reader.rb +0 -50
- data/lib/synapse/partitioning/amqp/amqp_queue_writer.rb +0 -31
- data/lib/synapse/partitioning/amqp/key_resolver.rb +0 -26
- data/lib/synapse/serialization/converter/bson.rb +0 -28
@@ -1,8 +0,0 @@
|
|
1
|
-
require 'synapse/event_store/mongo/cursor_event_stream'
|
2
|
-
require 'synapse/event_store/mongo/event_store'
|
3
|
-
|
4
|
-
require 'synapse/event_store/mongo/storage_strategy'
|
5
|
-
require 'synapse/event_store/mongo/per_commit_strategy'
|
6
|
-
require 'synapse/event_store/mongo/per_event_strategy'
|
7
|
-
|
8
|
-
require 'synapse/event_store/mongo/template'
|
@@ -1,63 +0,0 @@
|
|
1
|
-
module Synapse
|
2
|
-
module EventStore
|
3
|
-
module Mongo
|
4
|
-
# TODO Document me
|
5
|
-
class CursorDomainEventStream < Domain::DomainEventStream
|
6
|
-
# @param [StorageStrategy] storage_strategy
|
7
|
-
# @param [Mongo::Cursor] cursor
|
8
|
-
# @param [Array] last_snapshot_commit
|
9
|
-
# @param [Object] aggregate_id
|
10
|
-
# @return [undefined]
|
11
|
-
def initialize(storage_strategy, cursor, last_snapshot_commit, aggregate_id)
|
12
|
-
@storage_strategy = storage_strategy
|
13
|
-
@cursor = cursor
|
14
|
-
@aggregate_id = aggregate_id
|
15
|
-
|
16
|
-
if last_snapshot_commit
|
17
|
-
# Current batch is an enumerator
|
18
|
-
@current_batch = last_snapshot_commit.each
|
19
|
-
else
|
20
|
-
@current_batch = [].each
|
21
|
-
end
|
22
|
-
|
23
|
-
initialize_next_event
|
24
|
-
end
|
25
|
-
|
26
|
-
# @return [Boolean]
|
27
|
-
def end?
|
28
|
-
@next.nil?
|
29
|
-
end
|
30
|
-
|
31
|
-
# @return [DomainEventMessage]
|
32
|
-
def next_event
|
33
|
-
@next.tap do
|
34
|
-
initialize_next_event
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# @return [DomainEventMessage]
|
39
|
-
def peek
|
40
|
-
@next
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
# @return [undefined]
|
46
|
-
def initialize_next_event
|
47
|
-
begin
|
48
|
-
@next = @current_batch.next
|
49
|
-
rescue StopIteration
|
50
|
-
if @cursor.has_next?
|
51
|
-
document = @cursor.next
|
52
|
-
@current_batch = @storage_strategy.extract_events(document, @aggregate_id).each
|
53
|
-
|
54
|
-
retry
|
55
|
-
else
|
56
|
-
@next = nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end # CursorDomainEventStream
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
module Synapse
|
2
|
-
module EventStore
|
3
|
-
module Mongo
|
4
|
-
# Implementation of an event store backed by a Mongo database
|
5
|
-
class MongoEventStore < SnapshotEventStore
|
6
|
-
# @param [MongoTemplate] template
|
7
|
-
# @param [StorageStrategy] storage_strategy
|
8
|
-
# @return [undefined]
|
9
|
-
def initialize(template, storage_strategy)
|
10
|
-
@storage_strategy = storage_strategy
|
11
|
-
@template = template
|
12
|
-
end
|
13
|
-
|
14
|
-
# @return [undefined]
|
15
|
-
def ensure_indexes
|
16
|
-
@storage_strategy.ensure_indexes
|
17
|
-
end
|
18
|
-
|
19
|
-
# @raise [EventStoreError] If an error occurs while reading the stream from the store
|
20
|
-
# @param [String] type_identifier Type descriptor of the aggregate to retrieve
|
21
|
-
# @param [Object] aggregate_id
|
22
|
-
# @return [DomainEventStream]
|
23
|
-
def read_events(type_identifier, aggregate_id)
|
24
|
-
first_sequence_number = -1
|
25
|
-
|
26
|
-
last_snapshot_commit = load_last_snapshot type_identifier, aggregate_id
|
27
|
-
if last_snapshot_commit and last_snapshot_commit.size > 0
|
28
|
-
first_sequence_number = last_snapshot_commit[0].sequence_number
|
29
|
-
end
|
30
|
-
|
31
|
-
cursor = @storage_strategy.fetch_events type_identifier, aggregate_id, first_sequence_number
|
32
|
-
|
33
|
-
unless last_snapshot_commit or cursor.has_next?
|
34
|
-
raise StreamNotFoundError.new type_identifier, aggregate_id
|
35
|
-
end
|
36
|
-
|
37
|
-
CursorDomainEventStream.new @storage_strategy, cursor, last_snapshot_commit, aggregate_id
|
38
|
-
end
|
39
|
-
|
40
|
-
# @raise [EventStoreError] If an error occurs while appending the stream to the store
|
41
|
-
# @param [String] type_identifier Type descriptor of the aggregate to append to
|
42
|
-
# @param [DomainEventStream] stream
|
43
|
-
# @return [undefined]
|
44
|
-
def append_events(type_identifier, stream)
|
45
|
-
events = stream.to_a
|
46
|
-
documents = @storage_strategy.create_documents type_identifier, events
|
47
|
-
|
48
|
-
begin
|
49
|
-
@template.event_collection.insert documents
|
50
|
-
rescue Mongo::OperationFailure => ex
|
51
|
-
if e.error_code == 11000
|
52
|
-
raise Repository::ConcurrencyException,
|
53
|
-
'Event for this aggregate and sequence number already present'
|
54
|
-
end
|
55
|
-
|
56
|
-
raise ex
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# @raise [EventStoreError] If an error occurs while appending the event to the store
|
61
|
-
# @param [String] type_identifier Type descriptor of the aggregate to append to
|
62
|
-
# @param [DomainEventMessage] snapshot_event
|
63
|
-
# @return [undefined]
|
64
|
-
def append_snapshot_event(type_identifier, snapshot_event)
|
65
|
-
documents = @storage_strategy.create_documents type_identifier, [snapshot_event]
|
66
|
-
@template.snapshot_collection.insert documents
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
# @param [String] type_identifier Type descriptor of the aggregate to retrieve
|
72
|
-
# @param [Object] aggregate_id
|
73
|
-
def load_last_snapshot(type_identifier, aggregate_id)
|
74
|
-
cursor = @storage_strategy.fetch_last_snapshot type_identifier, aggregate_id
|
75
|
-
|
76
|
-
unless cursor.has_next?
|
77
|
-
return
|
78
|
-
end
|
79
|
-
|
80
|
-
first = cursor.next_document
|
81
|
-
@storage_strategy.extract_events first, aggregate_id
|
82
|
-
end
|
83
|
-
end # MongoEventStore
|
84
|
-
end # Mongo
|
85
|
-
end # EventStore
|
86
|
-
end # Synapse
|
@@ -1,253 +0,0 @@
|
|
1
|
-
module Synapse
|
2
|
-
module EventStore
|
3
|
-
module Mongo
|
4
|
-
# Storage strategy that stores all events in a commit operation in a single document
|
5
|
-
#
|
6
|
-
# Since Mongo doesn't support transactions, this can be used as a substitute to guarantee
|
7
|
-
# atomic storage of events. The only downside is that it may be harder to query events
|
8
|
-
# from the event store.
|
9
|
-
#
|
10
|
-
# Performance also seems to be better using this strategy
|
11
|
-
class DocumentPerCommitStrategy < StorageStrategy
|
12
|
-
# @param [String] type_identifier Type identifier for the aggregate
|
13
|
-
# @param [Array] events Domain events to be committed
|
14
|
-
# @return [Array]
|
15
|
-
def create_documents(type_identifier, events)
|
16
|
-
document = CommitDocument.new
|
17
|
-
document.from_events(type_identifier, events, @serializer).to_hash
|
18
|
-
end
|
19
|
-
|
20
|
-
# @param [Hash] hash
|
21
|
-
# @param [Object] aggregate_id
|
22
|
-
# @return [Array]
|
23
|
-
def extract_events(hash, aggregate_id)
|
24
|
-
document = CommitDocument.new
|
25
|
-
document.from_hash(hash).to_events(aggregate_id, @serializer, @upcaster_chain)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Mongo document that represents a commit containing one or more events
|
29
|
-
class CommitDocument
|
30
|
-
# @return [Object]
|
31
|
-
attr_reader :aggregate_id
|
32
|
-
|
33
|
-
# @param [String] type_identifier
|
34
|
-
# @param [Array] events
|
35
|
-
# @param [Serializer] serializer
|
36
|
-
# @return [CommitDocument]
|
37
|
-
def from_events(type_identifier, events, serializer)
|
38
|
-
first_event = events.first
|
39
|
-
last_event = events.last
|
40
|
-
|
41
|
-
@aggregate_type = type_identifier
|
42
|
-
@aggregate_id = first_event.aggregate_id.to_s
|
43
|
-
@first_sequence_number = first_event.sequence_number
|
44
|
-
@last_sequence_number = last_event.sequence_number
|
45
|
-
@first_timestamp = first_event.timestamp
|
46
|
-
@last_timestamp = last_event.timestamp
|
47
|
-
|
48
|
-
@events = Array.new
|
49
|
-
events.each do |event|
|
50
|
-
event_document = EventDocument.new
|
51
|
-
event_document.from_event event, serializer
|
52
|
-
|
53
|
-
@events.push event_document
|
54
|
-
end
|
55
|
-
|
56
|
-
self
|
57
|
-
end
|
58
|
-
|
59
|
-
# @param [Hash] hash
|
60
|
-
# @return [CommitDocument]
|
61
|
-
def from_hash(hash)
|
62
|
-
hash.symbolize_keys!
|
63
|
-
|
64
|
-
@aggregate_id = hash.fetch :aggregate_id
|
65
|
-
@aggregate_type = hash.fetch :aggregate_type
|
66
|
-
@first_sequence_number = hash.fetch :first_sequence_number
|
67
|
-
@last_sequence_number = hash.fetch :last_sequence_number
|
68
|
-
@first_timestamp = hash.fetch :first_timestamp
|
69
|
-
@last_timestamp = hash.fetch :last_timestamp
|
70
|
-
|
71
|
-
@events = Array.new
|
72
|
-
|
73
|
-
event_hashes = hash.fetch :events
|
74
|
-
event_hashes.each do |event_hash|
|
75
|
-
event_document = EventDocument.new
|
76
|
-
event_document.from_hash event_hash
|
77
|
-
|
78
|
-
@events.push event_document
|
79
|
-
end
|
80
|
-
|
81
|
-
self
|
82
|
-
end
|
83
|
-
|
84
|
-
# @return [Hash]
|
85
|
-
def to_hash
|
86
|
-
events = Array.new
|
87
|
-
@events.each do |event|
|
88
|
-
events.push event.to_hash
|
89
|
-
end
|
90
|
-
|
91
|
-
{ aggregate_id: @aggregate_id,
|
92
|
-
aggregate_type: @aggregate_type,
|
93
|
-
# Allows us to use the same query to filter events as DocumentPerEvent
|
94
|
-
sequence_number: @first_sequence_number,
|
95
|
-
first_sequence_number: @first_sequence_number,
|
96
|
-
last_sequence_number: @last_sequence_number,
|
97
|
-
# Allows us to use the same query to filter events as DocumentPerEvent
|
98
|
-
timestamp: @first_timestamp,
|
99
|
-
first_timestamp: @first_timestamp,
|
100
|
-
last_timestamp: @last_timestamp,
|
101
|
-
events: events }
|
102
|
-
end
|
103
|
-
|
104
|
-
# @param [Object] aggregate_id The actual aggregate identifier used to query the evnet store
|
105
|
-
# @param [Serializer] serializer
|
106
|
-
# @param [UpcasterChain] upcaster_chain
|
107
|
-
# @return [Array]
|
108
|
-
def to_events(aggregate_id, serializer, upcaster_chain)
|
109
|
-
events = Array.new
|
110
|
-
|
111
|
-
@events.each do |event_document|
|
112
|
-
event_data = DocumentDomainEventData.new aggregate_id, event_document
|
113
|
-
context = Upcasting::SerializedDomainEventUpcastingContext.new event_data, aggregate_id, serializer
|
114
|
-
|
115
|
-
upcast_objects = upcaster_chain.upcast event_document.payload, context
|
116
|
-
upcast_objects.each do |upcast_object|
|
117
|
-
upcast_data = Upcasting::UpcastSerializedDomainEventData.new event_data, aggregate_id, upcast_object
|
118
|
-
|
119
|
-
builder = Serialization::SerializedDomainEventMessageBuilder.new
|
120
|
-
|
121
|
-
# Prevent duplicate serialization of metadata if it was accessed during upcasting
|
122
|
-
metadata = context.serialized_metadata
|
123
|
-
if metadata.deserialized?
|
124
|
-
builder.metadata = Serialization::DeserializedObject.new metadata.deserialized
|
125
|
-
end
|
126
|
-
|
127
|
-
builder.from_data upcast_data, serializer
|
128
|
-
|
129
|
-
events.push builder.build
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
events
|
134
|
-
end
|
135
|
-
end # CommitDocument
|
136
|
-
|
137
|
-
# Mongo document that represents a single event as part of a commit document
|
138
|
-
class EventDocument
|
139
|
-
# @return [String]
|
140
|
-
attr_reader :id
|
141
|
-
|
142
|
-
# @return [Time]
|
143
|
-
attr_reader :timestamp
|
144
|
-
|
145
|
-
# @return [Integer]
|
146
|
-
attr_reader :sequence_number
|
147
|
-
|
148
|
-
# @return [SerializedObject]
|
149
|
-
def metadata
|
150
|
-
Serialization::SerializedMetadata.new @metadata, @metadata.class
|
151
|
-
end
|
152
|
-
|
153
|
-
# @return [SerializedObject]
|
154
|
-
def payload
|
155
|
-
Serialization::SerializedObject.new @payload, @payload.class,
|
156
|
-
Serialization::SerializedType.new(@payload_type, @payload_revision)
|
157
|
-
end
|
158
|
-
|
159
|
-
# @param [EventMessage] event
|
160
|
-
# @param [Serializer] serializer
|
161
|
-
# @return [EventDocument]
|
162
|
-
def from_event(event, serializer)
|
163
|
-
serialization_target = String
|
164
|
-
if serializer.can_serialize_to? Hash
|
165
|
-
serialization_target = Hash
|
166
|
-
end
|
167
|
-
|
168
|
-
serialized_metadata = serializer.serialize_metadata event, serialization_target
|
169
|
-
serialized_payload = serializer.serialize_payload event, serialization_target
|
170
|
-
|
171
|
-
@id = event.id
|
172
|
-
@metadata = serialized_metadata.content
|
173
|
-
@payload = serialized_payload.content
|
174
|
-
@payload_type = serialized_payload.type.name
|
175
|
-
@payload_revision = serialized_payload.type.revision
|
176
|
-
@timestamp = event.timestamp
|
177
|
-
@sequence_number = event.sequence_number
|
178
|
-
|
179
|
-
self
|
180
|
-
end
|
181
|
-
|
182
|
-
# @param [Hash] hash
|
183
|
-
# @return [EventDocument]
|
184
|
-
def from_hash(hash)
|
185
|
-
hash.symbolize_keys!
|
186
|
-
|
187
|
-
@id = hash.fetch :id
|
188
|
-
@metadata = hash.fetch :metadata
|
189
|
-
@payload = hash.fetch :payload
|
190
|
-
@payload_type = hash.fetch :payload_type
|
191
|
-
@payload_revision = hash.fetch :payload_revision
|
192
|
-
@timestamp = hash.fetch :timestamp
|
193
|
-
@sequence_number = hash.fetch :sequence_number
|
194
|
-
|
195
|
-
self
|
196
|
-
end
|
197
|
-
|
198
|
-
# @return [Hash]
|
199
|
-
def to_hash
|
200
|
-
{ id: @id,
|
201
|
-
metadata: @metadata,
|
202
|
-
payload: @payload,
|
203
|
-
payload_type: @payload_type,
|
204
|
-
payload_revision: @payload_revision,
|
205
|
-
timestamp: @timestamp,
|
206
|
-
sequence_number: @sequence_number }
|
207
|
-
end
|
208
|
-
end # EventDocument
|
209
|
-
|
210
|
-
# Serialized domain event data from an event document
|
211
|
-
class DocumentDomainEventData < Serialization::SerializedDomainEventData
|
212
|
-
# @param [Object] aggregate_id
|
213
|
-
# @param [EventDocument] event_document
|
214
|
-
# @return [undefined]
|
215
|
-
def initialize(aggregate_id, event_document)
|
216
|
-
@aggregate_id = aggregate_id
|
217
|
-
@event_document = event_document
|
218
|
-
end
|
219
|
-
|
220
|
-
# @return [String]
|
221
|
-
def id
|
222
|
-
@event_document.id
|
223
|
-
end
|
224
|
-
|
225
|
-
# @return [SerializedObject]
|
226
|
-
def metadata
|
227
|
-
@event_document.metadata
|
228
|
-
end
|
229
|
-
|
230
|
-
# @return [SerializedObject]
|
231
|
-
def payload
|
232
|
-
@event_document.payload
|
233
|
-
end
|
234
|
-
|
235
|
-
# @return [Time]
|
236
|
-
def timestamp
|
237
|
-
@event_document.timestamp
|
238
|
-
end
|
239
|
-
|
240
|
-
# @return [Object]
|
241
|
-
def aggregate_id
|
242
|
-
@aggregate_id
|
243
|
-
end
|
244
|
-
|
245
|
-
# @return [Integer]
|
246
|
-
def sequence_number
|
247
|
-
@event_document.sequence_number
|
248
|
-
end
|
249
|
-
end # DocumentDomainEventData
|
250
|
-
end # DocumentPerCommitStrategy
|
251
|
-
end # Mongo
|
252
|
-
end # EventStore
|
253
|
-
end # Synapse
|
@@ -1,143 +0,0 @@
|
|
1
|
-
module Synapse
|
2
|
-
module EventStore
|
3
|
-
module Mongo
|
4
|
-
# Storage strategy that stores each event as its own document
|
5
|
-
class DocumentPerEventStrategy < StorageStrategy
|
6
|
-
# @param [String] type_identifier Type identifier for the aggregate
|
7
|
-
# @param [Array] events Domain events to be committed
|
8
|
-
# @return [Array]
|
9
|
-
def create_documents(type_identifier, events)
|
10
|
-
documents = Array.new
|
11
|
-
|
12
|
-
events.each do |event|
|
13
|
-
document = EventDocument.new
|
14
|
-
document.from_event event, type_identifier, @serializer
|
15
|
-
|
16
|
-
documents.push document.to_hash
|
17
|
-
end
|
18
|
-
|
19
|
-
documents
|
20
|
-
end
|
21
|
-
|
22
|
-
# @param [Hash] hash
|
23
|
-
# @param [Object] aggregate_id
|
24
|
-
# @return [Array]
|
25
|
-
def extract_events(hash, aggregate_id)
|
26
|
-
document = EventDocument.new
|
27
|
-
document.from_hash(hash).to_events(aggregate_id, @serializer, @upcaster_chain)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Mongo document that represents a single domain event
|
31
|
-
class EventDocument < Serialization::SerializedDomainEventData
|
32
|
-
# @return [String]
|
33
|
-
attr_reader :id
|
34
|
-
|
35
|
-
# @return [Time]
|
36
|
-
attr_reader :timestamp
|
37
|
-
|
38
|
-
# @return [Object]
|
39
|
-
attr_reader :aggregate_id
|
40
|
-
|
41
|
-
# @return [Integer]
|
42
|
-
attr_reader :sequence_number
|
43
|
-
|
44
|
-
# @param [SerializedObject]
|
45
|
-
def metadata
|
46
|
-
Serialization::SerializedMetadata.new @metadata, @metadata.class
|
47
|
-
end
|
48
|
-
|
49
|
-
# @param [SerializedObject]
|
50
|
-
def payload
|
51
|
-
Serialization::SerializedObject.new @payload, @payload.class,
|
52
|
-
Serialization::SerializedType.new(@payload_type, @payload_revision)
|
53
|
-
end
|
54
|
-
|
55
|
-
# @param [DomainEventMessage] event
|
56
|
-
# @param [String] type_identifier
|
57
|
-
# @param [Serializer] serializer
|
58
|
-
# @return [EventDocument]
|
59
|
-
def from_event(event, type_identifier, serializer)
|
60
|
-
serialization_target = String
|
61
|
-
if serializer.can_serialize_to? Hash
|
62
|
-
serialization_target = Hash
|
63
|
-
end
|
64
|
-
|
65
|
-
serialized_metadata = serializer.serialize_metadata event, serialization_target
|
66
|
-
serialized_payload = serializer.serialize_payload event, serialization_target
|
67
|
-
|
68
|
-
@id = event.id
|
69
|
-
@metadata = serialized_metadata.content
|
70
|
-
@payload = serialized_payload.content
|
71
|
-
@payload_type = serialized_payload.type.name
|
72
|
-
@payload_revision = serialized_payload.type.revision
|
73
|
-
@timestamp = event.timestamp
|
74
|
-
@aggregate_id = event.aggregate_id
|
75
|
-
@aggregate_type = type_identifier
|
76
|
-
@sequence_number = event.sequence_number
|
77
|
-
|
78
|
-
self
|
79
|
-
end
|
80
|
-
|
81
|
-
# @param [Hash] hash
|
82
|
-
# @return [EventDocument]
|
83
|
-
def from_hash(hash)
|
84
|
-
hash.symbolize_keys!
|
85
|
-
|
86
|
-
@id = hash.fetch :_id
|
87
|
-
@metadata = hash.fetch :metadata
|
88
|
-
@payload = hash.fetch :payload
|
89
|
-
@payload_type = hash.fetch :payload_type
|
90
|
-
@payload_revision = hash.fetch :payload_revision
|
91
|
-
@timestamp = hash.fetch :timestamp
|
92
|
-
@aggregate_id = hash.fetch :aggregate_id
|
93
|
-
@aggregate_type = hash.fetch :aggregate_type
|
94
|
-
@sequence_number = hash.fetch :sequence_number
|
95
|
-
|
96
|
-
self
|
97
|
-
end
|
98
|
-
|
99
|
-
# @return [Hash]
|
100
|
-
def to_hash
|
101
|
-
{ _id: @id,
|
102
|
-
metadata: @metadata,
|
103
|
-
payload: @payload,
|
104
|
-
payload_type: @payload_type,
|
105
|
-
payload_revision: @payload_revision,
|
106
|
-
timestamp: @timestamp,
|
107
|
-
aggregate_id: @aggregate_id,
|
108
|
-
aggregate_type: @aggregate_type,
|
109
|
-
sequence_number: @sequence_number }
|
110
|
-
end
|
111
|
-
|
112
|
-
# @param [Object] aggregate_id
|
113
|
-
# @param [Serializer] serializer
|
114
|
-
# @param [UpcasterChain] upcaster_chain
|
115
|
-
# @return [Array]
|
116
|
-
def to_events(aggregate_id, serializer, upcaster_chain)
|
117
|
-
events = Array.new
|
118
|
-
|
119
|
-
context = Upcasting::SerializedDomainEventUpcastingContext.new self, aggregate_id, serializer
|
120
|
-
upcast_objects = upcaster_chain.upcast payload, context
|
121
|
-
upcast_objects.each do |upcast_object|
|
122
|
-
upcast_data = Upcasting::UpcastSerializedDomainEventData.new self, aggregate_id, upcast_object
|
123
|
-
|
124
|
-
builder = Serialization::SerializedDomainEventMessageBuilder.new
|
125
|
-
|
126
|
-
# Prevent duplicate serialization of metadata if it was accessed during upcasting
|
127
|
-
metadata = context.serialized_metadata
|
128
|
-
if metadata.deserialized?
|
129
|
-
builder.metadata = Serialization::DeserializedObject.new metadata.deserialized
|
130
|
-
end
|
131
|
-
|
132
|
-
builder.from_data upcast_data, serializer
|
133
|
-
|
134
|
-
events.push builder.build
|
135
|
-
end
|
136
|
-
|
137
|
-
events
|
138
|
-
end
|
139
|
-
end # EventDocument
|
140
|
-
end # DocumentPerEventStrategy
|
141
|
-
end # Mongo
|
142
|
-
end # EventStore
|
143
|
-
end # Synapse
|