strum-esb 0.2.0 → 0.3.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: 100cac09566f7c972a3ea3cb7005fc3c57ecc20cc7cb4e159b43dcf4b5d9bc24
4
- data.tar.gz: dd290413c6ae5f8cc50659a487bc656500c04cd27d289cf13f10eaea14e90343
3
+ metadata.gz: 115db6eaed48ee3c437b15fbf8103815214a5cdcc4d0d040960fc6ad73708190
4
+ data.tar.gz: dd0f567ec63c61781272ea0931a7348be7df38de6661b5d9da77ccf55e17855d
5
5
  SHA512:
6
- metadata.gz: c1a9a87ba8f0207f0de46d08f19229835e29ab844f2053f38a0eb484efc191460d83a6d5e87421d1d4df09152138e753f93705035b4866c6f0ff502b2cffdadf
7
- data.tar.gz: b3f3d16931dd745a09a7cfbe938b9170c8e4efb4bf511f7de796595ad43ec683cf72c4865cbfe838ee91005b5df1431b32fa12a09fa5426a176a2f99ede62bc3
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
@@ -13,3 +13,4 @@ gem "rubocop-rspec", "~> 2.3.0"
13
13
  gem "debase", "~> 0.2.4"
14
14
  gem "ruby-debug-ide", "~> 0.7.2"
15
15
 
16
+ gem "dry-inflector", "~> 0.2.1"
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- strum-esb (0.2.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
- json (2.5.1)
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.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.1)
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.0)
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
 
@@ -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
 
@@ -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: "application/json"
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
- rabbit_exchange.publish(payload.to_json, **properties)
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Strum
4
4
  module Esb
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
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.2.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: 2021-08-26 00:00:00.000000000 Z
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