ruby_event_store 2.1.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruby_event_store/batch_enumerator.rb +3 -3
  3. data/lib/ruby_event_store/broker.rb +5 -4
  4. data/lib/ruby_event_store/client.rb +81 -48
  5. data/lib/ruby_event_store/composed_dispatcher.rb +1 -3
  6. data/lib/ruby_event_store/correlated_commands.rb +4 -15
  7. data/lib/ruby_event_store/errors.rb +11 -10
  8. data/lib/ruby_event_store/event.rb +9 -14
  9. data/lib/ruby_event_store/expected_version.rb +3 -7
  10. data/lib/ruby_event_store/in_memory_repository.rb +100 -37
  11. data/lib/ruby_event_store/instrumented_dispatcher.rb +11 -2
  12. data/lib/ruby_event_store/instrumented_repository.rb +13 -8
  13. data/lib/ruby_event_store/link_by_metadata.rb +4 -21
  14. data/lib/ruby_event_store/mappers/default.rb +6 -4
  15. data/lib/ruby_event_store/mappers/encryption_key.rb +7 -16
  16. data/lib/ruby_event_store/mappers/encryption_mapper.rb +6 -6
  17. data/lib/ruby_event_store/mappers/forgotten_data.rb +1 -1
  18. data/lib/ruby_event_store/mappers/in_memory_encryption_key_repository.rb +1 -1
  19. data/lib/ruby_event_store/mappers/null_mapper.rb +0 -1
  20. data/lib/ruby_event_store/mappers/pipeline.rb +3 -10
  21. data/lib/ruby_event_store/mappers/pipeline_mapper.rb +1 -0
  22. data/lib/ruby_event_store/mappers/transformation/domain_event.rb +22 -12
  23. data/lib/ruby_event_store/mappers/transformation/encryption.rb +21 -25
  24. data/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +6 -5
  25. data/lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb +6 -5
  26. data/lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb +6 -5
  27. data/lib/ruby_event_store/mappers/transformation/upcast.rb +2 -6
  28. data/lib/ruby_event_store/metadata.rb +46 -17
  29. data/lib/ruby_event_store/projection.rb +12 -20
  30. data/lib/ruby_event_store/record.rb +14 -26
  31. data/lib/ruby_event_store/serialized_record.rb +14 -26
  32. data/lib/ruby_event_store/serializers/yaml.rb +17 -0
  33. data/lib/ruby_event_store/spec/broker_lint.rb +38 -28
  34. data/lib/ruby_event_store/spec/event_lint.rb +10 -10
  35. data/lib/ruby_event_store/spec/event_repository_lint.rb +746 -730
  36. data/lib/ruby_event_store/spec/mapper_lint.rb +2 -2
  37. data/lib/ruby_event_store/spec/subscriptions_lint.rb +58 -68
  38. data/lib/ruby_event_store/specification.rb +20 -16
  39. data/lib/ruby_event_store/specification_reader.rb +2 -3
  40. data/lib/ruby_event_store/specification_result.rb +52 -46
  41. data/lib/ruby_event_store/stream.rb +3 -7
  42. data/lib/ruby_event_store/subscriptions.rb +17 -17
  43. data/lib/ruby_event_store/transform_keys.rb +1 -1
  44. data/lib/ruby_event_store/version.rb +1 -1
  45. data/lib/ruby_event_store.rb +44 -43
  46. metadata +6 -4
@@ -1,26 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ostruct'
3
+ require "ostruct"
4
4
  module RubyEventStore
5
5
  class InMemoryRepository
6
+ class UnsupportedVersionAnyUsage < StandardError
7
+ def initialize
8
+ super <<~EOS
9
+ Mixing expected version :any and specific position (or :auto) is unsupported.
10
+
11
+ Read more about expected versions here:
12
+ https://railseventstore.org/docs/v2/expected_version/
13
+ EOS
14
+ end
15
+ end
16
+
17
+ class EventInStream
18
+ def initialize(event_id, position)
19
+ @event_id = event_id
20
+ @position = position
21
+ end
22
+
23
+ attr_reader :event_id, :position
24
+ end
6
25
 
7
- def initialize(serializer: NULL)
26
+ def initialize(serializer: NULL, ensure_supported_any_usage: false)
8
27
  @serializer = serializer
