evnt 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +118 -24
- data/lib/evnt/command.rb +3 -3
- data/lib/evnt/event.rb +1 -1
- data/lib/evnt/version.rb +2 -4
- data/lib/generators/evnt/command_generator.rb +38 -0
- data/lib/generators/evnt/event_generator.rb +36 -0
- data/lib/generators/evnt/handler_generator.rb +35 -0
- data/lib/generators/evnt/initializer_generator.rb +25 -0
- data/lib/generators/evnt/templates/command/command.rb.erb +13 -0
- data/lib/generators/evnt/templates/event/event.rb.erb +15 -0
- data/lib/generators/evnt/templates/handler/handler.rb.erb +13 -0
- data/lib/generators/evnt/templates/initializer/app/commands/application_command.rb +5 -0
- data/lib/generators/evnt/templates/initializer/app/events/application_event.rb +5 -0
- data/lib/generators/evnt/templates/initializer/app/handlers/application_handler.rb +5 -0
- data/lib/generators/evnt/templates/initializer/test/commands/application_command_test.rb +14 -0
- data/lib/generators/evnt/templates/initializer/test/events/application_event_test.rb +15 -0
- data/lib/generators/evnt/templates/initializer/test/handlers/application_handler_test.rb +13 -0
- metadata +16 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0d2cecb4f90544de842098f1f89110548ef2a2231504ac0cf47f821bf0abfbb3
|
4
|
+
data.tar.gz: 731c1460b90c981043850df9a5a5b6cc6b9a4d1d0b780859e2070cd0d94c8047
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e93adc9ffeead5ee8632b41d1bee8a030376d1876f61bf6d8e5c4f077fb5efda56c7a3a92a62493a3e3f118a153be0436dc9c5eb6ee87cd335530efc7f9300c9
|
7
|
+
data.tar.gz: 69e531d6aa91fd78f31c75bd3eb4cc30e9848f917bde1e81e191959633736f85e4b3ae7638104df84ecaf5bdaf32f301f8ec6e1348deb44c02ffeffb7895b82d
|
data/README.md
CHANGED
@@ -8,14 +8,25 @@ CQRS and Event Driven Development architecture for Ruby projects.
|
|
8
8
|
- [Event](#event)
|
9
9
|
- [Handler](#handler)
|
10
10
|
- [Rails integration](#rails-integration)
|
11
|
+
- [Generators integration](#generators-integration)
|
12
|
+
- [Command generators](#command-generators)
|
13
|
+
- [Event generators](#event-generators)
|
14
|
+
- [Handler generators](#handler-generators)
|
15
|
+
- [Manual integration](#manual-integration)
|
11
16
|
- [Development](#development)
|
12
17
|
|
13
|
-
Full documentation here: https://ideonetwork.github.io/
|
18
|
+
Full documentation here: https://ideonetwork.github.io/evnt/
|
14
19
|
|
15
20
|
## Installation
|
16
21
|
|
17
22
|
To use the gem you need to add it on your Gemfile
|
18
23
|
|
24
|
+
Latest version
|
25
|
+
```ruby
|
26
|
+
gem 'evnt', git: 'https://github.com/ideonetwork/evnt'
|
27
|
+
```
|
28
|
+
|
29
|
+
Legacy version
|
19
30
|
```ruby
|
20
31
|
gem 'evnt'
|
21
32
|
```
|
@@ -30,7 +41,7 @@ Evnt is developed to be used over all kinds of projects and frameworks (like Rub
|
|
30
41
|
|
31
42
|
### Command
|
32
43
|
|
33
|
-
Commands are used to run single tasks on the system. It's like a controller on an MVC architecture
|
44
|
+
Commands are used to run single tasks on the system. It's like a controller on an MVC architecture.
|
34
45
|
|
35
46
|
Every command has three steps to execute:
|
36
47
|
|
@@ -44,15 +55,16 @@ An example of command should be:
|
|
44
55
|
```ruby
|
45
56
|
class CreateOrderCommand < Evnt::Command
|
46
57
|
|
58
|
+
validates :user_id, type: :integer, presence: true
|
59
|
+
validates :product_id, type: :integer, presence: true
|
60
|
+
validates :quantity, type: :integer, presence: true
|
61
|
+
|
47
62
|
to_normalize_params do
|
48
63
|
params[:quantity] = params[:quantity].to_i
|
49
64
|
end
|
50
65
|
|
51
66
|
to_validate_params do
|
52
|
-
|
53
|
-
err 'User should be present' if params[:user_id].blank?
|
54
|
-
err 'Product should be present' if params[:product_id].blank?
|
55
|
-
err 'Quantity should be present' if params[:quantity].blank?
|
67
|
+
err 'Quantity should be positive' unless params[:quantity].positive?
|
56
68
|
end
|
57
69
|
|
58
70
|
to_validate_logic do
|
@@ -136,22 +148,6 @@ rescue => e
|
|
136
148
|
end
|
137
149
|
```
|
138
150
|
|
139
|
-
Some validations are similar for every command (like presence or paramter type), so you can also use general validations instead of **to_validate_params** block. An example of general validations should be:
|
140
|
-
|
141
|
-
```ruby
|
142
|
-
|
143
|
-
class CreateOrderCommand < Evnt::Command
|
144
|
-
|
145
|
-
validates :user_id, type: :integer, presence: true
|
146
|
-
validates :product_id, type: :integer, presence: true
|
147
|
-
validates :quantity, type: :integer, presence: true
|
148
|
-
|
149
|
-
# ...
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
```
|
154
|
-
|
155
151
|
### Event
|
156
152
|
|
157
153
|
Events are used to save on a persistent data structure what happends on the system.
|
@@ -180,7 +176,10 @@ class CreateOrderEvent < Evnt::Event
|
|
180
176
|
|
181
177
|
to_write_event do
|
182
178
|
# save event on database
|
183
|
-
Event.create(
|
179
|
+
Event.create(
|
180
|
+
name: name,
|
181
|
+
payload: payload
|
182
|
+
)
|
184
183
|
end
|
185
184
|
|
186
185
|
end
|
@@ -201,7 +200,7 @@ puts event.attributes # -> [:order_id, :user_id, :product_id, :quantity]
|
|
201
200
|
puts event.payload # -> { order_id: 1, user_id: 128, product_id: 534, quantity: 10, evnt: { timestamp: 2017010101, name: 'create_order' } }
|
202
201
|
```
|
203
202
|
|
204
|
-
The event payload should contain all event attributes and a
|
203
|
+
The event payload should contain all event attributes and a reserved attributes "evnt" used to store the event timestamp and the event name.
|
205
204
|
|
206
205
|
It's also possible to give datas to the event without save them on the event payload, to do this you shuld only use a key with "_" as first character. An example should be:
|
207
206
|
|
@@ -283,6 +282,101 @@ end
|
|
283
282
|
|
284
283
|
Evnt can be used with Ruby on Rails to extends the MVC pattern.
|
285
284
|
|
285
|
+
### Generators integration
|
286
|
+
|
287
|
+
There's a simple generator that can be used to inizialize a Rails application with Evnt.
|
288
|
+
|
289
|
+
```shell
|
290
|
+
|
291
|
+
rails generate evnt:initializer
|
292
|
+
|
293
|
+
```
|
294
|
+
|
295
|
+
This command should:
|
296
|
+
|
297
|
+
- Create an **application_command.rb** on app/commands directory.
|
298
|
+
- Create an **application_event.rb** on app/events directory.
|
299
|
+
- Create an **application_handler.rb** on app/handlers directory.
|
300
|
+
- Create tests for the three new classes added on the project.
|
301
|
+
- Added app/commands, app/events and app/handlers on config.autoload_paths setting of the application.
|
302
|
+
|
303
|
+
#### Command generators
|
304
|
+
|
305
|
+
Usage:
|
306
|
+
|
307
|
+
```shell
|
308
|
+
|
309
|
+
rails generate evnt:command Authentication::LoginCommand email:string password:string ip_address:string
|
310
|
+
|
311
|
+
```
|
312
|
+
|
313
|
+
Output:
|
314
|
+
|
315
|
+
```ruby
|
316
|
+
# ./app/commands/authentication/login_command.rb
|
317
|
+
module Authentication
|
318
|
+
class LoginCommand < ApplicationCommand
|
319
|
+
|
320
|
+
validates :email, type: :string
|
321
|
+
|
322
|
+
validates :password, type: :string
|
323
|
+
|
324
|
+
validates :ip_address, type: :string
|
325
|
+
|
326
|
+
end
|
327
|
+
end
|
328
|
+
```
|
329
|
+
|
330
|
+
#### Event generators
|
331
|
+
|
332
|
+
Usage:
|
333
|
+
|
334
|
+
```shell
|
335
|
+
|
336
|
+
rails generate evnt:event Authentication::LoginEvent user_uuid ip_address
|
337
|
+
|
338
|
+
```
|
339
|
+
|
340
|
+
Output:
|
341
|
+
|
342
|
+
```ruby
|
343
|
+
# ./app/events/authentication/login_event.rb
|
344
|
+
module Authentication
|
345
|
+
class LoginEvent < ApplicationEvent
|
346
|
+
|
347
|
+
name_is :authentication_login_event
|
348
|
+
|
349
|
+
attributes_are :user_uuid, :ip_address
|
350
|
+
|
351
|
+
end
|
352
|
+
end
|
353
|
+
```
|
354
|
+
|
355
|
+
#### Handler generators
|
356
|
+
|
357
|
+
Usage:
|
358
|
+
|
359
|
+
```shell
|
360
|
+
|
361
|
+
rails generate evnt:handler AuthenticationHandler authentication_login_event authentication_signup_event
|
362
|
+
|
363
|
+
```
|
364
|
+
|
365
|
+
Output:
|
366
|
+
|
367
|
+
```ruby
|
368
|
+
# ./app/handlers/authentication_handler.rb
|
369
|
+
class AuthenticationHandler < ApplicationHandler
|
370
|
+
|
371
|
+
on :authentication_login_event do; end
|
372
|
+
|
373
|
+
on :authentication_signup_event do; end
|
374
|
+
|
375
|
+
end
|
376
|
+
```
|
377
|
+
|
378
|
+
### Manual integration
|
379
|
+
|
286
380
|
To use the gem with Rails you need to create three folders inside the ./app project's path:
|
287
381
|
|
288
382
|
- **./app/commands**
|
data/lib/evnt/command.rb
CHANGED
@@ -26,7 +26,7 @@ module Evnt
|
|
26
26
|
#
|
27
27
|
# * +exceptions+ - Boolean value used to activate the throw of excetions.
|
28
28
|
##
|
29
|
-
def initialize(params)
|
29
|
+
def initialize(params = {})
|
30
30
|
_init_command_data(params)
|
31
31
|
_run_command_steps
|
32
32
|
end
|
@@ -96,7 +96,7 @@ module Evnt
|
|
96
96
|
)
|
97
97
|
|
98
98
|
# raise error if command needs exceptions
|
99
|
-
raise
|
99
|
+
raise message if @options[:exceptions]
|
100
100
|
end
|
101
101
|
|
102
102
|
# Private functions:
|
@@ -111,7 +111,7 @@ module Evnt
|
|
111
111
|
result: true,
|
112
112
|
errors: []
|
113
113
|
}
|
114
|
-
|
114
|
+
|
115
115
|
# set options
|
116
116
|
options = params[:_options] || {}
|
117
117
|
@options = {
|
data/lib/evnt/event.rb
CHANGED
data/lib/evnt/version.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/base'
|
4
|
+
|
5
|
+
module Evnt
|
6
|
+
|
7
|
+
# CommandGenerator.
|
8
|
+
class CommandGenerator < Rails::Generators::Base
|
9
|
+
|
10
|
+
source_root File.expand_path('../templates', __FILE__)
|
11
|
+
|
12
|
+
argument :informations, type: :array, optional: false
|
13
|
+
|
14
|
+
def create_comand
|
15
|
+
path = informations.first.split('::')
|
16
|
+
@command_class = path.last.camelize
|
17
|
+
@command_modules = path - [path.last]
|
18
|
+
@command_params = (informations - [informations.first]).map do |data|
|
19
|
+
data = data.split(':')
|
20
|
+
data.length > 1 ? ":#{data.first}, type: :#{data.last}" : ":#{data.first}"
|
21
|
+
end
|
22
|
+
|
23
|
+
template(
|
24
|
+
'./command/command.rb.erb',
|
25
|
+
command_path
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def command_path
|
30
|
+
path = './app/commands'
|
31
|
+
@command_modules.map { |m| path = "#{path}/#{m.underscore}" }
|
32
|
+
path = "#{path}/#{@command_class.underscore}.rb"
|
33
|
+
path
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/base'
|
4
|
+
|
5
|
+
module Evnt
|
6
|
+
|
7
|
+
# EventGenerator.
|
8
|
+
class EventGenerator < Rails::Generators::Base
|
9
|
+
|
10
|
+
source_root File.expand_path('../templates', __FILE__)
|
11
|
+
|
12
|
+
argument :informations, type: :array, optional: false
|
13
|
+
|
14
|
+
def create_event
|
15
|
+
path = informations.first.split('::')
|
16
|
+
@event_class = path.last.camelize
|
17
|
+
@event_modules = path - [path.last]
|
18
|
+
@event_name = path.map(&:underscore).join('_')
|
19
|
+
@event_attributes = (informations - [informations.first]).map { |a| ":#{a}" }.join(', ')
|
20
|
+
|
21
|
+
template(
|
22
|
+
'./event/event.rb.erb',
|
23
|
+
event_path
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def event_path
|
28
|
+
path = './app/events'
|
29
|
+
@event_modules.map { |m| path = "#{path}/#{m.underscore}" }
|
30
|
+
path = "#{path}/#{@event_class.underscore}.rb"
|
31
|
+
path
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/base'
|
4
|
+
|
5
|
+
module Evnt
|
6
|
+
|
7
|
+
# HandlerGenerator.
|
8
|
+
class HandlerGenerator < Rails::Generators::Base
|
9
|
+
|
10
|
+
source_root File.expand_path('../templates', __FILE__)
|
11
|
+
|
12
|
+
argument :informations, type: :array, optional: false
|
13
|
+
|
14
|
+
def create_handler
|
15
|
+
path = informations.first.split('::')
|
16
|
+
@handler_class = path.last.camelize
|
17
|
+
@handler_modules = path - [path.last]
|
18
|
+
@handler_events = (informations - [informations.first])
|
19
|
+
|
20
|
+
template(
|
21
|
+
'./handler/handler.rb.erb',
|
22
|
+
handler_path
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def handler_path
|
27
|
+
path = './app/handlers'
|
28
|
+
@handler_modules.map { |m| path = "#{path}/#{m.underscore}" }
|
29
|
+
path = "#{path}/#{@handler_class.underscore}.rb"
|
30
|
+
path
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/base'
|
4
|
+
|
5
|
+
module Evnt
|
6
|
+
|
7
|
+
# InitializerGenerator.
|
8
|
+
class InitializerGenerator < Rails::Generators::Base
|
9
|
+
|
10
|
+
source_root File.expand_path('../templates', __FILE__)
|
11
|
+
|
12
|
+
def create_initializer
|
13
|
+
directory './initializer', './'
|
14
|
+
update_config_application
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_config_application
|
18
|
+
application "config.autoload_paths += %W[\#{Rails.root}/app/commands]"
|
19
|
+
application "config.autoload_paths += %W[\#{Rails.root}/app/events]"
|
20
|
+
application "config.autoload_paths += %W[\#{Rails.root}/app/handlers]"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
<% @command_modules.each_with_index do |module_name, index| %>
|
3
|
+
<%= ' ' * index %>module <%= module_name %>
|
4
|
+
<% end %>
|
5
|
+
<%= ' ' * @command_modules.length %># <%= @command_class %>
|
6
|
+
<%= ' ' * @command_modules.length %>class <%= @command_class %> < ApplicationCommand
|
7
|
+
<% @command_params.each do |param| %>
|
8
|
+
<%= ' ' * (@command_modules.length + 1) %>validates <%= param %>
|
9
|
+
<% end %>
|
10
|
+
<%= ' ' * @command_modules.length %>end
|
11
|
+
<% @command_modules.each_with_index do |_module_name, index| %>
|
12
|
+
<%= ' ' * (@command_modules.length - index - 1) %>end
|
13
|
+
<% end %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
<% @event_modules.each_with_index do |module_name, index| %>
|
3
|
+
<%= ' ' * index %>module <%= module_name %>
|
4
|
+
<% end %>
|
5
|
+
<%= ' ' * @event_modules.length %># <%= @event_class %>
|
6
|
+
<%= ' ' * @event_modules.length %>class <%= @event_class %> < ApplicationEvent
|
7
|
+
|
8
|
+
<%= ' ' * (@event_modules.length + 1) %>name_is :<%= @event_name %>
|
9
|
+
<% unless @event_attributes.blank? %>
|
10
|
+
<%= ' ' * (@event_modules.length + 1) %>attributes_are <%= @event_attributes %>
|
11
|
+
<% end %>
|
12
|
+
<%= ' ' * @event_modules.length %>end
|
13
|
+
<% @event_modules.each_with_index do |_module_name, index| %>
|
14
|
+
<%= ' ' * (@event_modules.length - index - 1) %>end
|
15
|
+
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
<% @handler_modules.each_with_index do |module_name, index| %>
|
3
|
+
<%= ' ' * index %>module <%= module_name %>
|
4
|
+
<% end %>
|
5
|
+
<%= ' ' * @handler_modules.length %># <%= @handler_class %>
|
6
|
+
<%= ' ' * @handler_modules.length %>class <%= @handler_class %> < ApplicationHandler
|
7
|
+
<% @handler_events.each do |event| %>
|
8
|
+
<%= ' ' * (@handler_modules.length + 1) %>on :<%= event %> do; end
|
9
|
+
<% end %>
|
10
|
+
<%= ' ' * @handler_modules.length %>end
|
11
|
+
<% @handler_modules.each_with_index do |_module_name, index| %>
|
12
|
+
<%= ' ' * (@handler_modules.length - index - 1) %>end
|
13
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
# ApplicationCommandTest.
|
6
|
+
class ApplicationCommandTest < ActiveSupport::TestCase
|
7
|
+
|
8
|
+
test 'it should be initialized' do
|
9
|
+
command = ApplicationCommand.new
|
10
|
+
assert_not_nil command
|
11
|
+
assert command.completed?
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
# ApplicationEventTest.
|
6
|
+
class ApplicationEventTest < ActiveSupport::TestCase
|
7
|
+
|
8
|
+
test 'it should be initialized' do
|
9
|
+
event = ApplicationEvent.new
|
10
|
+
assert_not_nil event
|
11
|
+
assert_not_nil event.payload
|
12
|
+
assert_not_nil event.payload[:evnt]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
# ApplicationHandlerTest.
|
6
|
+
class ApplicationHandlerTest < ActiveSupport::TestCase
|
7
|
+
|
8
|
+
test 'it should be initialized' do
|
9
|
+
handler = ApplicationHandler.new
|
10
|
+
assert_not_nil handler
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evnt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ideonetwork
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -67,6 +67,19 @@ files:
|
|
67
67
|
- lib/evnt/handler.rb
|
68
68
|
- lib/evnt/validator.rb
|
69
69
|
- lib/evnt/version.rb
|
70
|
+
- lib/generators/evnt/command_generator.rb
|
71
|
+
- lib/generators/evnt/event_generator.rb
|
72
|
+
- lib/generators/evnt/handler_generator.rb
|
73
|
+
- lib/generators/evnt/initializer_generator.rb
|
74
|
+
- lib/generators/evnt/templates/command/command.rb.erb
|
75
|
+
- lib/generators/evnt/templates/event/event.rb.erb
|
76
|
+
- lib/generators/evnt/templates/handler/handler.rb.erb
|
77
|
+
- lib/generators/evnt/templates/initializer/app/commands/application_command.rb
|
78
|
+
- lib/generators/evnt/templates/initializer/app/events/application_event.rb
|
79
|
+
- lib/generators/evnt/templates/initializer/app/handlers/application_handler.rb
|
80
|
+
- lib/generators/evnt/templates/initializer/test/commands/application_command_test.rb
|
81
|
+
- lib/generators/evnt/templates/initializer/test/events/application_event_test.rb
|
82
|
+
- lib/generators/evnt/templates/initializer/test/handlers/application_handler_test.rb
|
70
83
|
homepage: http://ideonetwork.it/
|
71
84
|
licenses:
|
72
85
|
- MIT
|
@@ -87,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
100
|
version: '0'
|
88
101
|
requirements: []
|
89
102
|
rubyforge_project:
|
90
|
-
rubygems_version: 2.
|
103
|
+
rubygems_version: 2.7.3
|
91
104
|
signing_key:
|
92
105
|
specification_version: 4
|
93
106
|
summary: CQRS and Event Driven Development architecture for Ruby
|