sandthorn 0.13.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29159ff3ce6f7b8393363e2bf740c3a37d57a2b2
4
- data.tar.gz: 9b1053c87fb402b1887acb6bc8a0fd6faee71ebf
3
+ metadata.gz: d4f14306b2c1c46da7b99ce8409f6e69dcddf050
4
+ data.tar.gz: 87dc839602892021e7aa13b2830bedbb1cc90891
5
5
  SHA512:
6
- metadata.gz: e5cf43faad3a61d3fe307c1598701e99644c7f2d7ea57aa336cd6f22fe9b4c6d707406657ee824619baf0b32ff5418500b46649ace7e1cefa25092529a739b7c
7
- data.tar.gz: 2802ac2bf37494ff1ddd4cfd050057e070ddad9422ccee0f9078be37c12c2772bf3402ca7cee6ce92839c042df04df996b658cf3b50bbd1376e60231e590440f
6
+ metadata.gz: 627da016b372e4f64e452c7bd3a6a8b69412f11e43b2f885e46b1aff6593d4cc73db78521761d5ef2f670ff238836b17a9e25d36208db37830670b38b30fea41
7
+ data.tar.gz: a6db0ce8921f77bfeccf4fca94ba3ba2228f5f00d73318c445d5b3a60f9b8d7df98e3bfca6475bc27df9ff60a5704d3e51a0f46afeb8094bb0087bcd5a2b697a
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.0
4
- - 2.1.1
3
+ - 2.4.1
4
+ - 2.3.4
5
+ - 2.2.6
6
+ - 2.1.10
5
7
  - 2.0.0
6
8
  sudo: false
data/README.md CHANGED
@@ -13,8 +13,7 @@ A ruby library for saving an object's state as a series of events.
13
13
 
14
14
  ## When do I need event sourcing?
15
15
 
16
- If the history of how an object came to be is important a well known technique is to generate a separate history log. The log is generated in parallel with the object and all actions to the object needs to be stored to the log by a separate method call. With event sourcing the history log is now integrated with the object and generated based on the actions that are made on the object, the log is now the fact that the object is built upon.
17
-
16
+ When state changes made to an object is important a common technique is to store the changes in a separate history log where the log is generated in parallel with the object internal state. With event sourcing the history log is now integrated within the object and generated based on the actions made to the object. The entries in log is the facts the object is built upon.
18
17
 
19
18
  ## Why Sandthorn?
20
19
 
