strum-esb 0.3.3 → 0.4.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
  SHA256:
3
- metadata.gz: 5eed53438b480b0f9f2faae4b2662dfb7005441bd74f62b15986d4eefeefbe7e
4
- data.tar.gz: c8f52bbfc3955ca0735d1536e99fc07238ef6a823b84e602a242fad9b690646c
3
+ metadata.gz: ec01fbb52f6e4bbf0ae78e81b2c6c0d427b6724efc6e8a93283a595a21b512de
4
+ data.tar.gz: 57bd11fdbbd47f201d9d962893a160df528ab94c48410904df86c938bdcafc8d
5
5
  SHA512:
6
- metadata.gz: c4eb4852df47c231e43218243178582e860f3dc553b06f5f8f32165b27c4a7d2448f01ac690b59617b4e724927db4224b9311791df77a8aff3a70ada43b3f9a0
7
- data.tar.gz: c0a6ce6875f528459031905df09bdcccc1cc1fa34e6ed6eecfa5863647b8d711b38879f8c13afb1ff915c7ce642a92637bfc7bc559df40921cd30761baab2c53
6
+ metadata.gz: 97c3b7ebbe683fb790b66ac59abf913af645025a72b94cabbd5e0d8c114c8ef3c4cbd7c31b87c1c212e00f07499c807f71e2af1db8265856856693e8649cff9f
7
+ data.tar.gz: d7483cb8f561e2b07f11c5cc7a177af1fc9a6b9a01347b5458d76624fff02462d898ed7ec84ba61f8c6aa435814d058b7bd3e99e6dead29d336c4d97734c50ab
data/Gemfile CHANGED
@@ -6,9 +6,9 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "bundler", "~> 2.1.4"
9
- gem "rspec", "~> 3"
10
- gem "rubocop", "~> 1.15"
11
- gem "rubocop-rspec", "~> 2.3.0"
9
+ gem "rspec", "~> 3.11.0"
10
+ gem "rubocop", "~> 1.36.0"
11
+ gem "rubocop-rspec", "~> 2.12.1"
12
12
 
13
13
  gem "debase", "~> 0.2.5.beta2"
14
14
  gem "ruby-debug-ide", "~> 0.7.2"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- strum-esb (0.3.3)
4
+ strum-esb (0.4.0)
5
5
  bunny (~> 2.15)
6
6
  connection_pool (~> 2.2.2)
7
7
  dry-configurable (~> 0.12.1)
@@ -26,17 +26,17 @@ GEM
26
26
  dry-configurable (0.12.1)
27
27
  concurrent-ruby (~> 1.0)
28
28
  dry-core (~> 0.5, >= 0.5.0)
29
- dry-core (0.7.1)
29
+ dry-core (0.8.1)
30
30
  concurrent-ruby (~> 1.0)
31
31
  dry-inflector (0.2.1)
32
32
  json (2.6.2)
33
33
  parallel (1.22.1)
34
- parser (3.1.1.0)
34
+ parser (3.1.2.1)
35
35
  ast (~> 2.4.1)
36
36
  rainbow (3.1.1)
37
37
  rake (12.3.3)
38
38
  rbtree (0.4.5)
39
- regexp_parser (2.2.1)
39
+ regexp_parser (2.5.0)
40
40
  rexml (3.2.5)
41
41
  rspec (3.11.0)
42
42
  rspec-core (~> 3.11.0)
@@ -51,26 +51,26 @@ GEM
51
51
  diff-lcs (>= 1.2.0, < 2.0)
52
52
  rspec-support (~> 3.11.0)
53
53
  rspec-support (3.11.0)
54
- rubocop (1.26.1)
54
+ rubocop (1.36.0)
55
+ json (~> 2.3)
55
56
  parallel (~> 1.10)
56
- parser (>= 3.1.0.0)
57
+ parser (>= 3.1.2.1)
57
58
  rainbow (>= 2.2.2, < 4.0)
58
59
  regexp_parser (>= 1.8, < 3.0)
59
- rexml
60
- rubocop-ast (>= 1.16.0, < 2.0)
60
+ rexml (>= 3.2.5, < 4.0)
61
+ rubocop-ast (>= 1.20.1, < 2.0)
61
62
  ruby-progressbar (~> 1.7)
62
63
  unicode-display_width (>= 1.4.0, < 3.0)
63
- rubocop-ast (1.16.0)
64
+ rubocop-ast (1.21.0)
64
65
  parser (>= 3.1.1.0)
