ruby_event_store 2.15.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 -28
- 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 -6
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
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "ostruct"
|
4
3
|
module RubyEventStore
|
5
4
|
class InMemoryRepository
|
6
5
|
class UnsupportedVersionAnyUsage < StandardError
|
@@ -108,16 +107,14 @@ module RubyEventStore
|
|
108
107
|
records.each do |record|
|
109
108
|
read_event(record.event_id)
|
110
109
|
serialized_record =
|
111
|
-
Record
|
112
|
-
.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
)
|
120
|
-
.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)
|
121
118
|
storage[record.event_id] = serialized_record
|
122
119
|
end
|
123
120
|
end
|
@@ -145,33 +142,35 @@ module RubyEventStore
|
|
145
142
|
def read_scope(spec)
|
146
143
|
serialized_records = serialized_records_of_stream(spec.stream)
|
147
144
|
serialized_records = ordered(serialized_records, spec)
|
148
|
-
serialized_records =
|
149
|
-
.with_ids?
|
150
|
-
serialized_records =
|
151
|
-
.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?
|
152
149
|
serialized_records = serialized_records.reverse if spec.backward?
|
153
150
|
serialized_records = serialized_records.drop(index_of(serialized_records, spec.start) + 1) if spec.start
|
154
151
|
serialized_records = serialized_records.take(index_of(serialized_records, spec.stop)) if spec.stop
|
155
152
|
serialized_records = serialized_records.take(spec.limit) if spec.limit?
|
156
|
-
serialized_records = serialized_records.select { |sr| Time.iso8601(time_comparison_field(spec, sr)) < spec.older_than } if spec
|
157
|
-
.older_than
|
158
153
|
serialized_records =
|
159
|
-
serialized_records.select
|
160
|
-
|
161
|
-
|
162
|
-
|
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
|
163
161
|
serialized_records =
|
164
|
-
serialized_records.select
|
165
|
-
|
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
|
166
169
|
serialized_records
|
167
170
|
end
|
168
171
|
|
169
172
|
def time_comparison_field(spec, sr)
|
170
|
-
|
171
|
-
sr.valid_at
|
172
|
-
else
|
173
|
-
sr.timestamp
|
174
|
-
end
|
173
|
+
spec.time_sort_by_as_of? ? sr.valid_at : sr.timestamp
|
175
174
|
end
|
176
175
|
|
177
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)
|