ruby_event_store 0.39.0 → 0.40.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruby_event_store.rb +24 -6
  3. data/lib/ruby_event_store/broker.rb +43 -0
  4. data/lib/ruby_event_store/client.rb +3 -3
  5. data/lib/ruby_event_store/dispatcher.rb +18 -0
  6. data/lib/ruby_event_store/errors.rb +13 -12
  7. data/lib/ruby_event_store/event.rb +1 -0
  8. data/lib/ruby_event_store/mappers.rb +10 -0
  9. data/lib/ruby_event_store/mappers/default.rb +8 -24
  10. data/lib/ruby_event_store/mappers/encryption_key.rb +72 -0
  11. data/lib/ruby_event_store/mappers/encryption_mapper.rb +8 -239
  12. data/lib/ruby_event_store/mappers/forgotten_data.rb +28 -0
  13. data/lib/ruby_event_store/mappers/in_memory_encryption_key_repository.rb +32 -0
  14. data/lib/ruby_event_store/mappers/null_mapper.rb +2 -18
  15. data/lib/ruby_event_store/mappers/pipeline.rb +29 -0
  16. data/lib/ruby_event_store/mappers/pipeline_mapper.rb +20 -0
  17. data/lib/ruby_event_store/mappers/protobuf.rb +9 -47
  18. data/lib/ruby_event_store/mappers/transformation/domain_event.rb +24 -0
  19. data/lib/ruby_event_store/mappers/transformation/encryption.rb +125 -0
  20. data/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +22 -0
  21. data/lib/ruby_event_store/mappers/transformation/item.rb +55 -0
  22. data/lib/ruby_event_store/mappers/transformation/proto_event.rb +15 -0
  23. data/lib/ruby_event_store/mappers/transformation/protobuf_encoder.rb +28 -0
  24. data/lib/ruby_event_store/mappers/transformation/protobuf_nested_struct_metadata.rb +29 -0
  25. data/lib/ruby_event_store/mappers/transformation/serialization.rb +32 -0
  26. data/lib/ruby_event_store/mappers/transformation/serialized_record.rb +25 -0
  27. data/lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb +22 -0
  28. data/lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb +22 -0
  29. data/lib/ruby_event_store/pub_sub.rb +21 -0
  30. data/lib/ruby_event_store/spec/broker_lint.rb +3 -3
  31. data/lib/ruby_event_store/spec/dispatcher_lint.rb +2 -2
  32. data/lib/ruby_event_store/subscriptions.rb +108 -0
  33. data/lib/ruby_event_store/version.rb +1 -1
  34. metadata +24 -6
  35. data/lib/ruby_event_store/pub_sub/broker.rb +0 -45
  36. data/lib/ruby_event_store/pub_sub/dispatcher.rb +0 -20
  37. data/lib/ruby_event_store/pub_sub/subscriptions.rb +0 -110