9
28
  @streams = Hash.new { |h, k| h[k] = Array.new }
10
- @mutex = Mutex.new
29
+ @mutex = Mutex.new
11
30
  @storage = Hash.new
31
+ @ensure_supported_any_usage = ensure_supported_any_usage
12
32
  end
13
33
 
14
34
  def append_to_stream(records, stream, expected_version)
15
35
  serialized_records = records.map { |record| record.serialize(serializer) }
16
36
 
17
37
  with_synchronize(expected_version, stream) do |resolved_version|
18
- raise WrongExpectedEventVersion unless last_stream_version(stream).equal?(resolved_version)
38
+ ensure_supported_any_usage(resolved_version, stream)
39
+ unless resolved_version.nil? || last_stream_version(stream).equal?(resolved_version)
40
+ raise WrongExpectedEventVersion
41
+ end
19
42
 
20
- serialized_records.each do |serialized_record|
43
+ serialized_records.each_with_index do |serialized_record, index|
21
44
  raise EventDuplicatedInStream if has_event?(serialized_record.event_id)
22
45
  storage[serialized_record.event_id] = serialized_record
23
- streams[stream.name] << serialized_record.event_id
46
+ add_to_stream(stream, serialized_record, resolved_version, index)
24
47
  end
25
48
  end
26
49
  self
@@ -30,11 +53,14 @@ module RubyEventStore
30
53
  serialized_records = event_ids.map { |id| read_event(id) }
31
54
 
32
55
  with_synchronize(expected_version, stream) do |resolved_version|
33
- raise WrongExpectedEventVersion unless last_stream_version(stream).equal?(resolved_version)
56
+ ensure_supported_any_usage(resolved_version, stream)
57
+ unless resolved_version.nil? || last_stream_version(stream).equal?(resolved_version)
58
+ raise WrongExpectedEventVersion
59
+ end
34
60
 
35
- serialized_records.each do |serialized_record|
61
+ serialized_records.each_with_index do |serialized_record, index|
36
62
  raise EventDuplicatedInStream if has_event_in_stream?(serialized_record.event_id, stream.name)
37
- streams[stream.name] << serialized_record.event_id
63
+ add_to_stream(stream, serialized_record, resolved_version, index)
38
64
  end
39
65
  end
40
66
  self
@@ -69,9 +95,7 @@ module RubyEventStore
69
95
  serialized_records.last&.deserialize(serializer)
70
96
  else
71
97
  Enumerator.new do |y|
72
- serialized_records.each do |serialized_record|
73
- y << serialized_record.deserialize(serializer)
74
- end
98
+ serialized_records.each { |serialized_record| y << serialized_record.deserialize(serializer) }
75
99
  end
76
100
  end
77
101
  end
@@ -84,38 +108,61 @@ module RubyEventStore
84
108
  records.each do |record|
85
109
  read_event(record.event_id)
86
110
  serialized_record =
87
- Record.new(
88
- event_id: record.event_id,
89
- event_type: record.event_type,
90
- data: record.data,
91
- metadata: record.metadata,
92
- timestamp: Time.iso8601(storage.fetch(record.event_id).timestamp),
93
- valid_at: record.valid_at,
94
- ).serialize(serializer)
111
+ Record
112
+ .new(
113
+ event_id: record.event_id,
114
+ event_type: record.event_type,
115
+ data: record.data,
116
+ metadata: record.metadata,
117
+ timestamp: Time.iso8601(storage.fetch(record.event_id).timestamp),
118
+ valid_at: record.valid_at
119
+ )
120
+ .serialize(serializer)
95
121
  storage[record.event_id] = serialized_record
96
122
  end
97
123
  end
98
124
 
99
125
  def streams_of(event_id)
