ruby_event_store 2.16.0 → 2.17.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.
- checksums.yaml +4 -4
- data/lib/ruby_event_store/broker.rb +11 -7
- data/lib/ruby_event_store/client.rb +60 -20
- data/lib/ruby_event_store/composed_broker.rb +65 -0
- data/lib/ruby_event_store/errors.rb +1 -0
- data/lib/ruby_event_store/in_memory_repository.rb +27 -27
- data/lib/ruby_event_store/instrumented_broker.rb +73 -0
- data/lib/ruby_event_store/instrumented_subscriptions.rb +3 -11
- data/lib/ruby_event_store/mappers/batch_mapper.rb +19 -0
- data/lib/ruby_event_store/mappers/default.rb +2 -2
- data/lib/ruby_event_store/mappers/encryption_key.rb +8 -1
- data/lib/ruby_event_store/mappers/encryption_mapper.rb +2 -2
- data/lib/ruby_event_store/mappers/instrumented_batch_mapper.rb +28 -0
- data/lib/ruby_event_store/mappers/transformation/domain_event.rb +8 -10
- data/lib/ruby_event_store/mappers/transformation/encryption.rb +2 -3
- data/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +1 -1
- data/lib/ruby_event_store/mappers/transformation/preserve_types.rb +11 -19
- data/lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb +1 -1
- data/lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb +1 -1
- data/lib/ruby_event_store/record.rb +9 -10
- data/lib/ruby_event_store/serialized_record.rb +2 -2
- data/lib/ruby_event_store/spec/broker_lint.rb +27 -10
- data/lib/ruby_event_store/spec/dispatcher_lint.rb +1 -1
- data/lib/ruby_event_store/spec/event_lint.rb +3 -3
- data/lib/ruby_event_store/spec/event_repository_lint.rb +228 -189
- data/lib/ruby_event_store/spec/mapper_lint.rb +2 -2
- data/lib/ruby_event_store/spec/scheduler_lint.rb +1 -1
- data/lib/ruby_event_store/spec/subscriptions_lint.rb +21 -20
- data/lib/ruby_event_store/specification.rb +5 -5
- data/lib/ruby_event_store/specification_reader.rb +6 -2
- data/lib/ruby_event_store/specification_result.rb +32 -34
- data/lib/ruby_event_store/subscriptions.rb +20 -20
- data/lib/ruby_event_store/transform_keys.rb +1 -3
- data/lib/ruby_event_store/version.rb +1 -1
- data/lib/ruby_event_store.rb +5 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27e060aa3ab06f96bd8ad44af2213213bd0b7bce53dfb8b40c1f3a3ab24d9c28
|
4
|
+
data.tar.gz: 4895c1114df635ca973528418a6e349d6e08522e465aea83856e154d040fc20b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c05e1e7961fdcd92354d721b26e5bfd57bf5a64c1606c2c0940c4bf5c490860e85b36e165d3089d982b2fa1c0b405efc8c0f24f979f7807ddc8e28c3c17743f1
|
7
|
+
data.tar.gz: 1ffc6203b80784a28591d30617c035ca1f6b04ad8bbe1af2c8b1bd732f01a80758e468c30c6f188503a143023af1e87d64f01f804f9bcff63bd6592221265002
|
@@ -2,19 +2,19 @@
|
|
2
2
|
|
3
3
|
module RubyEventStore
|
4
4
|
class Broker
|
5
|
-
def initialize(subscriptions
|
5
|
+
def initialize(subscriptions: Subscriptions.new, dispatcher: Dispatcher.new)
|
6
6
|
@subscriptions = subscriptions
|
7
7
|
@dispatcher = dispatcher
|
8
8
|
end
|
9
9
|
|
10
|
-
def call(event, record)
|
11
|
-
subscribers = subscriptions.all_for(
|
10
|
+
def call(topic, event, record)
|
11
|
+
subscribers = subscriptions.all_for(topic)
|
12
12
|
subscribers.each { |subscriber| dispatcher.call(subscriber, event, record) }
|
13
13
|
end
|
14
14
|
|
15
|
-
def add_subscription(subscriber,
|
15
|
+
def add_subscription(subscriber, topics)
|
16
16
|
verify_subscription(subscriber)
|
17
|
-
subscriptions.add_subscription(subscriber,
|
17
|
+
subscriptions.add_subscription(subscriber, topics)
|
18
18
|
end
|
19
19
|
|
20
20
|
def add_global_subscription(subscriber)
|
@@ -22,9 +22,9 @@ module RubyEventStore
|
|
22
22
|
subscriptions.add_global_subscription(subscriber)
|
23
23
|
end
|
24
24
|
|
25
|
-
def add_thread_subscription(subscriber,
|
25
|
+
def add_thread_subscription(subscriber, topics)
|
26
26
|
verify_subscription(subscriber)
|
27
|
-
subscriptions.add_thread_subscription(subscriber,
|
27
|
+
subscriptions.add_thread_subscription(subscriber, topics)
|
28
28
|
end
|
29
29
|
|
30
30
|
def add_thread_global_subscription(subscriber)
|
@@ -32,6 +32,10 @@ module RubyEventStore
|
|
32
32
|
subscriptions.add_thread_global_subscription(subscriber)
|
33
33
|
end
|
34
34
|
|
35
|
+
def all_subscriptions_for(topic)
|
36
|
+
subscriptions.all_for(topic)
|
37
|
+
end
|
38
|
+
|
35
39
|
private
|
36
40
|
|
37
41
|
attr_reader :dispatcher, :subscriptions
|
@@ -6,21 +6,48 @@ module RubyEventStore
|
|
6
6
|
class Client
|
7
7
|
def initialize(
|
8
8
|
repository: InMemoryRepository.new,
|
9
|
-
mapper: Mappers::
|
10
|
-
subscriptions:
|
11
|
-
dispatcher:
|
9
|
+
mapper: Mappers::BatchMapper.new,
|
10
|
+
subscriptions: nil,
|
11
|
+
dispatcher: nil,
|
12
|
+
message_broker: nil,
|
12
13
|
clock: default_clock,
|
13
14
|
correlation_id_generator: default_correlation_id_generator,
|
14
15
|
event_type_resolver: EventTypeResolver.new
|
15
16
|
)
|
16
17
|
@repository = repository
|
17
|
-
@mapper = mapper
|
18
|
-
@
|
19
|
-
|
18
|
+
@mapper = batch_mapper?(mapper) ? mapper : Mappers::BatchMapper.new(mapper)
|
19
|
+
@broker =
|
20
|
+
message_broker ||
|
21
|
+
Broker.new(subscriptions: subscriptions || Subscriptions.new, dispatcher: dispatcher || Dispatcher.new)
|
20
22
|
@clock = clock
|
21
23
|
@metadata = Concurrent::ThreadLocalVar.new
|
22
24
|
@correlation_id_generator = correlation_id_generator
|
23
25
|
@event_type_resolver = event_type_resolver
|
26
|
+
|
27
|
+
if (subscriptions || dispatcher)
|
28
|
+
warn <<~EOW
|
29
|
+
Passing subscriptions and dispatcher to #{self.class} has been deprecated.
|
30
|
+
|
31
|
+
Pass it using message_broker argument. For example:
|
32
|
+
|
33
|
+
event_store = RubyEventStore::Client.new(
|
34
|
+
message_broker: RubyEventStore::Broker.new(
|
35
|
+
subscriptions: RubyEventStore::Subscriptions.new,
|
36
|
+
dispatcher: RubyEventStore::Dispatcher.new
|
37
|
+
)
|
38
|
+
)
|
39
|
+
EOW
|
40
|
+
warn <<~EOW if (message_broker)
|
41
|
+
|
42
|
+
Because message_broker has been provided,
|
43
|
+
arguments passed by subscriptions or dispatcher will be ignored.
|
44
|
+
EOW
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def rescue_from_double_json_serialization!
|
49
|
+
return unless repository.respond_to? :rescue_from_double_json_serialization!
|
50
|
+
repository.rescue_from_double_json_serialization!
|
24
51
|
end
|
25
52
|
|
26
53
|
# Persists events and notifies subscribed handlers about them
|
@@ -29,13 +56,22 @@ module RubyEventStore
|
|
29
56
|
# @param stream_name [String] name of the stream for persisting events.
|
30
57
|
# @param expected_version [:any, :auto, :none, Integer] controls optimistic locking strategy. {http://railseventstore.org/docs/expected_version/ Read more}
|
31
58
|
# @return [self]
|
32
|
-
def publish(events, stream_name: GLOBAL_STREAM, expected_version: :any)
|
59
|
+
def publish(events, topic: nil, stream_name: GLOBAL_STREAM, expected_version: :any)
|
33
60
|
enriched_events = enrich_events_metadata(events)
|
34
61
|
records = transform(enriched_events)
|
35
62
|
append_records_to_stream(records, stream_name: stream_name, expected_version: expected_version)
|
36
63
|
enriched_events.zip(records) do |event, record|
|
37
64
|
with_metadata(correlation_id: event.metadata.fetch(:correlation_id), causation_id: event.event_id) do
|
38
|
-
broker.(
|
65
|
+
if broker.public_method(:call).arity == 3
|
66
|
+
broker.call(topic || event.event_type, event, record)
|
67
|
+
else
|
68
|
+
warn <<~EOW
|
69
|
+
Message broker shall support topics.
|
70
|
+
Topic WILL BE IGNORED in the current broker.
|
71
|
+
Modify the broker implementation to pass topic as an argument to broker.call method.
|
72
|
+
EOW
|
73
|
+
broker.call(event, record)
|
74
|
+
end
|
39
75
|
end
|
40
76
|
end
|
41
77
|
self
|
@@ -49,7 +85,7 @@ module RubyEventStore
|
|
49
85
|
append_records_to_stream(
|
50
86
|
transform(enrich_events_metadata(events)),
|
51
87
|
stream_name: stream_name,
|
52
|
-
expected_version: expected_version
|
88
|
+
expected_version: expected_version,
|
53
89
|
)
|
54
90
|
self
|
55
91
|
end
|
@@ -167,7 +203,7 @@ module RubyEventStore
|
|
167
203
|
# @param to [Class, String] type of events to get list of sybscribed handlers
|
168
204
|
# @return [Array<Object, Class>]
|
169
205
|
def subscribers_for(event_class)
|
170
|
-
|
206
|
+
broker.all_subscriptions_for(event_type_resolver.call(event_class))
|
171
207
|
end
|
172
208
|
|
173
209
|
# Builder object for collecting temporary handlers (subscribers)
|
@@ -231,6 +267,7 @@ module RubyEventStore
|
|
231
267
|
end
|
232
268
|
|
233
269
|
private
|
270
|
+
|
234
271
|
attr_reader :resolver
|
235
272
|
|
236
273
|
def add_thread_subscribers
|
@@ -273,18 +310,18 @@ module RubyEventStore
|
|
273
310
|
def deserialize(serializer:, event_type:, event_id:, data:, metadata:, timestamp: nil, valid_at: nil)
|
274
311
|
extract_timestamp = lambda { |m| (m[:timestamp] || Time.parse(m.fetch("timestamp"))).iso8601 }
|
275
312
|
|
276
|
-
mapper.
|
277
|
-
|
278
|
-
.new(
|
313
|
+
mapper.records_to_events(
|
314
|
+
[
|
315
|
+
SerializedRecord.new(
|
279
316
|
event_type: event_type,
|
280
317
|
event_id: event_id,
|
281
318
|
data: data,
|
282
319
|
metadata: metadata,
|
283
320
|
timestamp: timestamp || timestamp_ = extract_timestamp[serializer.load(metadata)],
|
284
|
-
valid_at: valid_at || timestamp_
|
285
|
-
)
|
286
|
-
|
287
|
-
)
|
321
|
+
valid_at: valid_at || timestamp_,
|
322
|
+
).deserialize(serializer),
|
323
|
+
],
|
324
|
+
).first
|
288
325
|
end
|
289
326
|
|
290
327
|
# Read additional metadata which will be added for published events
|
@@ -339,13 +376,12 @@ module RubyEventStore
|
|
339
376
|
private
|
340
377
|
|
341
378
|
def transform(events)
|
342
|
-
|
379
|
+
mapper.events_to_records(events)
|
343
380
|
end
|
344
381
|
|
345
382
|
def enrich_events_metadata(events)
|
346
383
|
events = Array(events)
|
347
384
|
events.each { |event| enrich_event_metadata(event) }
|
348
|
-
events
|
349
385
|
end
|
350
386
|
|
351
387
|
def enrich_event_metadata(event)
|
@@ -361,6 +397,10 @@ module RubyEventStore
|
|
361
397
|
|
362
398
|
protected
|
363
399
|
|
400
|
+
def batch_mapper?(mapper)
|
401
|
+
%i[events_to_records records_to_events].all? { |m| mapper.respond_to? m }
|
402
|
+
end
|
403
|
+
|
364
404
|
def metadata=(value)
|
365
405
|
@metadata.value = value
|
366
406
|
end
|
@@ -373,6 +413,6 @@ module RubyEventStore
|
|
373
413
|
-> { SecureRandom.uuid }
|
374
414
|
end
|
375
415
|
|
376
|
-
attr_reader :repository, :mapper, :
|
416
|
+
attr_reader :repository, :mapper, :broker, :clock, :correlation_id_generator, :event_type_resolver
|
377
417
|
end
|
378
418
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyEventStore
|
4
|
+
class ComposedBroker
|
5
|
+
def initialize(*brokers, multiple_brokers: false)
|
6
|
+
@brokers = brokers
|
7
|
+
@multiple_brokers = multiple_brokers
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(event, record, topic)
|
11
|
+
brokers = verified_brokers(topic)
|
12
|
+
if brokers.empty?
|
13
|
+
warn "No broker found for topic '#{topic}'. Event #{event.event_id} will not be processed."
|
14
|
+
else
|
15
|
+
brokers.each { |broker| broker.call(event, record, topic) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_subscription(subscriber, topics)
|
20
|
+
topics.each do |topic|
|
21
|
+
brokers = verified_brokers(topic)
|
22
|
+
raise SubscriptionsNotSupported, "No broker found for topic '#{topic}'." if brokers.empty?
|
23
|
+
brokers.each { |broker| broker.add_subscription(subscriber, topic) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_global_subscription(subscriber)
|
28
|
+
brokers = verified_brokers(nil)
|
29
|
+
raise SubscriptionsNotSupported, "No broker found for global subscription." if brokers.empty?
|
30
|
+
brokers.each { |broker| broker.add_global_subscription(subscriber) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_thread_subscription(subscriber, topics)
|
34
|
+
topics.each do |topic|
|
35
|
+
brokers = verified_brokers(topic)
|
36
|
+
raise SubscriptionsNotSupported, "No broker found for topic '#{topic}'." if brokers.empty?
|
37
|
+
brokers.each { |broker| broker.add_thread_subscription(subscriber, topic) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_thread_global_subscription(subscriber)
|
42
|
+
brokers = verified_brokers(nil)
|
43
|
+
raise SubscriptionsNotSupported, "No broker found for global subscription." if brokers.empty?
|
44
|
+
brokers.each { |broker| broker.add_thread_global_subscription(subscriber) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def all_subscriptions_for(topic)
|
48
|
+
@brokers.flat_map { |broker| broker.all_subscriptions_for(topic) }
|
49
|
+
end
|
50
|
+
|
51
|
+
def verify(topic)
|
52
|
+
!verified_brokers(topic).empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def verified_brokers(topic)
|
58
|
+
if @multiple_brokers
|
59
|
+
@brokers.select { |broker| broker.verify(topic) }
|
60
|
+
else
|
61
|
+
[@brokers.find { |broker| broker.verify(topic) }].compact
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -107,16 +107,14 @@ module RubyEventStore
|
|
107
107
|
records.each do |record|
|
108
108
|
read_event(record.event_id)
|
109
109
|
serialized_record =
|
110
|
-
Record
|
111
|
-
.
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
)
|
119
|
-
.serialize(serializer)
|
110
|
+
Record.new(
|
111
|
+
event_id: record.event_id,
|
112
|
+
event_type: record.event_type,
|
113
|
+
data: record.data,
|
114
|
+
metadata: record.metadata,
|
115
|
+
timestamp: Time.iso8601(storage.fetch(record.event_id).timestamp),
|
116
|
+
valid_at: record.valid_at,
|
117
|
+
).serialize(serializer)
|
120
118
|
storage[record.event_id] = serialized_record
|
121
119
|
end
|
122
120
|
end
|
@@ -144,33 +142,35 @@ module RubyEventStore
|
|
144
142
|
def read_scope(spec)
|
145
143
|
serialized_records = serialized_records_of_stream(spec.stream)
|
146
144
|
serialized_records = ordered(serialized_records, spec)
|
147
|
-
serialized_records =
|
148
|
-
.with_ids?
|
149
|
-
serialized_records =
|
150
|
-
.with_types?
|
145
|
+
serialized_records =
|
146
|
+
serialized_records.select { |e| spec.with_ids.any? { |x| x.eql?(e.event_id) } } if spec.with_ids?
|
147
|
+
serialized_records =
|
148
|
+
serialized_records.select { |e| spec.with_types.any? { |x| x.eql?(e.event_type) } } if spec.with_types?
|
151
149
|
serialized_records = serialized_records.reverse if spec.backward?
|
152
150
|
serialized_records = serialized_records.drop(index_of(serialized_records, spec.start) + 1) if spec.start
|
153
151
|
serialized_records = serialized_records.take(index_of(serialized_records, spec.stop)) if spec.stop
|
154
152
|
serialized_records = serialized_records.take(spec.limit) if spec.limit?
|
155
|
-
serialized_records = serialized_records.select { |sr| Time.iso8601(time_comparison_field(spec, sr)) < spec.older_than } if spec
|
156
|
-
.older_than
|
157
153
|
serialized_records =
|
158
|
-
serialized_records.select
|
159
|
-
|
160
|
-
|
161
|
-
|
154
|
+
serialized_records.select do |sr|
|
155
|
+
Time.iso8601(time_comparison_field(spec, sr)) < spec.older_than
|
156
|
+
end if spec.older_than
|
157
|
+
serialized_records =
|
158
|
+
serialized_records.select do |sr|
|
159
|
+
Time.iso8601(time_comparison_field(spec, sr)) <= spec.older_than_or_equal
|
160
|
+
end if spec.older_than_or_equal
|
162
161
|
serialized_records =
|
163
|
-
serialized_records.select
|
164
|
-
|
162
|
+
serialized_records.select do |sr|
|
163
|
+
Time.iso8601(time_comparison_field(spec, sr)) > spec.newer_than
|
164
|
+
end if spec.newer_than
|
165
|
+
serialized_records =
|
166
|
+
serialized_records.select do |sr|
|
167
|
+
Time.iso8601(time_comparison_field(spec, sr)) >= spec.newer_than_or_equal
|
168
|
+
end if spec.newer_than_or_equal
|
165
169
|
serialized_records
|
166
170
|
end
|
167
171
|
|
168
172
|
def time_comparison_field(spec, sr)
|
169
|
-
|
170
|
-
sr.valid_at
|
171
|
-
else
|
172
|
-
sr.timestamp
|
173
|
-
end
|
173
|
+
spec.time_sort_by_as_of? ? sr.valid_at : sr.timestamp
|
174
174
|
end
|
175
175
|
|
176
176
|
def read_event(event_id)
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyEventStore
|
4
|
+
class InstrumentedBroker
|
5
|
+
def initialize(broker, instrumentation)
|
6
|
+
@broker = broker
|
7
|
+
@instrumentation = instrumentation
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(topic, event, record)
|
11
|
+
instrumentation.instrument("call.broker.rails_event_store", topic: topic, event: event, record: record) do
|
12
|
+
if broker.public_method(:call).arity == 3
|
13
|
+
broker.call(topic, event, record)
|
14
|
+
else
|
15
|
+
warn <<~EOW
|
16
|
+
Message broker shall support topics.
|
17
|
+
Topic WILL BE IGNORED in the current broker.
|
18
|
+
Modify the broker implementation to pass topic as an argument to broker.call method.
|
19
|
+
EOW
|
20
|
+
broker.call(event, record)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_subscription(subscriber, topics)
|
26
|
+
instrumentation.instrument("add_subscription.broker.rails_event_store", subscriber: subscriber, topics: topics) do
|
27
|
+
broker.add_subscription(subscriber, topics)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_global_subscription(subscriber)
|
32
|
+
instrumentation.instrument("add_global_subscription.broker.rails_event_store", subscriber: subscriber) do
|
33
|
+
broker.add_global_subscription(subscriber)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_thread_subscription(subscriber, topics)
|
38
|
+
instrumentation.instrument(
|
39
|
+
"add_thread_subscription.broker.rails_event_store",
|
40
|
+
subscriber: subscriber,
|
41
|
+
topics: topics,
|
42
|
+
) { broker.add_thread_subscription(subscriber, topics) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_thread_global_subscription(subscriber)
|
46
|
+
instrumentation.instrument("add_thread_global_subscription.broker.rails_event_store", subscriber: subscriber) do
|
47
|
+
broker.add_thread_global_subscription(subscriber)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def all_subscriptions_for(topic)
|
52
|
+
instrumentation.instrument("all_subscriptions_for.broker.rails_event_store", topic: topic) do
|
53
|
+
broker.all_subscriptions_for(topic)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def method_missing(method_name, *arguments, **keyword_arguments, &block)
|
58
|
+
if respond_to?(method_name)
|
59
|
+
broker.public_send(method_name, *arguments, **keyword_arguments, &block)
|
60
|
+
else
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def respond_to_missing?(method_name, _include_private)
|
66
|
+
broker.respond_to?(method_name)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
attr_reader :instrumentation, :broker
|
72
|
+
end
|
73
|
+
end
|
@@ -14,9 +14,7 @@ module RubyEventStore
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def add_global_subscription(subscriber)
|
17
|
-
instrument(subscriber: subscriber)
|
18
|
-
subscriptions.add_global_subscription(subscriber)
|
19
|
-
end
|
17
|
+
instrument(subscriber: subscriber) { subscriptions.add_global_subscription(subscriber) }
|
20
18
|
end
|
21
19
|
|
22
20
|
def add_thread_subscription(subscriber, event_types)
|
@@ -26,9 +24,7 @@ module RubyEventStore
|
|
26
24
|
end
|
27
25
|
|
28
26
|
def add_thread_global_subscription(subscriber)
|
29
|
-
instrument(subscriber: subscriber)
|
30
|
-
subscriptions.add_thread_global_subscription(subscriber)
|
31
|
-
end
|
27
|
+
instrument(subscriber: subscriber) { subscriptions.add_thread_global_subscription(subscriber) }
|
32
28
|
end
|
33
29
|
|
34
30
|
def method_missing(method_name, *arguments, &block)
|
@@ -48,11 +44,7 @@ module RubyEventStore
|
|
48
44
|
def instrument(args)
|
49
45
|
instrumentation.instrument("add.subscriptions.rails_event_store", args) do
|
50
46
|
unsubscribe = yield
|
51
|
-
->() {
|
52
|
-
instrumentation.instrument("remove.subscriptions.rails_event_store", args) do
|
53
|
-
unsubscribe.call
|
54
|
-
end
|
55
|
-
}
|
47
|
+
-> { instrumentation.instrument("remove.subscriptions.rails_event_store", args) { unsubscribe.call } }
|
56
48
|
end
|
57
49
|
end
|
58
50
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyEventStore
|
4
|
+
module Mappers
|
5
|
+
class BatchMapper
|
6
|
+
def initialize(mapper = Default.new)
|
7
|
+
@mapper = mapper
|
8
|
+
end
|
9
|
+
|
10
|
+
def events_to_records(events)
|
11
|
+
events.map { |event| @mapper.event_to_record(event) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def records_to_events(records)
|
15
|
+
records.map { |record| @mapper.record_to_event(record) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -20,7 +20,14 @@ module RubyEventStore
|
|
20
20
|
crypto = prepare_decrypt(cipher)
|
21
21
|
crypto.iv = iv
|
22
22
|
crypto.key = key
|
23
|
-
ciphertext =
|
23
|
+
ciphertext =
|
24
|
+
(
|
25
|
+
if crypto.authenticated?
|
26
|
+
ciphertext_from_authenticated(crypto, message)
|
27
|
+
else
|
28
|
+
message
|
29
|
+
end
|
30
|
+
)
|
24
31
|
(crypto.update(ciphertext) + crypto.final).force_encoding("UTF-8")
|
25
32
|
end
|
26
33
|
|
@@ -7,8 +7,8 @@ module RubyEventStore
|
|
7
7
|
super(
|
8
8
|
Pipeline.new(
|
9
9
|
Transformation::Encryption.new(key_repository, serializer: serializer, forgotten_data: forgotten_data),
|
10
|
-
Transformation::SymbolizeMetadataKeys.new
|
11
|
-
)
|
10
|
+
Transformation::SymbolizeMetadataKeys.new,
|
11
|
+
),
|
12
12
|
)
|
13
13
|
end
|
14
14
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyEventStore
|
4
|
+
module Mappers
|
5
|
+
class InstrumentedBatchMapper
|
6
|
+
def initialize(mapper, instrumentation)
|
7
|
+
@mapper = mapper
|
8
|
+
@instrumentation = instrumentation
|
9
|
+
end
|
10
|
+
|
11
|
+
def events_to_records(events)
|
12
|
+
instrumentation.instrument("events_to_records.mapper.rails_event_store", domain_events: events) do
|
13
|
+
mapper.events_to_records(events)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def records_to_events(records)
|
18
|
+
instrumentation.instrument("records_to_events.mapper.rails_event_store", records: records) do
|
19
|
+
mapper.records_to_events(records)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :instrumentation, :mapper
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -14,18 +14,16 @@ module RubyEventStore
|
|
14
14
|
data: event.data,
|
15
15
|
event_type: event.event_type,
|
16
16
|
timestamp: timestamp,
|
17
|
-
valid_at: valid_at
|
17
|
+
valid_at: valid_at,
|
18
18
|
)
|
19
19
|
end
|
20
20
|
|
21
21
|
def load(record)
|
22
|
-
Object
|
23
|
-
|
24
|
-
.
|
25
|
-
|
26
|
-
|
27
|
-
metadata: record.metadata.merge(timestamp: record.timestamp, valid_at: record.valid_at)
|
28
|
-
)
|
22
|
+
Object.const_get(record.event_type).new(
|
23
|
+
event_id: record.event_id,
|
24
|
+
data: record.data,
|
25
|
+
metadata: record.metadata.merge(timestamp: record.timestamp, valid_at: record.valid_at),
|
26
|
+
)
|
29
27
|
rescue NameError
|
30
28
|
Event.new(
|
31
29
|
event_id: record.event_id,
|
@@ -34,8 +32,8 @@ module RubyEventStore
|
|
34
32
|
record.metadata.merge(
|
35
33
|
timestamp: record.timestamp,
|
36
34
|
valid_at: record.valid_at,
|
37
|
-
event_type: record.event_type
|
38
|
-
)
|
35
|
+
event_type: record.event_type,
|
36
|
+
),
|
39
37
|
)
|
40
38
|
end
|
41
39
|
end
|
@@ -37,7 +37,7 @@ module RubyEventStore
|
|
37
37
|
data: encrypt_data(deep_dup(data), crypto_description),
|
38
38
|
metadata: metadata,
|
39
39
|
timestamp: record.timestamp,
|
40
|
-
valid_at: record.valid_at
|
40
|
+
valid_at: record.valid_at,
|
41
41
|
)
|
42
42
|
end
|
43
43
|
|
@@ -51,7 +51,7 @@ module RubyEventStore
|
|
51
51
|
data: decrypt_data(record.data, crypto_description),
|
52
52
|
metadata: metadata,
|
53
53
|
timestamp: record.timestamp,
|
54
|
-
valid_at: record.valid_at
|
54
|
+
valid_at: record.valid_at,
|
55
55
|
)
|
56
56
|
end
|
57
57
|
|
@@ -66,7 +66,6 @@ module RubyEventStore
|
|
66
66
|
def deep_dup(hash)
|
67
67
|
duplicate = hash.dup
|
68
68
|
duplicate.each { |k, v| duplicate[k] = v.instance_of?(Hash) ? deep_dup(v) : v }
|
69
|
-
duplicate
|
70
69
|
end
|
71
70
|
|
72
71
|
def encryption_metadata(data, schema)
|