@@ -0,0 +1,28 @@
1
+ module RubyEventStore
2
+ module Mappers
3
+ module Transformation
4
+ class ProtobufEncoder
5
+ def dump(item)
6
+ item.merge(data: encode_data(item.data))
7
+ end
8
+
9
+ def load(item)
10
+ item.merge(data: load_data(item.event_type, item.data))
11
+ end
12
+
13
+ private
14
+ def encode_data(data)
15
+ begin
16
+ data.class.encode(data)
17
+ rescue NoMethodError
18
+ raise ProtobufEncodingFailed
19
+ end
20
+ end
21
+
22
+ def load_data(event_type, protobuf_data)
23
+ Google::Protobuf::DescriptorPool.generated_pool.lookup(event_type).msgclass.decode(protobuf_data)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ module RubyEventStore
2
+ module Mappers
3
+ module Transformation
4
+ class ProtobufNestedStructMetadata
5
+ def initialize
6
+ require_optional_dependency
7
+ end
8
+
9
+ def dump(item)
10
+ stringify = StringifyMetadataKeys.new
11
+ metadata = ProtobufNestedStruct::HashMapStringValue.dump(stringify.dump(item).metadata)
12
+ item.merge(metadata: metadata)
13
+ end
14
+
15
+ def load(item)
16
+ metadata = ProtobufNestedStruct::HashMapStringValue.load(item.metadata)
17
+ symbolize = SymbolizeMetadataKeys.new
18
+ symbolize.load(item.merge(metadata: metadata))
19
+ end
20
+
21
+ def require_optional_dependency
22
+ require 'protobuf_nested_struct'
23
+ rescue LoadError
24
+ raise LoadError, "cannot load such file -- protobuf_nested_struct. Add protobuf_nested_struct gem to Gemfile"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ require 'yaml'
2
+
3
+ module RubyEventStore
4
+ module Mappers
5
+ module Transformation
6
+ class Serialization
7
+ def initialize(serializer: YAML)
8
+ @serializer = serializer
9
+ end
10
+ attr_reader :serializer
11
+
12
+ def dump(item)
13
+ Item.new(
14
+ event_id: item.event_id,
15
+ metadata: serializer.dump(item.metadata),
16
+ data: serializer.dump(item.data),
17
+ event_type: item.event_type
18
+ )
19
+ end
20
+
21
+ def load(item)
22
+ Item.new(
23
+ event_id: item.event_id,
24
+ metadata: serializer.load(item.metadata),
25
+ data: serializer.load(item.data),
26
+ event_type: item.event_type
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ module RubyEventStore
2
+ module Mappers
3
+ module Transformation
4
+ class SerializedRecord
5
+ def dump(item)
6
+ RubyEventStore::SerializedRecord.new(
7
+ event_id: item.event_id,
8
+ metadata: item.metadata,
9
+ data: item.data,
10
+ event_type: item.event_type
11
+ )
12
+ end
13
+
14
+ def load(serialized_record)
15
+ Item.new(
16
+ event_id: serialized_record.event_id,
17
+ metadata: serialized_record.metadata,
18
+ data: serialized_record.data,
19
+ event_type: serialized_record.event_type
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ module RubyEventStore
2
+ module Mappers
3
+ module Transformation
4
+ class StringifyMetadataKeys
5
+ def dump(item)
6
+ stringify(item)
7
+ end
8
+
9
+ def load(item)
10
+ stringify(item)
11
+ end
12
+
13
+ private
14
+ def stringify(item)
15
+ item.merge(
16
+ metadata: TransformKeys.stringify(item.metadata),
17
+ )
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module RubyEventStore
2
+ module Mappers
3
+ module Transformation
4
+ class SymbolizeMetadataKeys
5
+ def dump(item)
6
+ symbolize(item)
7
+ end
8
+
9
+ def load(item)
10
+ symbolize(item)
11
+ end
12
+
13
+ private
14
+ def symbolize(item)
15
+ item.merge(
16
+ metadata: TransformKeys.symbolize(item.metadata),
17
+ )
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module RubyEventStore
2
+ module PubSub
3
+ def self.const_missing(const_name)
4
+ if const_name.equal?(:Subscriptions)
5
+ warn "`RubyEventStore::PubSub::Subscriptions` has been deprecated. Use `RubyEventStore::Subscriptions` instead."
6
+
7
+ Subscriptions
8
+ elsif const_name.equal?(:Broker)
9
+ warn "`RubyEventStore::PubSub::Broker` has been deprecated. Use `RubyEventStore::Broker` instead."
10
+
11
+ Broker
12
+ elsif const_name.equal?(:Dispatcher)
13
+ warn "`RubyEventStore::PubSub::Dispatcher` has been deprecated. Use `RubyEventStore::Dispatcher` instead."
14
+
15
+ Dispatcher
16
+ else
17
+ super
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,8 +2,8 @@ RSpec.shared_examples :broker do |broker_klass|
2
2
  let(:event) { instance_double(::RubyEventStore::Event, type: 'EventType') }
3
3
  let(:serialized_event) { instance_double(::RubyEventStore::SerializedRecord) }
4
4
  let(:handler) { HandlerClass.new }
5
- let(:subscriptions) { ::RubyEventStore::PubSub::Subscriptions.new }
6
- let(:dispatcher) { ::RubyEventStore::PubSub::Dispatcher.new }
5
+ let(:subscriptions) { ::RubyEventStore::Subscriptions.new }
6
+ let(:dispatcher) { ::RubyEventStore::Dispatcher.new }
7
7
  let(:broker) { broker_klass.new(subscriptions: subscriptions, dispatcher: dispatcher) }
8
8
 
9
9
  specify "no dispatch when no subscriptions" do
@@ -42,7 +42,7 @@ RSpec.shared_examples :broker do |broker_klass|
42
42
  allow(dispatcher).to receive(:verify).and_return(false)
43
43
  expect do
44
44
  broker.add_subscription(HandlerClass, [])
45
- end.to raise_error(RubyEventStore::InvalidHandler, /Handler HandlerClass is invalid for dispatcher .*PubSub::Dispatcher/)
45
+ end.to raise_error(RubyEventStore::InvalidHandler, /Handler HandlerClass is invalid for dispatcher .*Dispatcher/)
46
46
  expect do
47
47
  broker.add_global_subscription(HandlerClass)
48
48
  end.to raise_error(RubyEventStore::InvalidHandler, /is invalid for dispatcher/)
@@ -1,9 +1,9 @@
1
1
  RSpec.shared_examples :dispatcher do |dispatcher|
2
2
  specify "#call" do
3
- silence_warnings { expect(dispatcher).to respond_to(:call).with(3).arguments }
3
+ expect(dispatcher).to respond_to(:call).with(3).arguments
4
4
  end
5
5
 
6
6
  specify "#verify" do
7
- silence_warnings { expect(dispatcher).to respond_to(:verify).with(1).argument }
7
+ expect(dispatcher).to respond_to(:verify).with(1).argument
8
8
  end
9
9
  end
@@ -0,0 +1,108 @@
1
+ require 'concurrent'
2
+
3
+ module RubyEventStore
4
+ class Subscriptions
5
+ def initialize
6
+ @local = LocalSubscriptions.new
7
+ @global = GlobalSubscriptions.new
8
+ @thread = ThreadSubscriptions.new
9
+ end
10
+
11
+ def add_subscription(subscriber, event_types)
12
+ local.add(subscriber, event_types)
13
+ end
14
+
15
+ def add_global_subscription(subscriber)
16
+ global.add(subscriber)
17
+ end
18
+
19
+ def add_thread_subscription(subscriber, event_types)
20
+ thread.local.add(subscriber, event_types)
21
+ end
22
+
23
+ def add_thread_global_subscription(subscriber)
24
+ thread.global.add(subscriber)
25
+ end
26
+
27
+ def all_for(event_type)
28
+ [local, global, thread].map{|r| r.all_for(event_type)}.reduce(&:+)
29
+ end
30
+
31
+ private
32
+ attr_reader :local, :global, :thread
33
+
34
+ class ThreadSubscriptions
35
+ def initialize
36
+ @local = ThreadLocalSubscriptions.new
37
+ @global = ThreadGlobalSubscriptions.new
38
+ end
39
+ attr_reader :local, :global
40
+
41
+ def all_for(event_type)
42
+ [global, local].map{|r| r.all_for(event_type)}.reduce(&:+)
43
+ end
44
+ end
45
+
46
+ class LocalSubscriptions
47
+ def initialize
48
+ @subscriptions = Hash.new {|hsh, key| hsh[key] = [] }
49
+ end
50
+
51
+ def add(subscription, event_types)
52
+ event_types.each{ |type| @subscriptions[type.to_s] << subscription }
53
+ ->() {event_types.each{ |type| @subscriptions.fetch(type.to_s).delete(subscription) } }
54
+ end
55
+
56
+ def all_for(event_type)
57
+ @subscriptions[event_type]
58
+ end
59
+ end
60
+
61
+ class GlobalSubscriptions
62
+ def initialize
63
+ @subscriptions = []
64
+ end
65
+
66
+ def add(subscription)
67
+ @subscriptions << subscription
68
+ ->() { @subscriptions.delete(subscription) }
69
+ end
70
+
71
+ def all_for(_event_type)
72
+ @subscriptions
73
+ end
74
+ end
75
+
76
+ class ThreadLocalSubscriptions
77
+ def initialize
78
+ @subscriptions = Concurrent::ThreadLocalVar.new do
79
+ Hash.new {|hsh, key| hsh[key] = [] }
80
+ end
81
+ end
82
+
83
+ def add(subscription, event_types)
84
+ event_types.each{ |type| @subscriptions.value[type.to_s] << subscription }
85
+ ->() {event_types.each{ |type| @subscriptions.value.fetch(type.to_s).delete(subscription) } }
86
+ end
87
+
88
+ def all_for(event_type)
89
+ @subscriptions.value[event_type]
90
+ end
91
+ end
92
+
93
+ class ThreadGlobalSubscriptions
94
+ def initialize
95
+ @subscriptions = Concurrent::ThreadLocalVar.new([])
96
+ end
97
+
98
+ def add(subscription)
99
+ @subscriptions.value += [subscription]
100
+ ->() { @subscriptions.value -= [subscription] }
101
+ end
102
+
103
+ def all_for(_event_type)
104
+ @subscriptions.value
105
+ end
106
+ end
107
+ end
108
+ end
@@ -1,3 +1,3 @@
1
1
  module RubyEventStore
2
- VERSION = "0.39.0"
2
+ VERSION = "0.40.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_event_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.0
4
+ version: 0.40.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkency
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-24 00:00:00.000000000 Z
11
+ date: 2019-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -37,10 +37,12 @@ files:
37
37
  - README.md
38
38
  - lib/ruby_event_store.rb
39
39
  - lib/ruby_event_store/batch_enumerator.rb
40
+ - lib/ruby_event_store/broker.rb
40
41
  - lib/ruby_event_store/client.rb
41
42
  - lib/ruby_event_store/composed_dispatcher.rb
42
43
  - lib/ruby_event_store/constants.rb
43
44
  - lib/ruby_event_store/correlated_commands.rb
45
+ - lib/ruby_event_store/dispatcher.rb
44
46
  - lib/ruby_event_store/errors.rb
45
47
  - lib/ruby_event_store/event.rb
46
48
  - lib/ruby_event_store/expected_version.rb
@@ -49,16 +51,31 @@ files:
49
51
  - lib/ruby_event_store/instrumented_dispatcher.rb
50
52
  - lib/ruby_event_store/instrumented_repository.rb
51
53
  - lib/ruby_event_store/link_by_metadata.rb
54
+ - lib/ruby_event_store/mappers.rb
52
55
  - lib/ruby_event_store/mappers/default.rb
56
+ - lib/ruby_event_store/mappers/encryption_key.rb
53
57
  - lib/ruby_event_store/mappers/encryption_mapper.rb
58
+ - lib/ruby_event_store/mappers/forgotten_data.rb
59
+ - lib/ruby_event_store/mappers/in_memory_encryption_key_repository.rb
54
60
  - lib/ruby_event_store/mappers/instrumented_mapper.rb
55
61
  - lib/ruby_event_store/mappers/null_mapper.rb
62
+ - lib/ruby_event_store/mappers/pipeline.rb
63
+ - lib/ruby_event_store/mappers/pipeline_mapper.rb
56
64
  - lib/ruby_event_store/mappers/protobuf.rb
65
+ - lib/ruby_event_store/mappers/transformation/domain_event.rb
66
+ - lib/ruby_event_store/mappers/transformation/encryption.rb
67
+ - lib/ruby_event_store/mappers/transformation/event_class_remapper.rb
68
+ - lib/ruby_event_store/mappers/transformation/item.rb
69
+ - lib/ruby_event_store/mappers/transformation/proto_event.rb
70
+ - lib/ruby_event_store/mappers/transformation/protobuf_encoder.rb
71
+ - lib/ruby_event_store/mappers/transformation/protobuf_nested_struct_metadata.rb
72
+ - lib/ruby_event_store/mappers/transformation/serialization.rb
73
+ - lib/ruby_event_store/mappers/transformation/serialized_record.rb
74
+ - lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb
75
+ - lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb
57
76
  - lib/ruby_event_store/metadata.rb
58
77
  - lib/ruby_event_store/projection.rb
59
- - lib/ruby_event_store/pub_sub/broker.rb
60
- - lib/ruby_event_store/pub_sub/dispatcher.rb
61
- - lib/ruby_event_store/pub_sub/subscriptions.rb
78
+ - lib/ruby_event_store/pub_sub.rb
62
79
  - lib/ruby_event_store/serialized_record.rb
63
80
  - lib/ruby_event_store/spec/broker_lint.rb
64
81
  - lib/ruby_event_store/spec/dispatcher_lint.rb
@@ -71,6 +88,7 @@ files:
71
88
  - lib/ruby_event_store/specification_reader.rb
72
89
  - lib/ruby_event_store/specification_result.rb
73
90
  - lib/ruby_event_store/stream.rb
91
+ - lib/ruby_event_store/subscriptions.rb
74
92
  - lib/ruby_event_store/transform_keys.rb
75
93
  - lib/ruby_event_store/version.rb
76
94
  - ruby_event_store.gemspec
@@ -97,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
115
  - !ruby/object:Gem::Version
98
116
  version: '0'
99
117
  requirements: []
100
- rubygems_version: 3.0.3
118
+ rubygems_version: 3.0.1
101
119
  signing_key:
102
120
  specification_version: 4
103
121
  summary: Event Store in Ruby
@@ -1,45 +0,0 @@
1
- module RubyEventStore
2
- module PubSub
3
- class Broker
4
- def initialize(subscriptions:, dispatcher:)
5
- @subscriptions = subscriptions
6
- @dispatcher = dispatcher
7
- end
8
-
9
- def call(event, serialized_event)
10
- subscribers = subscriptions.all_for(event.type)
11
- subscribers.each do |subscriber|
12
- dispatcher.call(subscriber, event, serialized_event)
13
- end
14
- end
15
-
16
- def add_subscription(subscriber, event_types)
17
- verify_subscription(subscriber)
18
- subscriptions.add_subscription(subscriber, event_types)
19
- end
20
-
21
- def add_global_subscription(subscriber)
22
- verify_subscription(subscriber)
23
- subscriptions.add_global_subscription(subscriber)
24
- end
25
-
26
- def add_thread_subscription(subscriber, event_types)
27
- verify_subscription(subscriber)
28
- subscriptions.add_thread_subscription(subscriber, event_types)
29
- end
30
-
31
- def add_thread_global_subscription(subscriber)
32
- verify_subscription(subscriber)
33
- subscriptions.add_thread_global_subscription(subscriber)
34
- end
35
-
36
- private
37
- attr_reader :subscriptions, :dispatcher
38
-
39
- def verify_subscription(subscriber)
40
- raise SubscriberNotExist, "subscriber must be first argument or block" unless subscriber
41
- raise InvalidHandler.new("Handler #{subscriber} is invalid for dispatcher #{dispatcher}") unless dispatcher.verify(subscriber)
42
- end
43
- end
44
- end
45
- end