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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruby_event_store/broker.rb +11 -7
  3. data/lib/ruby_event_store/client.rb +60 -20
  4. data/lib/ruby_event_store/composed_broker.rb +65 -0
  5. data/lib/ruby_event_store/errors.rb +1 -0
  6. data/lib/ruby_event_store/in_memory_repository.rb +27 -27
  7. data/lib/ruby_event_store/instrumented_broker.rb +73 -0
  8. data/lib/ruby_event_store/instrumented_subscriptions.rb +3 -11
  9. data/lib/ruby_event_store/mappers/batch_mapper.rb +19 -0
  10. data/lib/ruby_event_store/mappers/default.rb +2 -2
  11. data/lib/ruby_event_store/mappers/encryption_key.rb +8 -1
  12. data/lib/ruby_event_store/mappers/encryption_mapper.rb +2 -2
  13. data/lib/ruby_event_store/mappers/instrumented_batch_mapper.rb +28 -0
  14. data/lib/ruby_event_store/mappers/transformation/domain_event.rb +8 -10
  15. data/lib/ruby_event_store/mappers/transformation/encryption.rb +2 -3
  16. data/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +1 -1
  17. data/lib/ruby_event_store/mappers/transformation/preserve_types.rb +11 -19
  18. data/lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb +1 -1
  19. data/lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb +1 -1
  20. data/lib/ruby_event_store/record.rb +9 -10
  21. data/lib/ruby_event_store/serialized_record.rb +2 -2
  22. data/lib/ruby_event_store/spec/broker_lint.rb +27 -10
  23. data/lib/ruby_event_store/spec/dispatcher_lint.rb +1 -1
  24. data/lib/ruby_event_store/spec/event_lint.rb +3 -3
  25. data/lib/ruby_event_store/spec/event_repository_lint.rb +228 -189
  26. data/lib/ruby_event_store/spec/mapper_lint.rb +2 -2
  27. data/lib/ruby_event_store/spec/scheduler_lint.rb +1 -1
  28. data/lib/ruby_event_store/spec/subscriptions_lint.rb +21 -20
  29. data/lib/ruby_event_store/specification.rb +5 -5
  30. data/lib/ruby_event_store/specification_reader.rb +6 -2
  31. data/lib/ruby_event_store/specification_result.rb +32 -34
  32. data/lib/ruby_event_store/subscriptions.rb +20 -20
  33. data/lib/ruby_event_store/transform_keys.rb +1 -3
  34. data/lib/ruby_event_store/version.rb +1 -1
  35. data/lib/ruby_event_store.rb +5 -1
  36. metadata +7 -3
@@ -43,7 +43,6 @@ module RubyEventStore
43
43
  @resolver = resolver
44
44
  end
45
45
 
46
-
47
46
  NULL_TYPE = NullType.new
48
47
  private_constant :NULL_TYPE
49
48
 
@@ -56,6 +55,7 @@ module RubyEventStore
56
55
  end
57
56
 
58
57
  private
58
+
59
59
  attr_reader :resolver, :types
60
60
  end
61
61
  private_constant :Registry
@@ -78,7 +78,7 @@ module RubyEventStore
78
78
  data: data,
79
79
  metadata: metadata,
80
80
  timestamp: record.timestamp,
81
- valid_at: record.valid_at
81
+ valid_at: record.valid_at,
82
82
  )
83
83
  end
84
84
 
@@ -100,7 +100,7 @@ module RubyEventStore
100
100
  data: data,
101
101
  metadata: metadata,
102
102
  timestamp: record.timestamp,
103
- valid_at: record.valid_at
103
+ valid_at: record.valid_at,
104
104
  )
105
105
  end
106
106
 
@@ -108,6 +108,7 @@ module RubyEventStore
108
108
  private_constant :DEFAULT_STORE_TYPE
109
109
 
110
110
  private
111
+
111
112
  attr_reader :registry
112
113
 
113
114
  def transform_hash(argument)
@@ -125,16 +126,12 @@ module RubyEventStore
125
126
  end
126
127
  end
127
128
 
128
- def store_types(argument)
129
- argument.each_with_object({}) do |(key, value), hash|
130
- hash[transform(key)] = [store_type(key), store_type(value)]
131
- end
132
- end
133
-
134
129
  def store_type(argument)
135
130
  case argument
136
131
  when Hash
137
- store_types(argument)
132
+ argument.reduce({}) do |hash, (key, value)|
133
+ hash.merge(transform(key) => [store_type(key), store_type(value)])
134
+ end
138
135
  when Array
139
136
  argument.map { |i| store_type(i) }
140
137
  else
@@ -142,18 +139,13 @@ module RubyEventStore
142
139
  end
143
140
  end
144
141
 