65
- rubocop-rspec (2.3.0)
66
- rubocop (~> 1.0)
67
- rubocop-ast (>= 1.1.0)
66
+ rubocop-rspec (2.12.1)
67
+ rubocop (~> 1.31)
68
68
  ruby-debug-ide (0.7.3)
69
69
  rake (>= 0.8.1)
70
70
  ruby-progressbar (1.11.0)
71
71
  serverengine (2.1.1)
72
72
  sigdump (~> 0.2.2)
73
- set (1.0.2)
73
+ set (1.0.3)
74
74
  sigdump (0.2.4)
75
75
  sneakers (2.12.0)
76
76
  bunny (~> 2.14)
@@ -82,7 +82,7 @@ GEM
82
82
  rbtree
83
83
  set (~> 1.0)
84
84
  thor (1.2.1)
85
- unicode-display_width (2.1.0)
85
+ unicode-display_width (2.2.0)
86
86
 
87
87
  PLATFORMS
88
88
  ruby
@@ -91,9 +91,9 @@ DEPENDENCIES
91
91
  bundler (~> 2.1.4)
92
92
  debase (~> 0.2.5.beta2)
93
93
  dry-inflector (~> 0.2.1)
94
- rspec (~> 3)
95
- rubocop (~> 1.15)
96
- rubocop-rspec (~> 2.3.0)
94
+ rspec (~> 3.11.0)
95
+ rubocop (~> 1.36.0)
96
+ rubocop-rspec (~> 2.12.1)
97
97
  ruby-debug-ide (~> 0.7.2)
98
98
  strum-esb!
99
99
 
data/README.md CHANGED
@@ -106,8 +106,9 @@ module Queues
106
106
  class Resource
107
107
  include Strum::Esb::Handler
108
108
 
109
- json false
110
- protobuf_service Test::Router::Service
109
+ enable_json false
110
+ enable_protobuf true
111
+ use_protobuf_service Test::Router::Service
111
112
  from_queue "resource-queue",