100
- streams
101
- .select { |name,| has_event_in_stream?(event_id, name) }
102
- .map { |name,| Stream.new(name) }
126
+ streams.select { |name,| has_event_in_stream?(event_id, name) }.map { |name,| Stream.new(name) }
127
+ end
128
+
129
+ def position_in_stream(event_id, stream)
130
+ event_in_stream = streams[stream.name].find { |event_in_stream| event_in_stream.event_id.eql?(event_id) }
131
+ raise EventNotFoundInStream if event_in_stream.nil?
132
+ event_in_stream.position
133
+ end
134
+
135
+ def global_position(event_id)
136
+ storage.keys.index(event_id) or raise EventNotFound.new(event_id)
137
+ end
138
+
139
+ def event_in_stream?(event_id, stream)
140
+ !streams[stream.name].find { |event_in_stream| event_in_stream.event_id.eql?(event_id) }.nil?
103
141
  end
104
142
 
105
143
  private
144
+
106
145
  def read_scope(spec)
107
146
  serialized_records = serialized_records_of_stream(spec.stream)
108
147
  serialized_records = ordered(serialized_records, spec)
109
- serialized_records = serialized_records.select{|e| spec.with_ids.any?{|x| x.eql?(e.event_id)}} if spec.with_ids?
110
- serialized_records = serialized_records.select{|e| spec.with_types.any?{|x| x.eql?(e.event_type)}} if spec.with_types?
148
+ serialized_records = serialized_records.select { |e| spec.with_ids.any? { |x| x.eql?(e.event_id) } } if spec
149
+ .with_ids?
150
+ serialized_records = serialized_records.select { |e| spec.with_types.any? { |x| x.eql?(e.event_type) } } if spec
151
+ .with_types?
111
152
  serialized_records = serialized_records.reverse if spec.backward?
112
153
  serialized_records = serialized_records.drop(index_of(serialized_records, spec.start) + 1) if spec.start
113
154
  serialized_records = serialized_records.take(index_of(serialized_records, spec.stop)) if spec.stop
114
155
  serialized_records = serialized_records.take(spec.limit) if spec.limit?
115
- serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) < spec.older_than } if spec.older_than
116
- serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) <= spec.older_than_or_equal } if spec.older_than_or_equal
117
- serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) > spec.newer_than } if spec.newer_than
118
- serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) >= spec.newer_than_or_equal } if spec.newer_than_or_equal
156
+ serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) < spec.older_than } if spec
157
+ .older_than
158
+ serialized_records =
159
+ serialized_records.select { |sr| Time.iso8601(sr.timestamp) <= spec.older_than_or_equal } if spec
160
+ .older_than_or_equal
161
+ serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) > spec.newer_than } if spec
162
+ .newer_than
163
+ serialized_records =
164
+ serialized_records.select { |sr| Time.iso8601(sr.timestamp) >= spec.newer_than_or_equal } if spec
165
+ .newer_than_or_equal
119
166
  serialized_records
120
167
  end
121
168
 
@@ -124,7 +171,7 @@ module RubyEventStore
124
171
  end
125
172
 
126
173
  def event_ids_of_stream(stream)
127
- streams.fetch(stream.name, Array.new)
174
+ streams.fetch(stream.name, Array.new).map(&:event_id)
128
175
  end
129
176
 
130
177
  def serialized_records_of_stream(stream)
@@ -143,7 +190,7 @@ module RubyEventStore
143
190
  end
144
191
 
145
192
  def last_stream_version(stream)
146
- event_ids_of_stream(stream).size - 1
193
+ streams.fetch(stream.name, Array.new).size - 1
147
194
  end
148
195
 
149
196
  def with_synchronize(expected_version, stream, &block)
@@ -157,18 +204,34 @@ module RubyEventStore
157
204
  # conditions more likely. And we only use mutex.synchronize for writing
158
205
  # not for the whole read+write algorithm.
159
206
  Thread.pass
160
- mutex.synchronize do
161
- resolved_version = last_stream_version(stream) if expected_version.any?
162
- block.call(resolved_version)
163
- end
207
+ mutex.synchronize { block.call(resolved_version) }
164
208
  end
165
209
 
166
210
  def has_event_in_stream?(event_id, stream_name)
167
- streams.fetch(stream_name, Array.new).any? { |id| id.eql?(event_id) }
211
+ streams.fetch(stream_name, Array.new).any? { |event_in_stream| event_in_stream.event_id.eql?(event_id) }
168
212
  end
169
213
 
170
214
  def index_of(source, event_id)
