strum-esb 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -5
- data/README.md +39 -0
- data/lib/strum/esb/handler.rb +21 -2
- data/lib/strum/esb/message.rb +10 -4
- data/lib/strum/esb/serializer.rb +69 -0
- data/lib/strum/esb/version.rb +1 -1
- data/lib/strum/esb.rb +5 -0
- data/strum-esb.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 115db6eaed48ee3c437b15fbf8103815214a5cdcc4d0d040960fc6ad73708190
|
4
|
+
data.tar.gz: dd0f567ec63c61781272ea0931a7348be7df38de6661b5d9da77ccf55e17855d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3275b5108de6e8f5ac0bf8413d8fb53e0939855c9621fb1ac054b5ae9ecc693ff368a5d55d5e794956f75f038ba106eb4c3452c377b273eda7e064f713b6b605
|
7
|
+
data.tar.gz: 679fc2e04636143bbfcceb7fba20cb79972475313ed2731977035b1ceb21ca981d77247b03fc668c92d3e809894edeae16e5b74f92afbde55b2d21a77f287c4d
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
# Changelog
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [0.3.0] - 2022-03-14
|
6
|
+
### Added
|
7
|
+
- `content_type` option to send message by [@valeriia.kolisnyk]
|
8
|
+
- serialization/deserialization for protobuf by [@valeriia.kolisnyk]
|
9
|
+
- `json` and `protobuf_service` switchers for handler by [@valeriia.kolisnyk]
|
10
|
+
|
5
11
|
## [0.1.1] - 2021-06-01
|
6
12
|
### Added
|
7
13
|
- `pre_publish_hooks` to configuration by [@Samuron]
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
strum-esb (0.
|
4
|
+
strum-esb (0.3.0)
|
5
5
|
bunny (~> 2.15)
|
6
6
|
connection_pool (~> 2.2.2)
|
7
7
|
dry-configurable (~> 0.12.1)
|
8
|
+
dry-inflector (~> 0.2.1)
|
8
9
|
json (~> 2.3)
|
9
10
|
sneakers (~> 2.12)
|
10
11
|
|
@@ -27,13 +28,14 @@ GEM
|
|
27
28
|
dry-core (~> 0.5, >= 0.5.0)
|
28
29
|
dry-core (0.7.1)
|
29
30
|
concurrent-ruby (~> 1.0)
|
30
|
-
|
31
|
+
dry-inflector (0.2.1)
|
32
|
+
json (2.6.1)
|
31
33
|
parallel (1.20.1)
|
32
34
|
parser (3.0.1.1)
|
33
35
|
ast (~> 2.4.1)
|
34
36
|
rainbow (3.0.0)
|
35
37
|
rake (12.3.3)
|
36
|
-
rbtree (0.4.
|
38
|
+
rbtree (0.4.5)
|
37
39
|
regexp_parser (2.1.1)
|
38
40
|
rexml (3.2.5)
|
39
41
|
rspec (3.10.0)
|
@@ -68,7 +70,7 @@ GEM
|
|
68
70
|
ruby-progressbar (1.11.0)
|
69
71
|
serverengine (2.1.1)
|
70
72
|
sigdump (~> 0.2.2)
|
71
|
-
set (1.0.
|
73
|
+
set (1.0.2)
|
72
74
|
sigdump (0.2.4)
|
73
75
|
sneakers (2.12.0)
|
74
76
|
bunny (~> 2.14)
|
@@ -79,7 +81,7 @@ GEM
|
|
79
81
|
sorted_set (1.0.3)
|
80
82
|
rbtree
|
81
83
|
set (~> 1.0)
|
82
|
-
thor (1.1
|
84
|
+
thor (1.2.1)
|
83
85
|
unicode-display_width (2.0.0)
|
84
86
|
|
85
87
|
PLATFORMS
|
@@ -88,6 +90,7 @@ PLATFORMS
|
|
88
90
|
DEPENDENCIES
|
89
91
|
bundler (~> 2.1.4)
|
90
92
|
debase (~> 0.2.4)
|
93
|
+
dry-inflector (~> 0.2.1)
|
91
94
|
rspec (~> 3)
|
92
95
|
rubocop (~> 1.15)
|
93
96
|
rubocop-rspec (~> 2.3.0)
|
data/README.md
CHANGED
@@ -94,6 +94,45 @@ module Queues
|
|
94
94
|
end
|
95
95
|
```
|
96
96
|
|
97
|
+
### Sending protobuf via strum-esb
|
98
|
+
1. Encode your protobuf message using `encode` method to send it.
|
99
|
+
2. Define `protobuf_service` in your handler, and disable `json`:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
require "strum/esb"
|
103
|
+
require "contracts/test_pb"
|
104
|
+
|
105
|
+
module Queues
|
106
|
+
class Resource
|
107
|
+
include Strum::Esb::Handler
|
108
|
+
|
109
|
+
json false
|
110
|
+
protobuf_service Test::Router::Service
|
111
|
+
from_queue "resource-queue",
|
112
|
+
bindings: {
|
113
|
+
events: %w[user/create user/update],
|
114
|
+
|
115
|
+
}
|
116
|
+
|
117
|
+
def handler(payload)
|
118
|
+
# code here ...
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
Your rpc action must have the same name as your method in queue class, for example: if method is `action_get_user`, rpc action needs to be `ActionGetUser`.
|
125
|
+
|
126
|
+
3. Pass content type as additional param when you send Strum::Esb message:
|
127
|
+
```ruby
|
128
|
+
Strum::Esb::Action.call("payload", "action", "resource", content_type: "application/x-protobuf")
|
129
|
+
```
|
130
|
+
or add it as before_publish_hook:
|
131
|
+
```ruby
|
132
|
+
Strum::Esb.config.before_publish_hooks << lambda { |_body, properties|
|
133
|
+
properties[:content_type] = "application/x-protobuf"
|
134
|
+
}
|
135
|
+
```
|
97
136
|
|
98
137
|
## Development
|
99
138
|
|
data/lib/strum/esb/handler.rb
CHANGED
@@ -30,12 +30,19 @@ module Strum
|
|
30
30
|
def handlers
|
31
31
|
@handlers || {}
|
32
32
|
end
|
33
|
+
|
34
|
+
def protobuf_service(service)
|
35
|
+
Strum::Esb.config.protobuf_service = service
|
36
|
+
end
|
37
|
+
|
38
|
+
def json(switcher)
|
39
|
+
Strum::Esb.config.json = switcher
|
40
|
+
end
|
33
41
|
end
|
34
42
|
|
35
43
|
def work_with_params(deserialized_msg, delivery_info, metadata)
|
36
44
|
Strum::Esb.config.before_handler_hooks.each { |hook| hook.call(deserialized_msg, delivery_info, metadata) }
|
37
45
|
|
38
|
-
payload = JSON.parse(deserialized_msg)
|
39
46
|
snake_case_modify = ->(string) { string.nil? ? nil : string&.to_s.gsub(/[^a-zA-Z0-9]/, "_")&.downcase }
|
40
47
|
parse_header = ->(string) { metadata[:headers] && metadata[:headers][string] }
|
41
48
|
header = parse_header >> snake_case_modify
|
@@ -64,6 +71,18 @@ module Strum
|
|
64
71
|
|
65
72
|
method_name = ([*methods_names] << "handler").find { |n| respond_to?(n, include_all: true) }
|
66
73
|
|
74
|
+
unless Strum::Esb.config.serializer.enabled?(metadata[:content_type])
|
75
|
+
logger.error "Content type #{metadata[:content_type]} is disabled by handler. Message rejected #{metadata[:headers]} with payload #{deserialized_msg}"
|
76
|
+
return reject!
|
77
|
+
end
|
78
|
+
|
79
|
+
payload, valid_payload = Strum::Esb.config.serializer.deserialize(deserialized_msg, metadata[:content_type], method_name)
|
80
|
+
|
81
|
+
unless valid_payload
|
82
|
+
logger.error "Content type is invalid. Message rejected #{metadata[:headers]} with payload #{payload}"
|
83
|
+
return reject!
|
84
|
+
end
|
85
|
+
|
67
86
|
unless method_name
|
68
87
|
logger.error "Handler not found. Message rejected #{metadata[:headers]} with payload #{payload}"
|
69
88
|
return reject!
|
@@ -83,7 +102,7 @@ module Strum
|
|
83
102
|
error = e
|
84
103
|
logger.error e
|
85
104
|
reject!
|
86
|
-
ensure
|
105
|
+
ensure
|
87
106
|
Strum::Esb.config.after_handler_hooks.each { |hook| hook.call(deserialized_msg, delivery_info, metadata, payload, error) }
|
88
107
|
end
|
89
108
|
|
data/lib/strum/esb/message.rb
CHANGED
@@ -5,11 +5,11 @@ module Strum
|
|
5
5
|
# Strum Message
|
6
6
|
class Message
|
7
7
|
class << self
|
8
|
-
def publish(exchange:, headers:, payload:)
|
8
|
+
def publish(exchange:, headers:, payload:, content_type: "application/json")
|
9
9
|
rabbit_exchange ||= Strum::Esb.config.rabbit_channel_pool.with { |rabbit_channel| rabbit_channel.headers(exchange, durable: true) }
|
10
10
|
properties = {
|
11
11
|
headers: headers,
|
12
|
-
content_type:
|
12
|
+
content_type: content_type
|
13
13
|
}
|
14
14
|
|
15
15
|
Strum::Esb.config.before_publish_hooks.each { |hook| hook.call(payload, properties) }
|
@@ -21,8 +21,14 @@ module Strum
|
|
21
21
|
payload["chain"] ||= chain
|
22
22
|
headers["chain"] ||= chain
|
23
23
|
end
|
24
|
-
|
25
|
-
|
24
|
+
|
25
|
+
payload, valid_payload = Strum::Esb.config.serializer.serialize(payload, properties[:content_type])
|
26
|
+
unless valid_payload
|
27
|
+
Sneakers.logger.error "Content type is invalid. Message rejected #{properties[:headers]} with payload #{payload}"
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
rabbit_exchange.publish(payload, **properties)
|
26
32
|
end
|
27
33
|
end
|
28
34
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strum
|
4
|
+
module Esb
|
5
|
+
# Payload serializer/deserializer
|
6
|
+
class Serializer
|
7
|
+
CONTENT_TYPES = %w[application/json application/x-protobuf].freeze
|
8
|
+
|
9
|
+
%i[serialize deserialize].each do |base_method|
|
10
|
+
define_method base_method do |payload, content_type, queue_method_name = nil|
|
11
|
+
return [payload, false] unless valid_content_type?(content_type)
|
12
|
+
|
13
|
+
perform_method_name = content_type_method_name(base_method, content_type)
|
14
|
+
payload = send(*[perform_method_name, payload, queue_method_name].compact)
|
15
|
+
[payload, true]
|
16
|
+
rescue StandardError
|
17
|
+
[payload, false]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def enabled?(content_type)
|
22
|
+
case data_type(content_type)
|
23
|
+
when "json"
|
24
|
+
Strum::Esb.config.json
|
25
|
+
when "protobuf"
|
26
|
+
Strum::Esb.config.protobuf_service
|
27
|
+
else
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def valid_content_type?(content_type)
|
35
|
+
CONTENT_TYPES.include?(content_type)
|
36
|
+
end
|
37
|
+
|
38
|
+
def content_type_method_name(action, content_type)
|
39
|
+
"#{action}_#{data_type(content_type)}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def data_type(content_type)
|
43
|
+
content_type.gsub("-", "/").split("/").last
|
44
|
+
end
|
45
|
+
|
46
|
+
def deserialize_json(payload, _queue_method_name)
|
47
|
+
JSON.parse(payload)
|
48
|
+
end
|
49
|
+
|
50
|
+
def deserialize_protobuf(payload, queue_method_name)
|
51
|
+
action_name = inflector.camelize(queue_method_name)
|
52
|
+
rpc_struct = Strum::Esb.config.protobuf_service.rpc_descs[action_name.to_sym]
|
53
|
+
rpc_struct.input.decode(payload)
|
54
|
+
end
|
55
|
+
|
56
|
+
def serialize_json(payload)
|
57
|
+
payload.to_json
|
58
|
+
end
|
59
|
+
|
60
|
+
def serialize_protobuf(payload)
|
61
|
+
payload
|
62
|
+
end
|
63
|
+
|
64
|
+
def inflector
|
65
|
+
Dry::Inflector.new
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/strum/esb/version.rb
CHANGED
data/lib/strum/esb.rb
CHANGED
@@ -15,6 +15,8 @@ require "strum/esb/event"
|
|
15
15
|
require "strum/esb/notice"
|
16
16
|
require "strum/esb/info"
|
17
17
|
require "dry/configurable"
|
18
|
+
require "dry/inflector"
|
19
|
+
require "strum/esb/serializer"
|
18
20
|
|
19
21
|
module Strum
|
20
22
|
module Esb
|
@@ -38,6 +40,9 @@ module Strum
|
|
38
40
|
setting :before_publish_hooks, []
|
39
41
|
setting :before_handler_hooks, []
|
40
42
|
setting :after_handler_hooks, []
|
43
|
+
setting :serializer, Serializer.new
|
44
|
+
setting :protobuf_service, false
|
45
|
+
setting :json, true
|
41
46
|
|
42
47
|
Strum::Esb.config.before_fork_hooks << proc { DB.disconnect } if defined?(DB)
|
43
48
|
|
data/strum-esb.gemspec
CHANGED
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_dependency "bunny", "~> 2.15"
|
32
32
|
spec.add_dependency "connection_pool", "~> 2.2.2"
|
33
33
|
spec.add_dependency "dry-configurable", "~> 0.12.1"
|
34
|
+
spec.add_dependency "dry-inflector", "~> 0.2.1"
|
34
35
|
spec.add_dependency "json", "~> 2.3"
|
35
36
|
spec.add_dependency "sneakers", "~> 2.12"
|
36
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strum-esb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Serhiy Nazarov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.12.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: dry-inflector
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.1
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.2.1
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: json
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +121,7 @@ files:
|
|
107
121
|
- lib/strum/esb/info.rb
|
108
122
|
- lib/strum/esb/message.rb
|
109
123
|
- lib/strum/esb/notice.rb
|
124
|
+
- lib/strum/esb/serializer.rb
|
110
125
|
- lib/strum/esb/version.rb
|
111
126
|
- lib/strum/patch/sneakers/queue_patch.rb
|
112
127
|
- strum-esb.gemspec
|