145
- def restore_types(argument, types)
146
- argument.each_with_object({}) do |(key, value), hash|
147
- key_type, value_type = types.fetch(key.to_sym) { types.fetch(key.to_s) }
148
- restored_key = restore_type(key, key_type)
149
- hash[restored_key] = restore_type(value, value_type)
150
- end
151
- end
152
-
153
142
  def restore_type(argument, type)
154
143
  case type
155
144
  when Hash
156
- restore_types(argument, type)
145
+ argument.reduce({}) do |hash, (key, value)|
146
+ key_type, value_type = type.fetch(key.to_sym) { type.fetch(key) }
147
+ hash.merge(restore_type(key, key_type) => restore_type(value, value_type))
148
+ end
157
149
  when Array
158
150
  argument.each_with_index.map { |a, idx| restore_type(a, type.fetch(idx)) }
159
151
  else
@@ -21,7 +21,7 @@ module RubyEventStore
21
21
  data: record.data,
22
22
  metadata: TransformKeys.stringify(record.metadata),
23
23
  timestamp: record.timestamp,
24
- valid_at: record.valid_at
24
+ valid_at: record.valid_at,
25
25
  )
26
26
  end
27
27
  end
@@ -21,7 +21,7 @@ module RubyEventStore
21
21
  data: record.data,
22
22
  metadata: TransformKeys.symbolize(record.metadata),
23
23
  timestamp: record.timestamp,
24
- valid_at: record.valid_at
24
+ valid_at: record.valid_at,
25
25
  )
26
26
  end
27
27
  end
@@ -34,20 +34,19 @@ module RubyEventStore
34
34
  metadata: metadata,
35
35
  event_type: event_type,
36
36
  timestamp: timestamp,
37
- valid_at: valid_at
37
+ valid_at: valid_at,
38
38
  }
39
39
  end
40
40
 
41
41
  def serialize(serializer)
42
- @serialized_records[serializer] ||=
43
- SerializedRecord.new(
44
- event_id: event_id,
45
- event_type: event_type,
46
- data: serializer.dump(data),
47
- metadata: serializer.dump(metadata),
48
- timestamp: timestamp.iso8601(TIMESTAMP_PRECISION),
49
- valid_at: valid_at.iso8601(TIMESTAMP_PRECISION)
50
- )
42
+ @serialized_records[serializer] ||= SerializedRecord.new(
43
+ event_id: event_id,
44
+ event_type: event_type,
45
+ data: serializer.dump(data),
46
+ metadata: serializer.dump(metadata),
47
+ timestamp: timestamp.iso8601(TIMESTAMP_PRECISION),
48
+ valid_at: valid_at.iso8601(TIMESTAMP_PRECISION),
49
+ )
51
50
  end
52
51
 
53
52
  alias_method :eql?, :==
@@ -33,7 +33,7 @@ module RubyEventStore
33
33
  metadata: metadata,
34
34
  event_type: event_type,
35
35
  timestamp: timestamp,
36
- valid_at: valid_at
36
+ valid_at: valid_at,
37
37
  }
38
38
  end
39
39
 
@@ -44,7 +44,7 @@ module RubyEventStore
44
44
  data: serializer.load(data),
45
45
  metadata: serializer.load(metadata),
46
46
  timestamp: Time.iso8601(timestamp),
47
- valid_at: Time.iso8601(valid_at)
47
+ valid_at: Time.iso8601(valid_at),
48
48
  )
49
49
  end
50
50
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.shared_examples :broker do |broker_klass|
3
+ RSpec.shared_examples "broker" do |broker_klass|
4
4
  let(:event) { instance_double(::RubyEventStore::Event, event_type: "EventType") }
5
5
  let(:record) { instance_double(::RubyEventStore::Record) }
6
6
  let(:handler) { HandlerClass.new }
@@ -11,32 +11,38 @@ RSpec.shared_examples :broker do |broker_klass|
11
11
  specify "no dispatch when no subscriptions" do
12
12
  expect(subscriptions).to receive(:all_for).with("EventType").and_return([])
13
13
  expect(dispatcher).not_to receive(:call)
14
- broker.call(event, record)
14
+ broker.call(event.event_type, event, record)
15
+ end
16
+
17
+ specify "calls subscription using topic" do
18
+ expect(subscriptions).to receive(:all_for).with("topic").and_return([handler])
19
+ expect(dispatcher).to receive(:call).with(handler, event, record)
20
+ broker.call("topic", event, record)
15
21
  end
16
22
 
17
23
  specify "calls subscription" do
18
24
  expect(subscriptions).to receive(:all_for).with("EventType").and_return([handler])
19
25
  expect(dispatcher).to receive(:call).with(handler, event, record)
20
- broker.call(event, record)
26
+ broker.call(event.event_type, event, record)
21
27
  end
22
28
 