171
- source.index {|item| item.event_id.eql?(event_id)}
215
+ source.index { |item| item.event_id.eql?(event_id) }
216
+ end
217
+
218
+ def compute_position(resolved_version, index)
219
+ resolved_version + index + 1 unless resolved_version.nil?
220
+ end
221
+
222
+ def add_to_stream(stream, serialized_record, resolved_version, index)
223
+ streams[stream.name] << EventInStream.new(serialized_record.event_id, compute_position(resolved_version, index))
224
+ end
225
+
226
+ def ensure_supported_any_usage(resolved_version, stream)
227
+ if @ensure_supported_any_usage
228
+ stream_positions = streams.fetch(stream.name, Array.new).map(&:position)
229
+ if resolved_version.nil?
230
+ raise UnsupportedVersionAnyUsage if !stream_positions.compact.empty?
231
+ else
232
+ raise UnsupportedVersionAnyUsage if stream_positions.include?(nil)
233
+ end
234
+ end
172
235
  end
173
236
 
174
237
  attr_reader :streams, :mutex, :storage, :serializer
@@ -13,11 +13,20 @@ module RubyEventStore
13
13
  end
14
14
  end
15
15
 
16
- def verify(subscriber)
17
- dispatcher.verify(subscriber)
16
+ def method_missing(method_name, *arguments, **keyword_arguments, &block)
17
+ if respond_to?(method_name)
18
+ dispatcher.public_send(method_name, *arguments, **keyword_arguments, &block)
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ def respond_to_missing?(method_name, _include_private)
25
+ dispatcher.respond_to?(method_name)
18
26
  end
19
27
 
20
28
  private
29
+
21
30
  attr_reader :instrumentation, :dispatcher
22
31
  end
23
32
  end
@@ -25,14 +25,6 @@ module RubyEventStore
25
25
  end
26
26
  end
27
27
 
28
- def has_event?(event_id)
29
- repository.has_event?(event_id)
30
- end
31
-
32
- def last_stream_event(stream)
33
- repository.last_stream_event(stream)
34
- end
35
-
36
28
  def read(specification)
37
29
  instrumentation.instrument("read.repository.rails_event_store", specification: specification) do
38
30
  repository.read(specification)
@@ -57,7 +49,20 @@ module RubyEventStore
57
49
  end
58
50
  end
59
51
 
52
+ def method_missing(method_name, *arguments, **keyword_arguments, &block)
53
+ if respond_to?(method_name)
54
+ repository.public_send(method_name, *arguments, **keyword_arguments, &block)
55
+ else
56
+ super
57
+ end
58
+ end
59
+
60
+ def respond_to_missing?(method_name, _include_private)
61
+ repository.respond_to?(method_name)
62
+ end
63
+
60
64
  private
65
+
61
66
  attr_reader :repository, :instrumentation
62
67
  end
63
68
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  module RubyEventStore
4
4
  class LinkByMetadata
5
-
6
5
  def initialize(event_store:, key:, prefix: nil)
7
6
  @event_store = event_store
8
7
  @key = key
@@ -12,31 +11,19 @@ module RubyEventStore
12
11
  def call(event)
13
12
  return unless event.metadata.has_key?(@key)
14
13
 
15
- @event_store.link(
16
- [event.event_id],
17
- stream_name: "#{@prefix}#{event.metadata.fetch(@key)}"
18
- )
14
+ @event_store.link([event.event_id], stream_name: "#{@prefix}#{event.metadata.fetch(@key)}")
19
15
  end
20
-
21
16
  end
22
17
 
23
18
  class LinkByCorrelationId < LinkByMetadata
24
19
  def initialize(event_store:, prefix: nil)
25
- super(
26
- event_store: event_store,
27
- prefix: prefix,
28
- key: :correlation_id,
29
- )
20
+ super(event_store: event_store, prefix: prefix, key: :correlation_id)
30
21
  end
31
22
  end
32
23
 
33
24
  class LinkByCausationId < LinkByMetadata
34
25
  def initialize(event_store:, prefix: nil)
35
- super(
36
- event_store: event_store,
37
- prefix: prefix,
38
- key: :causation_id,
39
- )
26
+ super(event_store: event_store, prefix: prefix, key: :causation_id)
40
27
  end
41
28
  end
42
29
 