112
113
  bindings: {
113
114
  events: %w[user/create user/update],
@@ -125,12 +126,24 @@ Your rpc action must have the same name as your method in queue class, for examp
125
126
 
126
127
  3. Pass content type as additional param when you send Strum::Esb message:
127
128
  ```ruby
128
- Strum::Esb::Action.call("payload", "action", "resource", content_type: "application/x-protobuf")
129
+ message = { id: 10 }
130
+ args = {
131
+ content_type: "application/x-protobuf",
132
+ message_class: Messages::ActionGetUser
133
+ }
134
+ Strum::Esb::Action.call(message, "action", "resource", **args)
129
135
  ```
130
- or add it as before_publish_hook:
136
+
137
+ 4. Configure proto serialization/deserialization:
131
138
  ```ruby
132
- Strum::Esb.config.before_publish_hooks << lambda { |_body, properties|
133
- properties[:content_type] = "application/x-protobuf"
139
+ Strum::Esb.config.serializer_conf = {
140
+ to_proto: proc do |message_class, payload|
141
+ ::CustomSerializer.to_protobuf(message_class, payload).to_proto
142
+ end,
143
+ from_proto: proc do |message_class, encoded_payload|
144
+ rpc_instance = message_class.decode(encoded_payload)
145
+ ::CustomSerializer.from_protobuf(rpc_instance)
146
+ end
134
147
  }
135
148
  ```
136
149
 
@@ -12,6 +12,7 @@ module Strum
12
12
  include Sneakers::Worker
13
13
  end
14
14
  base.extend ClassMethods
15
+ base.use_application_config
15
16
  end
16
17
 
17
18
  module ClassMethods
@@ -22,16 +23,16 @@ module Strum
22
23
  yield(bindings)
23
24
  else
24
25
  bindings[message_type] ||= []
25
- bindings[message_type] << message_binding
26
+ bindings[message_type] << message_binding
26
27
  end
27
28
 
28
29
  from_queue queue, bindings: bindings
29
- handlers[handler_key(message_type, message_binding)] = handler.to_s if handler
30
+ handlers[handler_key(message_type, message_binding)] = handler.to_s if handler
30
31
  end
31
32
 
32
33
  def handler_key(message_type, message_binding)
33
34
  _, *msg = Strum::Esb::Functions.public_send("#{message_type}_explain", message_binding)
34
- params = msg.map{ |param| param&.to_s.gsub(/[^a-zA-Z0-9]/, "_")&.downcase }
35
+ params = msg.map { |param| param&.to_s&.gsub(/[^a-zA-Z0-9]/, "_")&.downcase }
35
36
  ([message_type] + params).join("-")
36
37
  end
37
38
 
@@ -39,12 +40,47 @@ module Strum
39
40
  @handlers ||= {}
40
41
  end
41
42
 
42
- def protobuf_service(service)
43
- Strum::Esb.config.protobuf_service = service
43
+ def enable_json(switcher)
44
+ @json_mode = switcher
44
45
  end
45
46
 
46
- def json(switcher)
47
- Strum::Esb.config.json = switcher
47
+ def json_enabled?
48
+ @json_mode
49
+ end
50
+
51
+ def enable_protobuf(switcher)
52
+ @protobuf_mode = switcher
53
+ end
54
+
55
+ def protobuf_enabled?
56
+ @protobuf_mode
57
+ end
58
+
59
+ def content_type_enabled?(content_type)
60
+ case content_type
61
+ when "application/json"
62
+ json_enabled?
63
+ when "application/x-protobuf"
64
+ protobuf_enabled?
65
+ else
66
+ false
67
+ end
68
+ end
69
+
70
+ def use_protobuf_service(service)
71
+ raise ArgumentError, "#{service} must be a grpc service" unless service.respond_to?(:rpc_descs)
72
+
73
+ @protobuf_service = service
74
+ enable_protobuf(true)
75
+ end
76
+
77
+ def protobuf_service
78
+ @protobuf_service
79
+ end
80
+
81
+ def use_application_config
82
+ enable_json(Strum::Esb.config.enable_json)
83
+ enable_protobuf(Strum::Esb.config.enable_protobuf)
48
84
  end
49
85
  end
50
86
 
@@ -85,12 +121,14 @@ module Strum
85
121
 
86
122
  content_type = metadata[:content_type] || "application/json"
87
123
 
88
- unless Strum::Esb.config.serializer.enabled?(content_type)
124
+ unless self.class.content_type_enabled?(content_type)
89
125
  logger.error "Content type #{content_type} is disabled by handler. Message rejected #{metadata[:headers]} with payload #{deserialized_msg}"
90
126
  return reject!
91
127
  end
92
128
 
93
- payload, valid_payload = Strum::Esb.config.serializer.deserialize(deserialized_msg, content_type, method_name)
129
+ args = { queue_method_name: method_name, grpc_service: self.class.protobuf_service, content_type: content_type }
130
+
131
+ payload, valid_payload = Strum::Esb.config.serializer.deserialize(deserialized_msg, args: args)
94
132
 
95
133
  unless valid_payload
96
134
  logger.error "Payload was unable to be parsed with #{content_type} content type. Message rejected #{metadata[:headers]} with payload #{payload}"
@@ -153,7 +191,7 @@ module Strum
153
191
  result << "notice_#{notice}"
154
192
  result << "notice_handler"
155
193
  result
156
- end
194
+ end
157
195
  end
158
196
  end
159
197
  end
@@ -5,26 +5,26 @@ module Strum
5
5
  # Strum Message
6
6
  class Message
7
7
  class << self
8
- def publish(exchange:, headers:, payload:, content_type: "application/json")
9
- rabbit_exchange ||= Strum::Esb.config.rabbit_channel_pool.with { |rabbit_channel| rabbit_channel.headers(exchange, durable: true) }
10
- properties = {
11
- headers: headers,
12
- content_type: content_type
13
- }
8
+ def publish(exchange:, headers:, payload:, **args)
9
+ rabbit_exchange ||= Strum::Esb.config.rabbit_channel_pool.with do |rabbit_channel|
10
+ rabbit_channel.headers(exchange, durable: true)
11
+ end
12
+
13
+ properties = { headers: headers, content_type: args.fetch(:content_type, "application/json") }
14
14
 
15
15
  Strum::Esb.config.before_publish_hooks.each { |hook| hook.call(payload, properties) }
16
+ args.merge!(properties)
17
+
18
+ payload, valid_payload = Strum::Esb.config.serializer.serialize(payload, args: args)
19
+ return unless valid_payload
20
+
21
+ rabbit_exchange.publish(payload, **properties)
22
+ end
16
23
 
24
+ def extend_headers(properties)
17
25
  properties[:headers] = {} unless properties[:headers].is_a?(Hash)
18
26
  properties[:headers]["pipeline"] ||= Thread.current[:pipeline] if Thread.current[:pipeline]
19
27
  properties[:headers]["pipeline-id"] ||= Thread.current[:pipeline_id] if Thread.current[:pipeline_id]
20
-
21
- payload, valid_payload = Strum::Esb.config.serializer.serialize(payload, properties[:content_type])
22
- unless valid_payload
23
- Sneakers.logger.error "Content type is invalid. Message rejected #{properties[:headers]} with payload #{payload}"
24
- return
25
- end
26
-
27
- rabbit_exchange.publish(payload, **properties)
28
28
  end
29
29
  end
30
30
  end
@@ -7,28 +7,20 @@ module Strum
7
7
  CONTENT_TYPES = %w[application/json application/x-protobuf].freeze
8
8
 
9
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)
10
+ define_method base_method do |payload, args: {}|
11
+ content_type = args.fetch(:content_type)
12
+ raise ArgumentError, "invalid content_type" unless valid_content_type?(content_type)
12
13
 