@@ -25,88 +24,6 @@ Check out examples of Sandthorn:
25
24
  * [Examples](https://github.com/Sandthorn/sandthorn_examples) including a product shop and TicTacToe game.
26
25
  * Live [demo](http://infinite-mesa-8629.herokuapp.com/) comparing Active Record and Sandthorn.
27
26
 
28
- ## How do I use Sandthorn?
29
-
30
-
31
-
32
- Think of it as an object database where you store not only what the new value of an attribute is, but also when and why it changed.
33
- _Example:_
34
-
35
- ```ruby
36
-
37
- # Setup the Aggregate
38
-
39
- # The one available right now
40
- require 'sandthorn'
41
- require 'sandthorn_driver_sequel'
42
-
43
- class Ship
44
- include Sandthorn::AggregateRoot
45
- attr_reader :name
46
-
47
- def initialize name: nil, shipping_company: nil
48
- @name = name
49
- end
50
-
51
- # State-changing command
52
- def rename! new_name: ""
53
- unless new_name.empty? or new_name == name
54
- @name = new_name
55
- ship_was_renamed
56
- end
57
- end
58
-
59
- private
60
-
61
- # Commit the event and state-change is automatically recorded.
62
- def ship_was_renamed
63
- commit
64
- end
65
- end
66
-
67
- # Configure one driver
68
- url = "sqlite://spec/db/sequel_driver.sqlite3"
69
- sql_event_store = SandthornDriverSequel.driver_from_url(url: url)
70
- Sandthorn.configure do |c|
71
- c.event_store = sql_event_store
72
- end
73
-
74
- # Or configure many drivers
75
- url = "sqlite://spec/db/sequel_driver.sqlite3"
76
- sql_event_store = SandthornDriverSequel.driver_from_url(url: url)
77
- url_two = "sqlite://spec/db/sequel_driver_two.sqlite3"
78
- other_store = SandthornDriverSequel.driver_from_url(url: url_two)
79
-
80
- Sandthorn.configure do |c|
81
- c.event_stores = {
82
- default: sql_event_store,
83
- other_event_store: other_store
84
- }
85
- end
86
-
87
- # Assign your aggregates to a named event store
88
-
89
- class Boat
90
- include Sandthorn::AggregateRoot
91
- event_store :other_event_store
92
- end
93
-
94
- # Aggregates with no explicit event store will use the default event store
95
-
96
- # Migrate db schema for the sequel driver
97
- migrator = SandthornDriverSequel::Migration.new url: url
98
- SandthornDriverSequel.migrate_db url: url
99
-
100
- # Usage
101
- ship = Ship.new name: "Titanic"
102
- ship.rename! new_name: "Vasa"
103
-
104
- ship.save
105
-
106
- new_ship = Ship.find ship.id
107
- puts new_ship.name
108
- ```
109
-
110
27
  # Installation
111
28
 
112
29
  Add this line to your application's Gemfile:
@@ -124,79 +41,42 @@ Or install it yourself as:
124
41
  # Configuring Sandthorn
125
42
 
126
43
  ## Driver
44
+ Sandthorn can be setup with one or more drivers. A driver is bound to a specific data store where events are saved and loaded from. The current implemented drivers are [sandthorn_driver_sequel](https://github.com/Sandthorn/sandthorn_driver_sequel) for SQL via [Sequel](https://github.com/jeremyevans/sequel) and [sandthorn_driver_event_store](https://github.com/Sandthorn/sandthorn_driver_event_store) that uses [Get Event Store](https://geteventstore.com).
127
45
 
128
- Sandthorn relies on a driver that is specific to the data storage that you are using. This means Sandthorn can be used with any data storage given that a driver exists.
46
+ This means Sandthorn can be used with any data store given that a driver exists.
129
47
 
130
- To setup a driver you need to add it to your project's Gemfile and configure it in your application code.
131
-
132
- gem 'sandthorn_driver_sequel'
133
-
134
-
135
- The driver is configured when your application launches. Here's an example of how to do it using the Sequel driver and a sqlite3 database.
48
+ Here's an example of setting up Sandthorn with the Sequel driver and a sqlite3 database.
136
49
 
137
50
  ```ruby
138
- url = "sqlite://spec/db/sequel_driver.sqlite3"
51
+ url = "sqlite://sql.sqlite3"
139
52
  driver = SandthornDriverSequel.driver_from_url(url: url)
140
53
  Sandthorn.configure do |conf|
141
54
  conf.event_stores = { default: driver }
142
55
  end
143
56
  ```
144
57
 
145
- First we specify the path to the sqlite3 database in the `url` variable. Secondly, the specific driver is instantiated with the `url`. Hence, the driver could be instantiated using a different configuration, for example, an address to a Postgres database. Finally, `Sandthorn.configure` accepts a keyword list with options. It´s here the driver is bound to Sandthorn via a context.
146
-
147
- The first time you use the Sequel driver it is necessary to install the database schema.
148
-
149
- ```ruby
150
- url = "sqlite://spec/db/sequel_driver.sqlite3"
151
- SandthornDriverSequel::Migration.new url: url
152
- SandthornDriverSequel.migrate_db url: url
153
- ```
154
-
155
- Optionally, when using Sandthorn in your tests you can configure it in a `spec_helper.rb` which is then required by your test suites [example](https://github.com/Sandthorn/sandthorn_examples/blob/master/sandthorn_tictactoe/spec/spec_helper.rb#L20-L30). Note that the Sequel driver accepts a special parameter to empty the database between each test.
156
-
157
- The Sequel driver is the only production-ready driver to date.
158
-
159
-
160
58
  ## Map aggregate types to event stores
161
59
 
162
- Its possible to map aggregate_types to events stores from the configuration setup. This makes it possible to work with data from different stores that are using the same context, and will override any event_store setting within an aggregate.
60
+ Its possible to save events from different classes into different stores. Below the events from class FooAggregate are stored into the sql_foo.sqlite3 database and events from class BarAggregate are stored in sql_bar.sqlite3.
163
61
 
164
62
  ```ruby
165
- url_foo = "sqlite://spec/db/sequel_driver_foo.sqlite3"
166
- driver_foo = SandthornDriverSequel.driver_from_url(url: url_foo)
63
+ driver_foo = SandthornDriverSequel.driver_from_url(url: "sqlite://sql_foo.sqlite3")
64
+ driver_bar = SandthornDriverSequel.driver_from_url(url: "sqlite://sql_bar.sqlite3")
167
65
 
168
- url_bar = "sqlite://spec/db/sequel_driver_bar.sqlite3"
169
- driver_bar = SandthornDriverSequel.driver_from_url(url: url_bar)
170
-
171
- class AnAggregate
66
+ class FooAggregate
172
67
  Include Sandthorn::AggregateRoot
173
68
  end
174
69
 
175
- class AnOtherAggregate
70
+ class BarAggregate
176
71
  Include Sandthorn::AggregateRoot
177
72
  end
178
73
 
179
74
  Sandthorn.configure do |conf|
180
75
  conf.event_stores = { foo: driver_foo, bar: driver_bar }
181
- conf.map_types = { foo: [AnAggregate], bar: [AnOtherAggregate] }
76
+ conf.map_types = { foo: [FooAggregate], bar: [BarAggregate] }
182
77
  end
183
78
  ```
184
79
 
185
- ## Data serialization
186
-
187
- Its possible to configure how events and snapshots are serialized. Since version `0.11.0` of Sandthorn the serialization of events and snapshots is the responsibility of the driver. This means drivers can have different serialization mechanism, independent of each other.
188
-
189
- The default serializer of the Sequel driver is YAML.
190
-
191
- Here's how to use the Oj gem to serialize data in the Sequel driver:
192
-
193
- ```ruby
194
- oj_driver = SandthornDriverSequel.driver_from_connection(connection: Sequel.sqlite) { |conf|
195
- conf.event_serializer = Proc.new { |data| Oj::dump(data) }
196
- conf.event_deserializer = Proc.new { |data| Oj::load(data) }
197
- }
198
- ```
199
-
200
80
  # Usage
201
81
 
202
82
  ## Aggregate Root
@@ -217,7 +97,7 @@ All objects that include `Sandthorn::AggregateRoot` is provided with an `aggrega
217
97
 
218
98
  An abstraction over `commit` that creates events methods that can be used from within a command method.
219
99
 
220
- In this exampel the `events` method will generate a method called `marked`, this method take *args as input that will result in the method argument on the event. It also take a block that will be executed before the event is commited and is used to groups the state changes to the event (but is only optional right now).
100
+ In this exampel the `events` method will generate a method called `marked`, this method take an block that will be executed before the event is commited and is used to groups the state changes to the event. The block is optional and the state changes could have been made outside the `marked` method.
221
101
 
222
102
  ```ruby
223
103
  class Board
@@ -227,7 +107,7 @@ class Board
227
107
 
228
108
  def mark player, pos_x, pos_y
229
109
  # change some state
230
- marked(player) do
110
+ marked() do
231
111
  @pos_x = pos_x
232
112
  @pos_y = pos_y
233
113
  end
@@ -237,7 +117,7 @@ end
237
117
 
238
118
  ### `Sandthorn::AggregateRoot::constructor_events`
239
119
 
240
- Before version 0.13.0 the only initial event on an aggregate were `new`. With the `constructor_events` its possible to be more specific on how an aggregate came to be.
120
+ With `constructor_events` its possible to be more specific on how an aggregate came to be. The first event will now have the name `board_created` instead of the default `new`.
241
121
 
242
122
  ```ruby
243
123
  class Board
@@ -257,9 +137,9 @@ end
257
137
 
258
138
  ### `Sandthorn::AggregateRoot::stateless_events`
259
139
 
260
- Calling `stateless_events` creates public class methods. The first argument is an `aggregate_id`. The resulting event is attached to the referenced aggregate. The rest of the arguments are optional and are stored in the method_args of the event.
140
+ Calling `stateless_events` creates public class methods. The first argument is an `aggregate_id` and the second argument is optional but has to be a hash and is stored in the attribute_deltas of the event.
261
141
 
262
- When creating a stateless event, the corresponding aggregate is never loaded. The event is appendend to the aggregate's event stream.
142
+ When creating a stateless event, the corresponding aggregate is never loaded and the event is saved without calling the save method.
263
143
 
264
144
  ```ruby
265
145
  class Board
@@ -269,7 +149,7 @@ class Board
269
149
 
270
150
  end
271
151
 
272
- Board.player_went_to_toilet "board_aggregate_id", player_id, time
152
+ Board.player_went_to_toilet "board_aggregate_id", {player_id: "1", time: "10:12"}
273
153
  ```
274
154
 
275
155
  ### `Sandthorn::AggregateRoot::default_attributes`
@@ -286,7 +166,7 @@ end
286
166
 
287
167
  ### `Sandthorn::AggregateRoot.commit`
288
168
 
289
- It is required that an event is commited to the aggregate to be stored as an event. `commit` extracts the object's delta and locally caches the state changes that has been applied to the aggregate. Commonly, commit is called when an event is applied. In [CQRS](http://martinfowler.com/bliki/CQRS.html), events are named using past tense.
169
+ To generate an event the commit method has to be called within the aggregate. `commit` extracts the object's delta and locally caches the state changes that has been applied to the aggregate.
290
170
 
291
171
  ```ruby
292
172
  def mark player, pos_x, pos_y
@@ -301,11 +181,11 @@ end
301
181
 
302
182
  `commit` determines the state changes by monitoring the object's readable fields.
303
183
 
304
- Since version 0.10.0 of Sandthorn the concept `events` have been introduced to abstract away the usage of `commit`. Commit still works as before but we think that the `events` abstraction makes the aggregate more readable.
184
+ The concept `events` have been introduced to abstract away the usage of `commit`. Commit still works as before but we think that the `events` abstraction makes the aggregate more readable.
305
185
 
306
186
  ### `Sandthorn::AggregateRoot.save`
307
187
 
308
- Once one or more commits have been applied to an aggregate it should be saved. This means all commited events will be persisted by the specific Sandthorn driver. `save` is called by the owning object.
188
+ The save method store generated events, this means all commited events will be persisted via a Sandthorn driver.
309
189
 
310
190
  ```ruby
311
191
  board = Board.new
@@ -315,7 +195,7 @@ board.save
315
195
 
316
196
  ### `Sandthorn::AggregateRoot.all`
317
197
 
318
- It is possible to retrieve an array with all instances of a specific aggregate.
198
+ Retrieve an array with all instances of a specific aggregate type.
319
199
 
320
200
  ```ruby
321
201
  Board.all
@@ -329,20 +209,18 @@ Board.all.select { |board| board.active == true }
329
209
 
330
210
  ### `Sandthorn::AggregateRoot.find`
331
211
 
332
- Using `find` it is possible to retrieve a specific aggregate using it's id.
212
+ Loads a specific aggregate using it's uuid.
333
213
 
334
214
  ```ruby
335
215
  uuid = '550e8400-e29b-41d4-a716-446655440000'
336
216
  board = Board.find(uuid)
337
- board.aggregate_id == uuid
338
217
  ```
339
218
 
340
- If no aggregate with the specifid id is found, a `Sandthorn::Errors::AggregateNotFound` exception is raised.
341
-
219
+ If no aggregate with the specifid uuid is found, a `Sandthorn::Errors::AggregateNotFound` exception is raised.
342
220
 
343
221
  ### `Sandthorn::AggregateRoot.aggregate_trace`
344
222
 
345
- Using `aggregate_trace` one can store meta data with events. The data is not aggregate specific, for example, one can store who executed a specific command on the aggregate.
223
+ Using `aggregate_trace` one can store meta data on events. The data is not aggregate specific and it can for example store who executed a specific command on the aggregate.
346
224
 
347
225
  ```ruby
348
226
  board.aggregate_trace {player: "Fred"} do |aggregate|
@@ -353,7 +231,7 @@ end
353
231
 
354
232
  `aggregate_trace` can also be specified on a class.
355
233
 
356
- ````ruby
234
+ ```ruby
357
235
  Board.aggregate_trace {ip: :127.0.0.1} do
358
236
  board = Board.new
359
237
  board.mark :o , 0, 1
@@ -32,50 +32,20 @@ module Sandthorn
32
32
  SecureRandom.uuid
33
33
  end
34
34
 
35
- def get_aggregate_events aggregate_type, aggregate_id
36
- event_store_for(aggregate_type).get_aggregate_events aggregate_id
37
- end
38
-
39
35
  def save_events aggregate_events, aggregate_id, aggregate_type
40
36
  event_store_for(aggregate_type).save_events aggregate_events, aggregate_id, *aggregate_type
41
37
  end
42
38
 
43
- def get_aggregate aggregate_id, aggregate_type
44
- event_store_for(aggregate_type).get_aggregate_events_from_snapshot aggregate_id
45
- end
46
-
47
- def save_snapshot(aggregate)
48
- event_store_for(aggregate.class).save_snapshot(aggregate)
49
- end
50
-
51
- def get_aggregate_list_by_type aggregate_type
52
- event_store_for(aggregate_type).get_aggregate_ids(aggregate_type: aggregate_type)
53
- end
54
-
55
39
  def all aggregate_type
56
40
  event_store_for(aggregate_type).all(aggregate_type)
57
41
  end
58
42
 
59
43
  def find aggregate_id, aggregate_type
60
- event_store_for(aggregate_type).find(aggregate_id)
44
+ event_store_for(aggregate_type).find(aggregate_id, aggregate_type)
61
45
  end
62
46
 
63
- def get_events event_store: :default, aggregate_types: [], take: 0, after_sequence_number: 0
64
- event_store = find_event_store(event_store)
65
- events = event_store.get_events aggregate_types: aggregate_types, take: take, after_sequence_number: after_sequence_number
66
- events.map do |event|
67
- Event.new(event)
68
- end
69
- end
70
-
71
- def obsolete_snapshots type_names: [], min_event_distance: 0
72
- obsolete = event_stores.flat_map { |event_store| event_store.obsolete_snapshots(aggregate_types: type_names, max_event_distance: min_event_distance) }
73
- obsolete.map do |single_obsolete|
74
- type = Kernel.const_get single_obsolete[:aggregate_type]
75
- aggregate = type.aggregate_find(single_obsolete[:aggregate_id]).tap do |agg|
76
- yield agg if block_given?
77
- end
78
- end
47
+ def save_snapshot(aggregate)
48
+ raise "Not Implemented"
79
49
  end
80
50
 
81
51
  def find_event_store(name)
@@ -42,9 +42,9 @@ module Sandthorn
42
42
  @aggregate_trace_information = nil
43
43
  end
44
44
 
45
- def commit *args
45
+ def commit
46
46
  event_name = caller_locations(1,1)[0].label.gsub(/block ?(.*) in /, "")
47
- commit_with_event_name(event_name, args)
47
+ commit_with_event_name(event_name)
48
48
  end
49
49
 
50
50
  def default_attributes
@@ -82,12 +82,17 @@ module Sandthorn
82
82
  end
83
83
 
84
84
  def aggregate_find aggregate_id
85
- events = Sandthorn.find(aggregate_id, self)
86
- unless events && !events.empty?
87
- raise Sandthorn::Errors::AggregateNotFound
88
- end
85
+ begin
86
+ events = Sandthorn.find(aggregate_id, self)
87
+ unless events && !events.empty?
88
+ raise Errors::AggregateNotFound
89
+ end
89
90
 
90
- aggregate_build events
91
+ return aggregate_build events
92
+ rescue Exception
93
+ raise Errors::AggregateNotFound
94
+ end
95
+
91
96
  end
92
97
 
93
98
  def new *args, &block
@@ -100,26 +105,20 @@ module Sandthorn
100
105
  aggregate.send :set_aggregate_id, Sandthorn.generate_aggregate_id
101
106
 
102
107
  aggregate.aggregate_trace @@aggregate_trace_information do |aggr|
103
- aggr.send :commit, *args
108
+ aggr.send :commit
104
109
  return aggr
105
110
  end
106
111
 
107
112
  end
108
113
 
109
114
  def aggregate_build events
110
- if first_event_snapshot?(events)
111
- aggregate = events.first[:aggregate]
112
- events.shift
113
- else
114
- aggregate = create_new_empty_aggregate
115
- end
115
+ aggregate = create_new_empty_aggregate
116
116
 
117
117
  if events.any?
118
118
  current_aggregate_version = events.last[:aggregate_version]
119
119
  aggregate.send :set_orginating_aggregate_version!, current_aggregate_version
120
120
  aggregate.send :set_current_aggregate_version!, current_aggregate_version
121
121
  end
122
-
123
122
  attributes = build_instance_vars_from_events events
124
123
  aggregate.send :clear_aggregate_events
125
124
 
@@ -130,15 +129,12 @@ module Sandthorn
130
129
  aggregate
131
130
  end
132
131
 
133
-
134
-
135
132
  def stateless_events(*event_names)
136
133
  event_names.each do |name|
137
134
  define_singleton_method name do |aggregate_id, *args|
138
- event = build_event(name.to_s, args, [], nil)
135
+ event = build_stateless_event(name.to_s, args)
139
136
  Sandthorn.save_events([event], aggregate_id, self)
140
137
  return aggregate_id
141
-
142
138
  end
143
139
  end
144
140
  end
@@ -152,7 +148,7 @@ module Sandthorn
152
148
  aggregate.aggregate_initialize
153
149
  aggregate.send :set_aggregate_id, Sandthorn.generate_aggregate_id
154
150
  aggregate.instance_eval(&block) if block
155
- aggregate.send :commit_with_event_name, name.to_s, args
151
+ aggregate.send :commit_with_event_name, name.to_s
156
152
  return aggregate
157
153
  end
158
154
 
@@ -165,7 +161,7 @@ module Sandthorn
165
161
  event_names.each do |name|
166
162
  define_method(name) do |*args, &block|
167
163
  block.call() if block
168
- commit_with_event_name(name.to_s, args)
164
+ commit_with_event_name(name.to_s)
169
165
  end
170
166
  private name.to_s
171
167
  end
@@ -173,30 +169,33 @@ module Sandthorn
173
169
 
174
170
  private
175
171
 
176
- def build_event name, args, attribute_deltas, aggregate_version, trace_information = nil
172
+ def build_stateless_event name, args = []
173
+
174
+ formated_attribute_deltas = args.first.map do |key, value|
175
+ {
176
+ attribute_name: key.to_s,
177
+ old_value: nil,
178
+ new_value: value
179
+ }
180
+ end unless args.empty?
177
181
 
178
182
  data = {
179
- method_name: name,
180
- method_args: args,
181
- attribute_deltas: attribute_deltas
183
+ attribute_deltas: formated_attribute_deltas
182
184
  }
183
185
 
184
- unless trace_information.nil? || trace_information.empty?
185
- data.merge!({ trace: trace_information })
186
- end
187
-
188
186
  return {
189
- aggregate_version: aggregate_version,
187
+ aggregate_version: nil,
190
188
  event_name: name,
191
- event_args: data
189
+ event_data: data,
190
+ event_metadata: nil
192
191
  }
193
192
 
194
193
  end
195
194
 
196
195
  def build_instance_vars_from_events events
197
196
  events.each_with_object({}) do |event, instance_vars|
198
- event_args = event[:event_args]
199
- attribute_deltas = event_args[:attribute_deltas]
197
+ event_data = event[:event_data]
198
+ attribute_deltas = event_data[:attribute_deltas]
200
199
  unless attribute_deltas.nil?
201
200
  deltas = attribute_deltas.each_with_object({}) do |delta, acc|
202
201
  acc[delta[:attribute_name]] = delta[:new_value]
@@ -206,10 +205,6 @@ module Sandthorn
206
205
  end
207
206
  end
208
207
 
209
- def first_event_snapshot? events
210
- events.first[:aggregate]
211
- end
212
-
213
208
  def create_new_empty_aggregate
214
209
  allocate
215
210
  end
@@ -256,24 +251,19 @@ module Sandthorn
256
251
  @aggregate_id = aggregate_id
257
252
  end
258
253
 
259
- def commit_with_event_name(event_name, args)
254
+ def commit_with_event_name(event_name)
260
255
  aggregate_attribute_deltas = get_delta
261
256
 
262
257
  increase_current_aggregate_version!
263
258
  data = {
264
- method_name: event_name,
265
- method_args: args,
266
259
  attribute_deltas: aggregate_attribute_deltas
267
260
  }
268
- trace_information = @aggregate_trace_information
269
- unless trace_information.nil? || trace_information.empty?
270
- data.merge!({ trace: trace_information })
271
- end
272
261
 
273
262
  @aggregate_events << ({
274
263
  aggregate_version: @aggregate_current_event_version,
275
264
  event_name: event_name,
276
- event_args: data
265
+ event_data: data,
266
+ event_metadata: @aggregate_trace_information
277
267
  })
278
268
 
279
269
  self