@@ -47,11 +34,7 @@ module RubyEventStore
47
34
  end
48
35
 
49
36
  def call(event)
50
- @event_store.link(
51
- [event.event_id],
52
- stream_name: "#{@prefix}#{event.event_type}"
53
- )
37
+ @event_store.link([event.event_id], stream_name: "#{@prefix}#{event.event_type}")
54
38
  end
55
39
  end
56
-
57
40
  end
@@ -4,10 +4,12 @@ module RubyEventStore
4
4
  module Mappers
5
5
  class Default < PipelineMapper
6
6
  def initialize(events_class_remapping: {})
7
- super(Pipeline.new(
8
- Transformation::EventClassRemapper.new(events_class_remapping),
9
- Transformation::SymbolizeMetadataKeys.new,
10
- ))
7
+ super(
8
+ Pipeline.new(
9
+ Transformation::EventClassRemapper.new(events_class_remapping),
10
+ Transformation::SymbolizeMetadataKeys.new
11
+ )
12
+ )
11
13
  end
12
14
  end
13
15
  end
@@ -5,31 +5,22 @@ module RubyEventStore
5
5
  class EncryptionKey
6
6
  def initialize(cipher:, key:)
7
7
  @cipher = cipher
8
- @key = key
8
+ @key = key
9
9
  end
10
10
 
11
11
  def encrypt(message, iv)
12
- crypto = prepare_encrypt(cipher)
13
- crypto.iv = iv
12
+ crypto = prepare_encrypt(cipher)
13
+ crypto.iv = iv
14
14
  crypto.key = key
15
15
 
16
- if crypto.authenticated?
17
- encrypt_authenticated(crypto, message)
18
- else
19
- crypto.update(message) + crypto.final
20
- end
16
+ crypto.authenticated? ? encrypt_authenticated(crypto, message) : crypto.update(message) + crypto.final
21
17
  end
22
18
 
23
19
  def decrypt(message, iv)
24
- crypto = prepare_decrypt(cipher)
25
- crypto.iv = iv
20
+ crypto = prepare_decrypt(cipher)
21
+ crypto.iv = iv
26
22
  crypto.key = key
27
- ciphertext =
28
- if crypto.authenticated?
29
- ciphertext_from_authenticated(crypto, message)
30
- else
31
- message
32
- end
23
+ ciphertext = crypto.authenticated? ? ciphertext_from_authenticated(crypto, message) : message
33
24
  (crypto.update(ciphertext) + crypto.final).force_encoding("UTF-8")
34
25
  end
35
26
 
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml'
4
-
5
3
  module RubyEventStore
6
4
  module Mappers
7
5
  class EncryptionMapper < PipelineMapper
8
- def initialize(key_repository, serializer: YAML, forgotten_data: ForgottenData.new)
9
- super(Pipeline.new(
10
- Transformation::Encryption.new(key_repository, serializer: serializer, forgotten_data: forgotten_data),
11
- ))
6
+ def initialize(key_repository, serializer: Serializers::YAML, forgotten_data: ForgottenData.new)
7
+ super(
8
+ Pipeline.new(
9
+ Transformation::Encryption.new(key_repository, serializer: serializer, forgotten_data: forgotten_data)
10
+ )
11
+ )
12
12
  end
13
13
  end
14
14
  end
@@ -3,7 +3,7 @@
3
3
  module RubyEventStore
4
4
  module Mappers
5
5
  class ForgottenData
6
- FORGOTTEN_DATA = 'FORGOTTEN_DATA'.freeze
6
+ FORGOTTEN_DATA = "FORGOTTEN_DATA".freeze
7
7
 
8
8
  def initialize(string = FORGOTTEN_DATA)
9
9
  @string = string
@@ -3,7 +3,7 @@
3
3
  module RubyEventStore
4
4
  module Mappers
5
5
  class InMemoryEncryptionKeyRepository
6
- DEFAULT_CIPHER = 'aes-256-gcm'.freeze
6
+ DEFAULT_CIPHER = "aes-256-gcm".freeze
7
7
 
8
8
  def initialize
9
9
  @keys = {}
@@ -3,7 +3,6 @@
3
3
  module RubyEventStore
4
4
  module Mappers
5
5
  class NullMapper < PipelineMapper
6
-
7
6
  def initialize
8
7
  super(Pipeline.new)
9
8
  end
@@ -4,22 +4,15 @@ module RubyEventStore
4
4
  module Mappers
5
5
  class Pipeline
6
6
  def initialize(*transformations, to_domain_event: Transformation::DomainEvent.new)
7
- @transformations = [
8
- to_domain_event,
9
- transformations,
10
- ].flatten.freeze
7
+ @transformations = [to_domain_event, transformations].flatten.freeze
11
8
  end
12
9
 
13
10
  def dump(domain_event)
14
- transformations.reduce(domain_event) do |item, transform|
15
- transform.dump(item)
16
- end
11
+ transformations.reduce(domain_event) { |item, transform| transform.dump(item) }
17
12
  end
18
13
 
19
14
  def load(record)
20
- transformations.reverse.reduce(record) do |item, transform|
21
- transform.load(item)
22
- end
15
+ transformations.reverse.reduce(record) { |item, transform| transform.load(item) }
23
16
  end
24
17
 
25
18
  attr_reader :transformations
@@ -16,6 +16,7 @@ module RubyEventStore
16
16
  end
17
17
 
18
18
  private
19
+
19
20
  attr_reader :pipeline
20
21
  end
21
22
  end
@@ -5,27 +5,37 @@ module RubyEventStore
5
5
  module Transformation
6
6
  class DomainEvent
7
7
  def dump(domain_event)
8
- metadata = domain_event.metadata.to_h
8
+ metadata = domain_event.metadata.dup.to_h
9
9
  timestamp = metadata.delete(:timestamp)
10
10
  valid_at = metadata.delete(:valid_at)
11
11
  Record.new(
12
- event_id: domain_event.event_id,
13
- metadata: metadata,
14
- data: domain_event.data,
12
+ event_id: domain_event.event_id,
13
+ metadata: metadata,
14
+ data: domain_event.data,
15
15
  event_type: domain_event.event_type,
16
- timestamp: timestamp,
17
- valid_at: valid_at,
16
+ timestamp: timestamp,
17
+ valid_at: valid_at
18
18
  )
19
19
  end
20
20
 
21
21
  def load(record)
22
- Object.const_get(record.event_type).new(
22
+ Object
23
+ .const_get(record.event_type)
24
+ .new(
25
+ event_id: record.event_id,
26
+ data: record.data,
27
+ metadata: record.metadata.merge(timestamp: record.timestamp, valid_at: record.valid_at)
28
+ )
29
+ rescue NameError
30
+ Event.new(
23
31
  event_id: record.event_id,
24
- metadata: record.metadata.merge(
25
- timestamp: record.timestamp,
26
- valid_at: record.valid_at,
27
- ),
28
- data: record.data,
32
+ data: record.data,
33
+ metadata:
34
+ record.metadata.merge(
35
+ timestamp: record.timestamp,
36
+ valid_at: record.valid_at,
37
+ event_type: record.event_type
38
+ )
29
39
  )
30
40
  end
31
41
  end
@@ -6,38 +6,38 @@ module RubyEventStore
6
6
  class Encryption
7
7
  class Leaf
8
8
  def self.===(hash)
9
- hash.keys.sort.eql? %i(cipher identifier iv)
9
+ hash.keys.sort.eql? %i[cipher identifier iv]
10
10
  end
11
11
  end
12
12
  private_constant :Leaf
13
13
 
14
14
  class MissingEncryptionKey < StandardError
15
15
  def initialize(key_identifier)
16
- super %Q|Could not find encryption key for '#{key_identifier}'|
16
+ super "Could not find encryption key for '#{key_identifier}'"
17
17
  end
18
18
  end
19
19
 
20
- def initialize(key_repository, serializer: YAML, forgotten_data: ForgottenData.new)
20
+ def initialize(key_repository, serializer: Serializers::YAML, forgotten_data: ForgottenData.new)
21
21
  @key_repository = key_repository
22
22
  @serializer = serializer
23
23
  @forgotten_data = forgotten_data
24
24
  end
25
25
 
26
26
  def dump(record)
27
- data = record.data
28
- metadata = record.metadata.dup
27
+ data = record.data
28
+ metadata = record.metadata.dup
29
29
  event_class = Object.const_get(record.event_type)
30
30
 
31
- crypto_description = encryption_metadata(data, encryption_schema(event_class))
31
+ crypto_description = encryption_metadata(data, encryption_schema(event_class))
32
32
  metadata[:encryption] = crypto_description unless crypto_description.empty?
33
33
 
34
34
  Record.new(
35
- event_id: record.event_id,
35
+ event_id: record.event_id,
36
36
  event_type: record.event_type,
37
- data: encrypt_data(deep_dup(data), crypto_description),
38
- metadata: metadata,
39
- timestamp: record.timestamp,
40
- valid_at: record.valid_at,
37
+ data: encrypt_data(deep_dup(data), crypto_description),
38
+ metadata: metadata,
39
+ timestamp: record.timestamp,
40
+ valid_at: record.valid_at
41
41
  )
42
42
  end
43
43
 
@@ -46,16 +46,17 @@ module RubyEventStore
46
46
  crypto_description = Hash(metadata.delete(:encryption))
47
47
 
48
48
  Record.new(
49
- event_id: record.event_id,
49
+ event_id: record.event_id,
50
50
  event_type: record.event_type,
51
- data: decrypt_data(record.data, crypto_description),
52
- metadata: metadata,
53
- timestamp: record.timestamp,
54
- valid_at: record.valid_at,
51
+ data: decrypt_data(record.data, crypto_description),
52
+ metadata: metadata,
53
+ timestamp: record.timestamp,
54
+ valid_at: record.valid_at
55
55
  )
56
56
  end
57
57
 
58
58
  private
59
+
59
60
  attr_reader :key_repository, :serializer, :forgotten_data
60
61
 
61
62
  def encryption_schema(event_class)
@@ -64,9 +65,7 @@ module RubyEventStore
64
65
 
65
66
  def deep_dup(hash)
66
67
  duplicate = hash.dup
67
- duplicate.each do |k, v|
68
- duplicate[k] = v.instance_of?(Hash) ? deep_dup(v) : v
69
- end
68
+ duplicate.each { |k, v| duplicate[k] = v.instance_of?(Hash) ? deep_dup(v) : v }
70
69
  duplicate
71
70
  end
72
71
 
@@ -79,11 +78,7 @@ module RubyEventStore
79
78
  key_identifier = value.call(data)
80
79
  encryption_key = key_repository.key_of(key_identifier)
81
80
  raise MissingEncryptionKey.new(key_identifier) unless encryption_key
82
- acc[key] = {
83
- cipher: encryption_key.cipher,
84
- iv: encryption_key.random_iv,
85
- identifier: key_identifier,
86
- }
81
+ acc[key] = { cipher: encryption_key.cipher, iv: encryption_key.random_iv, identifier: key_identifier }
87
82
  end
88
83
  acc
89
84
  end
@@ -122,7 +117,8 @@ module RubyEventStore
122
117
  cryptogram = data.fetch(attribute)
123
118
  return unless cryptogram
124
119
 
125
- encryption_key = key_repository.key_of(meta.fetch(:identifier), cipher: meta.fetch(:cipher)) or return forgotten_data
120
+ encryption_key = key_repository.key_of(meta.fetch(:identifier), cipher: meta.fetch(:cipher)) or
121
+ return forgotten_data
126
122
  serializer.load(encryption_key.decrypt(cryptogram, meta.fetch(:iv)))
127
123
  when Hash
128
124
  decrypt_data(data.fetch(attribute), meta)
@@ -14,16 +14,17 @@ module RubyEventStore
14
14
 
15
15
  def load(record)
16
16
  Record.new(
17
- event_id: record.event_id,
17
+ event_id: record.event_id,
18
18
  event_type: class_map[record.event_type] || record.event_type,
19
- data: record.data,
20
- metadata: record.metadata,
21
- timestamp: record.timestamp,
22
- valid_at: record.valid_at,
19
+ data: record.data,
20
+ metadata: record.metadata,
21
+ timestamp: record.timestamp,
22
+ valid_at: record.valid_at
23
23
  )
24
24
  end
25
25
 
26
26
  private
27
+
27
28
  attr_reader :class_map
28
29
  end
29
30
  end