23
29
  specify "calls subscribed class" do
24
30
  expect(subscriptions).to receive(:all_for).with("EventType").and_return([HandlerClass])
25
31
  expect(dispatcher).to receive(:call).with(HandlerClass, event, record)
26
- broker.call(event, record)
32
+ broker.call(event.event_type, event, record)
27
33
  end
28
34
 
29
35
  specify "calls all subscriptions" do
30
36
  expect(subscriptions).to receive(:all_for).with("EventType").and_return([handler, HandlerClass])
31
37
  expect(dispatcher).to receive(:call).with(handler, event, record)
32
38
  expect(dispatcher).to receive(:call).with(HandlerClass, event, record)
33
- broker.call(event, record)
39
+ broker.call(event.event_type, event, record)
34
40
  end
35
41
 
36
42
  specify "raise error when no subscriber" do
37
43
  expect { broker.add_subscription(nil, []) }.to raise_error(
38
44
  RubyEventStore::SubscriberNotExist,
39
- "subscriber must be first argument or block"
45
+ "subscriber must be first argument or block",
40
46
  )
41
47
  expect { broker.add_global_subscription(nil) }.to raise_error(RubyEventStore::SubscriberNotExist),
42
48
  "subscriber must be first argument or block"
@@ -50,19 +56,19 @@ RSpec.shared_examples :broker do |broker_klass|
50
56
  allow(dispatcher).to receive(:verify).and_return(false)
51
57
  expect { broker.add_subscription(HandlerClass, []) }.to raise_error(
52
58
  RubyEventStore::InvalidHandler,
53
- /Handler HandlerClass is invalid for dispatcher .*Dispatcher/
59
+ /Handler HandlerClass is invalid for dispatcher .*Dispatcher/,
54
60
  )
55
61
  expect { broker.add_global_subscription(HandlerClass) }.to raise_error(
56
62
  RubyEventStore::InvalidHandler,
57
- /is invalid for dispatcher/
63
+ /is invalid for dispatcher/,
58
64
  )
59
65
  expect { broker.add_thread_subscription(HandlerClass, []) }.to raise_error(
60
66
  RubyEventStore::InvalidHandler,
61
- /is invalid for dispatcher/
67
+ /is invalid for dispatcher/,
62
68
  )
63
69
  expect { broker.add_thread_global_subscription(HandlerClass) }.to raise_error(
64
70
  RubyEventStore::InvalidHandler,
65
- /is invalid for dispatcher/
71
+ /is invalid for dispatcher/,
66
72
  )
67
73
  end
68
74
 
@@ -90,6 +96,17 @@ RSpec.shared_examples :broker do |broker_klass|
90
96
  broker.add_thread_global_subscription(handler)
91
97
  end
92
98
 
99
+ specify "all_subscriptions_for" do
100
+ handler = Subscribers::ValidHandler.new
101
+ broker.add_subscription(handler, ["ProductAdded"])
102
+ block = Proc.new { "Event published!" }
103
+ broker.add_subscription(block, ["OrderCreated"])
104
+
105
+ expect(broker.all_subscriptions_for("ProductAdded")).to eq [handler]
106
+ expect(broker.all_subscriptions_for("OrderCreated")).to eq [block]
107
+ expect(broker.all_subscriptions_for("NotExistingOne")).to eq []
108
+ end
109
+
93
110
  private
94
111
 
95
112
  class HandlerClass
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.shared_examples :dispatcher do |dispatcher|
3
+ RSpec.shared_examples "dispatcher" do |dispatcher|
4
4
  specify "#call" do
5
5
  expect(dispatcher).to respond_to(:call).with(3).arguments
6
6
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.shared_examples :event do |event_class, data, metadata|
3
+ RSpec.shared_examples "event" do |event_class, data, metadata|
4
4
  it "allows initialization" do
5
5
  expect {
6
6
  event_class.new(event_id: Object.new, data: data || Object.new, metadata: metadata || {})
@@ -11,7 +11,7 @@ RSpec.shared_examples :event do |event_class, data, metadata|
11
11
  event = event_class.new
12
12
  expect(event.event_id).to be_an_instance_of(String)
13
13
  expect(event.event_id).not_to eq ""
14
- expect(event.event_id).not_to eq nil
14
+ expect(event.event_id).not_to be_nil
15
15
  end
16
16
 
17
17
  it "provides message_id as string" do
@@ -33,7 +33,7 @@ RSpec.shared_examples :event do |event_class, data, metadata|
33
33
  event = event_class.new
34
34
  expect(event.event_type).to be_an_instance_of(String)
35
35
  expect(event.event_type).not_to eq ""
36
- expect(event.event_type).not_to eq nil
36
+ expect(event.event_type).not_to be_nil
37
37
  end
38
38
 
39
39
  it "provides data" do