13
14
  perform_method_name = content_type_method_name(base_method, content_type)
14
- payload = send(*[perform_method_name, payload, queue_method_name].compact)
15
+ payload = send(perform_method_name, payload, args: args)
15
16
  [payload, true]
16
- rescue StandardError
17
+ rescue StandardError => e
18
+ Sneakers.logger.error(e.inspect)
19
+ Sneakers.logger.error "Content type is invalid. Message rejected #{args[:headers]} with payload #{payload}"
17
20
  [payload, false]
18
21
  end
19
22
  end
20
23
 
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
24
  private
33
25
 
34
26
  def valid_content_type?(content_type)
@@ -43,22 +35,24 @@ module Strum
43
35
  content_type.gsub("-", "/").split("/").last
44
36
  end
45
37
 
46
- def deserialize_json(payload, _queue_method_name)
38
+ def deserialize_json(payload, args: {}) # rubocop:disable Lint/UnusedMethodArgument
47
39
  JSON.parse(payload)
48
40
  end
49
41
 
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)
42
+ def deserialize_protobuf(payload, args: {})
43
+ action_name = inflector.camelize(args.fetch(:queue_method_name))
44
+ message_class = args.fetch(:grpc_service).rpc_descs[action_name.to_sym].input
45
+
46
+ Strum::Esb.config.serializer_conf[:from_proto].call(message_class, payload)
54
47
  end
55
48
 
56
- def serialize_json(payload)
49
+ def serialize_json(payload, args: {}) # rubocop:disable Lint/UnusedMethodArgument
57
50
  payload.to_json
58
51
  end
59
52
 
60
- def serialize_protobuf(payload)
61
- payload
53
+ def serialize_protobuf(payload, args: {})
54
+ message_class = args.fetch(:message_class)
55
+ Strum::Esb.config.serializer_conf[:to_proto].call(message_class, payload)
62
56
  end
63
57
 
64
58
  def inflector
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Strum
4
4
  module Esb
5
- VERSION = "0.3.3"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
data/lib/strum/esb.rb CHANGED
@@ -40,9 +40,18 @@ module Strum
40
40
  setting :before_publish_hooks, []
41
41
  setting :before_handler_hooks, []
42
42
  setting :after_handler_hooks, []
43
+
43
44
  setting :serializer, Serializer.new
44
- setting :protobuf_service, false
45
- setting :json, true
45
+ setting :enable_json, true
46
+ setting :enable_protobuf, false
47
+ setting :serializer_conf, {
48
+ to_proto: proc do |message_class, payload|
49
+ message_class.new(payload).to_proto
50
+ end,
51
+ from_proto: proc do |message_class, encoded_payload|
52
+ message_class.decode(encoded_payload).to_h
53
+ end
54
+ }
46
55
 
47
56
  Strum::Esb.config.before_fork_hooks << proc { DB.disconnect } if defined?(DB)
48
57
 
@@ -56,12 +65,12 @@ module Strum
56
65
  @app = app
57
66
  @args = args
58
67
  end
59
-
68
+
60
69
  def call(deserialized_msg, delivery_info, metadata, handler)
61
- Thread.current.keys.each{ |key| Thread.current[key] = nil }
70
+ Thread.current.keys.each { |key| Thread.current[key] = nil }
62
71
  @app.call(deserialized_msg, delivery_info, metadata, handler)
63
72
  end
64
- end
73
+ end
65
74
 
66
75
  Sneakers.configure(
67
76
  log: $stdout,
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.3.3
4
+ version: 0.4.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: 2022-07-18 00:00:00.000000000 Z
11
+ date: 2022-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny