bug_bunny 1.0.0 → 2.0.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/README.md +18 -61
- data/Rakefile +5 -1
- data/lib/bug_bunny/config.rb +2 -2
- data/lib/bug_bunny/controller.rb +80 -7
- data/lib/bug_bunny/exception.rb +14 -66
- data/lib/bug_bunny/publisher.rb +115 -0
- data/lib/bug_bunny/rabbit.rb +283 -82
- data/lib/bug_bunny/resource.rb +226 -0
- data/lib/bug_bunny/version.rb +1 -1
- data/lib/bug_bunny.rb +7 -16
- metadata +7 -26
- data/Gemfile +0 -8
- data/lib/bug_bunny/adapter.rb +0 -347
- data/lib/bug_bunny/helpers.rb +0 -36
- data/lib/bug_bunny/message.rb +0 -161
- data/lib/bug_bunny/queue.rb +0 -23
- data/lib/bug_bunny/railtie.rb +0 -124
- data/lib/bug_bunny/response.rb +0 -15
- data/lib/bug_bunny/security.rb +0 -19
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bug_bunny
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- gabix
|
|
@@ -15,28 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '2.
|
|
18
|
+
version: '2.24'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '2.
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: rubocop
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - ">="
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '0'
|
|
33
|
-
type: :development
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - ">="
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '0'
|
|
25
|
+
version: '2.24'
|
|
40
26
|
description: Gem for sync and async comunication via rabbit bunny.
|
|
41
27
|
email:
|
|
42
28
|
- gab.edera@gmail.com
|
|
@@ -45,25 +31,20 @@ extensions: []
|
|
|
45
31
|
extra_rdoc_files: []
|
|
46
32
|
files:
|
|
47
33
|
- CHANGELOG.md
|
|
48
|
-
- Gemfile
|
|
49
34
|
- README.md
|
|
50
35
|
- Rakefile
|
|
51
36
|
- lib/bug_bunny.rb
|
|
52
|
-
- lib/bug_bunny/adapter.rb
|
|
53
37
|
- lib/bug_bunny/config.rb
|
|
54
38
|
- lib/bug_bunny/controller.rb
|
|
55
39
|
- lib/bug_bunny/exception.rb
|
|
56
|
-
- lib/bug_bunny/
|
|
57
|
-
- lib/bug_bunny/message.rb
|
|
58
|
-
- lib/bug_bunny/queue.rb
|
|
40
|
+
- lib/bug_bunny/publisher.rb
|
|
59
41
|
- lib/bug_bunny/rabbit.rb
|
|
60
|
-
- lib/bug_bunny/
|
|
61
|
-
- lib/bug_bunny/response.rb
|
|
62
|
-
- lib/bug_bunny/security.rb
|
|
42
|
+
- lib/bug_bunny/resource.rb
|
|
63
43
|
- lib/bug_bunny/version.rb
|
|
64
44
|
- sig/bug_bunny.rbs
|
|
65
45
|
homepage: https://github.com/gedera/bug_bunny
|
|
66
|
-
licenses:
|
|
46
|
+
licenses:
|
|
47
|
+
- MIT
|
|
67
48
|
metadata:
|
|
68
49
|
homepage_uri: https://github.com/gedera/bug_bunny
|
|
69
50
|
source_code_uri: https://github.com/gedera/bug_bunny
|
data/Gemfile
DELETED
data/lib/bug_bunny/adapter.rb
DELETED
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
module BugBunny
|
|
2
|
-
class Adapter
|
|
3
|
-
PERSIST_MESSAGE = true
|
|
4
|
-
|
|
5
|
-
SERVICE_HEALTH_CHECK = :health_check
|
|
6
|
-
TIMEOUT = 3
|
|
7
|
-
BOMBA = :bomba
|
|
8
|
-
PUBLISH_TIMEOUT = :publish_timeout
|
|
9
|
-
CONSUMER_TIMEOUT = :consumer_timeout
|
|
10
|
-
COMUNICATION_ERROR = :comunication_error
|
|
11
|
-
CONSUMER_COUNT_ZERO = :consumer_count_zero
|
|
12
|
-
|
|
13
|
-
PG_EXCEPTIONS_TO_EXIT = %w[PG::ConnectionBad PG::UnableToSend].freeze
|
|
14
|
-
|
|
15
|
-
attr_accessor :consumer,
|
|
16
|
-
:rabbit,
|
|
17
|
-
:logger,
|
|
18
|
-
:time_to_wait,
|
|
19
|
-
:communication_response,
|
|
20
|
-
:service_message
|
|
21
|
-
|
|
22
|
-
def initialize(attrs = {})
|
|
23
|
-
@logger = Logger.new('./log/bug_bunny.log', 'monthly')
|
|
24
|
-
@communication_response = ::BugBunny::Response.new status: false
|
|
25
|
-
@time_to_wait = 2
|
|
26
|
-
create_adapter_with_rabbit
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def publish!(message, publish_queue, opts = {})
|
|
30
|
-
Timeout::timeout(TIMEOUT) do
|
|
31
|
-
if opts[:check_consumers_count] && publish_queue.check_consumers.zero?
|
|
32
|
-
self.communication_response = ::BugBunny::Response.new(status: false, response: CONSUMER_COUNT_ZERO)
|
|
33
|
-
return
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
publish_opts = { routing_key: publish_queue.name,
|
|
37
|
-
persistent: opts[:persistent],
|
|
38
|
-
correlation_id: message.correlation_id }
|
|
39
|
-
|
|
40
|
-
publish_opts[:reply_to] = opts[:reply_to] if opts[:reply_to]
|
|
41
|
-
|
|
42
|
-
# Esta es la idea en el caso que nos pongamos mas mañosos y queramos cambiar las exchange a la hora de publicar.
|
|
43
|
-
# _exchange = if opts.has_key?(:exchange_type)
|
|
44
|
-
# channel.exchange(opts[:exchange_type].to_s, { type: opts[:exchange_type] })
|
|
45
|
-
# else
|
|
46
|
-
# exchange
|
|
47
|
-
# end
|
|
48
|
-
# _exchange.publish(message.to_json, publish_opts)
|
|
49
|
-
logger.debug("#{publish_queue.name}-Send Request: (#{message})")
|
|
50
|
-
|
|
51
|
-
rabbit.exchange.publish(message.to_json, publish_opts)
|
|
52
|
-
rabbit.channel.wait_for_confirms if rabbit.confirm_select
|
|
53
|
-
|
|
54
|
-
self.communication_response = ::BugBunny::Response.new(status: true)
|
|
55
|
-
end
|
|
56
|
-
rescue Timeout::Error => e
|
|
57
|
-
logger.error(e)
|
|
58
|
-
close_connection!
|
|
59
|
-
self.communication_response = ::BugBunny::Response.new(status: false, response: PUBLISH_TIMEOUT, exception: e)
|
|
60
|
-
rescue StandardError => e
|
|
61
|
-
logger.error(e)
|
|
62
|
-
close_connection!
|
|
63
|
-
self.communication_response = ::BugBunny::Response.new(status: false, response: BOMBA, exception: e)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def consume!(queue, thread: false, manual_ack: true, exclusive: false, block: true, opts: {})
|
|
67
|
-
Signal.trap('INT') { exit }
|
|
68
|
-
|
|
69
|
-
logger.debug("Suscribe consumer to: #{queue.name}")
|
|
70
|
-
logger.debug("ENTRO AL CONSUMER #{rabbit.try(:identifier)}")
|
|
71
|
-
|
|
72
|
-
self.consumer = queue.rabbit_queue.subscribe(manual_ack: manual_ack, exclusive: exclusive, block: block) do |delivery_info, metadata, json_payload|
|
|
73
|
-
# Session depends on thread info, subscribe block cleans thread info
|
|
74
|
-
# ::Session.init unless Session.tags_context
|
|
75
|
-
|
|
76
|
-
begin
|
|
77
|
-
payload = ActiveSupport::JSON.decode(json_payload).deep_symbolize_keys # Timezones pulenteado
|
|
78
|
-
rescue StandardError
|
|
79
|
-
payload = JSON.parse(json_payload).deep_symbolize_keys
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Session for Sentry logger
|
|
83
|
-
# locale, version, service_name
|
|
84
|
-
# payload.except(:body, :service_name).each do |k, v|
|
|
85
|
-
# Session.assign(k, v)
|
|
86
|
-
# end
|
|
87
|
-
# Session.from_service = payload[:service_name]
|
|
88
|
-
# Session.correlation_id = metadata.correlation_id
|
|
89
|
-
# Session.queue_name = queue.name
|
|
90
|
-
|
|
91
|
-
# unless defined?(ActiveRecord) && ActiveRecord::Base.connection_pool.with_connection(&:active?)
|
|
92
|
-
# logger.error('[PG] PG connection down')
|
|
93
|
-
# exit 7
|
|
94
|
-
# end
|
|
95
|
-
|
|
96
|
-
begin
|
|
97
|
-
message = ::BugBunny::Message.new(correlation_id: metadata.correlation_id, reply_to: metadata.reply_to, **payload)
|
|
98
|
-
|
|
99
|
-
# Default sentry info
|
|
100
|
-
# ::Session.request_id = message.correlation_id rescue nil
|
|
101
|
-
# ::Session.tags_context.merge!(
|
|
102
|
-
# server_version: message.version,
|
|
103
|
-
# service_action: message.service_action,
|
|
104
|
-
# service_name: message.service_name,
|
|
105
|
-
# isp_id: (message.body&.fetch(:isp_id, nil) rescue nil)
|
|
106
|
-
# )
|
|
107
|
-
# ::Session.extra_context[:message] = message.body
|
|
108
|
-
|
|
109
|
-
logger.info("#{queue.name}-Received Request: (#{message.service_action})")
|
|
110
|
-
logger.debug("#{queue.name}-Received Request: (#{message})")
|
|
111
|
-
logger.debug("Message will be yield")
|
|
112
|
-
logger.debug("Block given? #{block_given?}")
|
|
113
|
-
yield(message) if block_given?
|
|
114
|
-
logger.debug('Message processed')
|
|
115
|
-
|
|
116
|
-
begin
|
|
117
|
-
Timeout.timeout(5) do
|
|
118
|
-
rabbit.channel.ack delivery_info.delivery_tag if delivery_info[:consumer].manual_acknowledgement?
|
|
119
|
-
end
|
|
120
|
-
rescue Timeout::Error => e
|
|
121
|
-
logger.debug("Rabbit Identifier: #{rabbit.try(:identifier)} can not check manual_ack #{e.to_s}")
|
|
122
|
-
rescue ::StandardError => e
|
|
123
|
-
logger.debug("Rabbit Identifier: #{rabbit.try(:identifier)} can not check manual_ack #{e.to_s}")
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
self.service_message = message
|
|
127
|
-
self.communication_response = ::BugBunny::Response.new(status: true)
|
|
128
|
-
rescue ::SystemExit => e # Ensure exit code
|
|
129
|
-
raise e
|
|
130
|
-
rescue => e
|
|
131
|
-
logger.debug("Rabbit Identifier: #{rabbit.try(:identifier)}")
|
|
132
|
-
logger.error(e)
|
|
133
|
-
|
|
134
|
-
close_connection!
|
|
135
|
-
|
|
136
|
-
# Session.clean!
|
|
137
|
-
self.communication_response = ::BugBunny::Response.new(status: false, response: BOMBA, exception: e)
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
if thread # sync consumer flag :D
|
|
141
|
-
begin
|
|
142
|
-
Timeout::timeout(1) do
|
|
143
|
-
delivery_info[:consumer].cancel
|
|
144
|
-
end
|
|
145
|
-
rescue Timeout::Error => e
|
|
146
|
-
close_connection!
|
|
147
|
-
thread.exit
|
|
148
|
-
end
|
|
149
|
-
close_connection!
|
|
150
|
-
thread.exit
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
if thread
|
|
155
|
-
close_connection!
|
|
156
|
-
thread.exit
|
|
157
|
-
else
|
|
158
|
-
while true
|
|
159
|
-
begin
|
|
160
|
-
logger.debug("SALIO DEL CONSUMER #{rabbit.try(:identifier)}")
|
|
161
|
-
logger.debug(rabbit.status)
|
|
162
|
-
exit # consumer.cancel
|
|
163
|
-
rescue Bunny::NotAllowedError => e
|
|
164
|
-
logger.debug("NOT ALLOWED #{e.to_s}")
|
|
165
|
-
break
|
|
166
|
-
rescue Timeout::Error => e
|
|
167
|
-
if queue.rabbit_queue.channel.status == :closed || queue.rabbit_queue.channel.connection.status == :closed
|
|
168
|
-
logger.debug("Channel or connection closed")
|
|
169
|
-
break
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
sleep time_to_wait
|
|
173
|
-
logger.debug("Rabbit Identifier: #{rabbit.try(:identifier)}")
|
|
174
|
-
logger.error(e)
|
|
175
|
-
retry
|
|
176
|
-
rescue StandardError => e
|
|
177
|
-
if queue.rabbit_queue.channel.status == :closed || queue.rabbit_queue.channel.connection.status == :closed
|
|
178
|
-
logger.debug("Channel or connection closed")
|
|
179
|
-
break
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
sleep time_to_wait
|
|
183
|
-
logger.debug("Rabbit Identifier: #{rabbit.try(:identifier)}")
|
|
184
|
-
logger.error(e)
|
|
185
|
-
retry
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
rescue Timeout::Error => e
|
|
190
|
-
logger.debug("Rabbit Identifier: #{rabbit.try(:identifier)}")
|
|
191
|
-
logger.error(e)
|
|
192
|
-
close_connection!
|
|
193
|
-
::BugBunny::Response.new(status: false, response: CONSUMER_TIMEOUT, exception: e)
|
|
194
|
-
rescue StandardError => e
|
|
195
|
-
logger.debug("Rabbit Identifier: #{rabbit.try(:identifier)}")
|
|
196
|
-
logger.error(e)
|
|
197
|
-
close_connection!
|
|
198
|
-
::BugBunny::Response.new(status: false, response: BOMBA, exception: e)
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def publish_and_consume!(publish_message, sync_queue, opts={})
|
|
202
|
-
reply_queue = build_queue('', initialize: true, exclusive: true, durable: false, auto_delete: true)
|
|
203
|
-
|
|
204
|
-
retries = 0
|
|
205
|
-
begin
|
|
206
|
-
publish!(publish_message, sync_queue, opts.merge(reply_to: reply_queue.name))
|
|
207
|
-
rescue
|
|
208
|
-
if (retries += 1) <= 3
|
|
209
|
-
sleep 0.5
|
|
210
|
-
retry
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
close_connection!
|
|
214
|
-
raise
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
return communication_response unless communication_response.success?
|
|
218
|
-
|
|
219
|
-
t = Thread.new do
|
|
220
|
-
retries = 0
|
|
221
|
-
begin
|
|
222
|
-
consume!(reply_queue, thread: Thread.current, exclusive: true) do |msg|
|
|
223
|
-
yield(msg) if block_given?
|
|
224
|
-
end
|
|
225
|
-
rescue
|
|
226
|
-
if (retries += 1) <= 3
|
|
227
|
-
sleep 0.5
|
|
228
|
-
retry
|
|
229
|
-
end
|
|
230
|
-
raise
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
t.join
|
|
234
|
-
communication_response
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
def build_queue(name, opts = {})
|
|
238
|
-
init = opts.key?(:initialize) ? opts[:initialize] : true
|
|
239
|
-
new_queue = ::BugBunny::Queue.new(opts.merge(name: name))
|
|
240
|
-
|
|
241
|
-
if init
|
|
242
|
-
logger.debug("Building rabbit new_queue: #{name} status: #{rabbit.status} queue_options: #{new_queue.options}")
|
|
243
|
-
|
|
244
|
-
retries = 0
|
|
245
|
-
begin
|
|
246
|
-
built_queue = rabbit.channel.queue(new_queue.name.to_s, new_queue.options)
|
|
247
|
-
rescue StandardError
|
|
248
|
-
if (retries += 1) <= 3
|
|
249
|
-
sleep 0.5
|
|
250
|
-
retry
|
|
251
|
-
end
|
|
252
|
-
raise
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
new_queue.rabbit_queue = built_queue
|
|
256
|
-
new_queue.name = new_queue.rabbit_queue.name
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
new_queue
|
|
260
|
-
rescue Timeout::Error, StandardError => e
|
|
261
|
-
logger.debug("Rabbit Identifier: #{rabbit.try(:identifier)}")
|
|
262
|
-
logger.debug("Status adapter created: #{rabbit.status}")
|
|
263
|
-
logger.error(e)
|
|
264
|
-
|
|
265
|
-
close_connection!
|
|
266
|
-
raise Exception::ComunicationRabbitError.new(COMUNICATION_ERROR, e.backtrace)
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
def self.make_response(comunication_result, consume_result = nil)
|
|
270
|
-
if comunication_result.success?
|
|
271
|
-
consume_result || comunication_result
|
|
272
|
-
else
|
|
273
|
-
comunication_result.response = comunication_result.response.to_s
|
|
274
|
-
comunication_result
|
|
275
|
-
end
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
def make_response
|
|
279
|
-
if communication_response.success?
|
|
280
|
-
service_message || communication_response
|
|
281
|
-
else
|
|
282
|
-
communication_response.response = communication_response.response.to_s
|
|
283
|
-
communication_response
|
|
284
|
-
end
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
def status
|
|
288
|
-
rabbit.try(:status)
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
def close_connection!
|
|
292
|
-
rabbit.try(:close)
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
def check_pg_exception!(exception)
|
|
296
|
-
# el consumidor no reconecta (rails tasks) asi que salimos a la goma
|
|
297
|
-
if PG_EXCEPTIONS_TO_EXIT.any? { |msg| exception.try(:message)&.starts_with?(msg) }
|
|
298
|
-
exit 7 # salimos con un int especial para identificarlo
|
|
299
|
-
end
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
private
|
|
303
|
-
|
|
304
|
-
# AMQ::Protocol::EmptyResponseError: Este error lo note cuando el rabbit
|
|
305
|
-
# acepta la connection pero aun no ha terminado de inicializar el servicio,
|
|
306
|
-
# por lo que salta esta exception.
|
|
307
|
-
# Errno::ECONNRESET: Este error se presenta cuando justo esta arrancando
|
|
308
|
-
# el rabbit y se quiere conectar al mismo. El rabbit resetea la connection,
|
|
309
|
-
# haciendo saltar esta exception.
|
|
310
|
-
def create_adapter_with_rabbit
|
|
311
|
-
self.rabbit = ::BugBunny::Rabbit.new(confirm_select: true, logger: logger)
|
|
312
|
-
rescue Bunny::NetworkFailure, Bunny::TCPConnectionFailed,
|
|
313
|
-
Bunny::ConnectionForced, AMQ::Protocol::EmptyResponseError,
|
|
314
|
-
Errno::ECONNRESET => e
|
|
315
|
-
|
|
316
|
-
logger.debug(e)
|
|
317
|
-
close_connection!
|
|
318
|
-
raise Exception::ComunicationRabbitError.new(COMUNICATION_ERROR, e.backtrace)
|
|
319
|
-
rescue OpenSSL::SSL::SSLError, OpenSSL::X509::CertificateError => e
|
|
320
|
-
# el `e.to_s` devuelve alguno de los sgtes errores. Por ej:
|
|
321
|
-
# SSL_connect returned=1 errno=0 state=unknown state: sslv3
|
|
322
|
-
# alert bad certificate
|
|
323
|
-
# SSL_CTX_use_PrivateKey: key values mismatch
|
|
324
|
-
# OpenSSL::X509::CertificateError: not enough data // headers too short
|
|
325
|
-
if respond_to?(:handle_ssl_issues)
|
|
326
|
-
handle_ssl_issues # esto pide los certificados de nuevo
|
|
327
|
-
@retries ||= 0
|
|
328
|
-
@retries += 1
|
|
329
|
-
sleep 1
|
|
330
|
-
retry if @retries < 4
|
|
331
|
-
@retries = 0 # reset the counter
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
# Si sigue fallando desp de 3 veces o no tiene definido el handle
|
|
335
|
-
# bombita rodriguez
|
|
336
|
-
logger.error(e)
|
|
337
|
-
|
|
338
|
-
close_connection!
|
|
339
|
-
raise Exception::ComunicationRabbitError.new(COMUNICATION_ERROR, e.backtrace)
|
|
340
|
-
rescue Timeout::Error, StandardError => e
|
|
341
|
-
logger.error(e)
|
|
342
|
-
|
|
343
|
-
close_connection!
|
|
344
|
-
raise Exception::ComunicationRabbitError.new(COMUNICATION_ERROR, e.backtrace)
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
end
|
data/lib/bug_bunny/helpers.rb
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
module BugBunny
|
|
2
|
-
module Helpers
|
|
3
|
-
extend self
|
|
4
|
-
|
|
5
|
-
def datetime_values_to_utc(data)
|
|
6
|
-
case data
|
|
7
|
-
when Hash
|
|
8
|
-
data.inject({}) {|memo, (k, v)| memo.merge!({k => datetime_values_to_utc(v)}) }
|
|
9
|
-
when Array
|
|
10
|
-
data.map {|e| datetime_values_to_utc(e) }
|
|
11
|
-
when DateTime, Time
|
|
12
|
-
data.to_time.utc.iso8601
|
|
13
|
-
else
|
|
14
|
-
data
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def utc_values_to_local(data)
|
|
19
|
-
case data
|
|
20
|
-
when Hash
|
|
21
|
-
data.inject({}) {|memo, (k, v)| memo.merge!({k => utc_values_to_local(v)}) }
|
|
22
|
-
when Array
|
|
23
|
-
data.map {|e| utc_values_to_local(e) }
|
|
24
|
-
when DateTime, Time
|
|
25
|
-
data.to_time.localtime # ensure we always use Time instances
|
|
26
|
-
when /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:.*Z$/
|
|
27
|
-
t = Time.respond_to?(:zone) ? Time.zone.parse(data) : Time.parse(data)
|
|
28
|
-
t.to_time.localtime
|
|
29
|
-
when /^\d{4}-\d{2}-\d{2}$/
|
|
30
|
-
Date.parse(data)
|
|
31
|
-
else
|
|
32
|
-
data
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
data/lib/bug_bunny/message.rb
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
module BugBunny
|
|
2
|
-
class Message
|
|
3
|
-
# API ERROR RESPONSE KEY
|
|
4
|
-
FIELD_ERROR = :field
|
|
5
|
-
SERVER_ERROR = :server
|
|
6
|
-
|
|
7
|
-
# API ERROR RESPONSE CODES
|
|
8
|
-
MISSING_FIELD = :missing
|
|
9
|
-
UNKNOWN_FIELD = :unknown
|
|
10
|
-
NOT_FOUND = :not_found
|
|
11
|
-
NO_ACTION = :no_action
|
|
12
|
-
TIMEOUT = :timeout
|
|
13
|
-
BOMBA = :bomba
|
|
14
|
-
|
|
15
|
-
attr_accessor :correlation_id,
|
|
16
|
-
:body,
|
|
17
|
-
:signature,
|
|
18
|
-
:errors,
|
|
19
|
-
:status,
|
|
20
|
-
:service_name,
|
|
21
|
-
:service_action,
|
|
22
|
-
:version,
|
|
23
|
-
:reply_to,
|
|
24
|
-
:exception
|
|
25
|
-
|
|
26
|
-
def initialize(opts = {})
|
|
27
|
-
@correlation_id = opts[:correlation_id] || SecureRandom.uuid
|
|
28
|
-
@body = deserialize_body(opts[:body] || opts[:response] || {})
|
|
29
|
-
@errors = opts[:errors]
|
|
30
|
-
@status = opts[:status] || :success
|
|
31
|
-
@service_name = opts[:service_name]
|
|
32
|
-
@service_action = opts[:service_action] # Deberiamos raisear si esto no viene...
|
|
33
|
-
@version = opts[:version]
|
|
34
|
-
@signature = opts[:signature]
|
|
35
|
-
@reply_to = opts[:reply_to]
|
|
36
|
-
@exception = opts[:exception]
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def server_not_found!
|
|
40
|
-
server_error! [NOT_FOUND]
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def server_timeout!
|
|
44
|
-
server_error! [TIMEOUT]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def server_no_action!
|
|
48
|
-
server_error! [NO_ACTION]
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def server_error!(errors=nil)
|
|
52
|
-
self.status = :error
|
|
53
|
-
self.body = {}
|
|
54
|
-
if errors
|
|
55
|
-
self.errors ||= {}
|
|
56
|
-
self.errors[SERVER_ERROR] ||= []
|
|
57
|
-
self.errors[SERVER_ERROR] += [errors].flatten # just in case
|
|
58
|
-
else
|
|
59
|
-
self.exception = Exception::ServiceError.new
|
|
60
|
-
end
|
|
61
|
-
self
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def signed?
|
|
65
|
-
signature.present?
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def sign!(key)
|
|
69
|
-
self.signature = ::BugBunny::Security.sign_message(key, body.to_json)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def invalid_signature?(key)
|
|
73
|
-
!valid_signature?(key)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def valid_signature?(key)
|
|
77
|
-
return if signature.blank?
|
|
78
|
-
|
|
79
|
-
::BugBunny::Security.check_sign(key, signature, body.to_json)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def formatted
|
|
83
|
-
resp = {
|
|
84
|
-
correlation_id: correlation_id,
|
|
85
|
-
version: version,
|
|
86
|
-
status: status,
|
|
87
|
-
service_name: service_name,
|
|
88
|
-
service_action: service_action,
|
|
89
|
-
signature: signature,
|
|
90
|
-
errors: errors,
|
|
91
|
-
body: serialize_body
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if exception
|
|
95
|
-
# resp[:exception] = exception.backtrace.join("\n") rescue nil
|
|
96
|
-
resp[:exception] = [
|
|
97
|
-
exception.to_s,
|
|
98
|
-
exception.try(:backtrace) || []
|
|
99
|
-
].flatten.join("\n") rescue exception.to_s
|
|
100
|
-
|
|
101
|
-
unless ::BugBunny::Exception::ServiceClasses.include?(exception.class)
|
|
102
|
-
self.exception = Exception::ServiceError.new
|
|
103
|
-
end
|
|
104
|
-
resp[:errors] ||= {}
|
|
105
|
-
unless resp[:errors][SERVER_ERROR]&.any?
|
|
106
|
-
resp[:errors][SERVER_ERROR] ||= []
|
|
107
|
-
resp[:errors][SERVER_ERROR] << exception.to_s
|
|
108
|
-
end
|
|
109
|
-
resp[:status] = self.status = :critical
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
resp
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def to_json
|
|
116
|
-
formatted.to_json
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def to_s
|
|
120
|
-
to_json # Asegurarse de que siempre se llame al "formatted"
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def to_h
|
|
124
|
-
formatted
|
|
125
|
-
rescue StandardError
|
|
126
|
-
original_to_h
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
alias :original_to_h :to_h
|
|
130
|
-
|
|
131
|
-
def success?
|
|
132
|
-
status.to_sym == :success
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def error?
|
|
136
|
-
status.to_sym == :error
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def critical?
|
|
140
|
-
status.to_sym == :critical
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def build_message(params = {})
|
|
144
|
-
Message.new({ version: version, correlation_id: correlation_id, service_action: service_action }.merge(params))
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def serialize_body
|
|
148
|
-
Helpers.datetime_values_to_utc(body)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def deserialize_body(body)
|
|
152
|
-
Helpers.utc_values_to_local(body)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# def critical_response
|
|
156
|
-
# ::BugBunny::ParserMessage.humanize_error(errors, :adapter)
|
|
157
|
-
# rescue StandarError
|
|
158
|
-
# [:general_error]
|
|
159
|
-
# end
|
|
160
|
-
end
|
|
161
|
-
end
|
data/lib/bug_bunny/queue.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module BugBunny
|
|
2
|
-
class Queue
|
|
3
|
-
attr_accessor :name, :auto_delete, :durable, :exclusive, :rabbit_queue
|
|
4
|
-
|
|
5
|
-
def initialize(attrs={})
|
|
6
|
-
# "Real" queue opts
|
|
7
|
-
@name = attrs.fetch(:name, 'undefined')
|
|
8
|
-
@auto_delete = attrs.fetch(:auto_delete, true)
|
|
9
|
-
@durable = attrs.fetch(:durable, false)
|
|
10
|
-
@exclusive = attrs.fetch(:exclusive, false)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def options
|
|
14
|
-
{ durable: durable, exclusive: exclusive, auto_delete: auto_delete }
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def check_consumers
|
|
18
|
-
rabbit_queue.consumer_count
|
|
19
|
-
rescue StandardError
|
|
20
|
-
0
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|