rservicebus2 0.2.5 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RServiceBus2
2
4
  # Given a directory, this class is responsible for finding
3
5
  # msgnames,
@@ -20,10 +22,10 @@ module RServiceBus2
20
22
  # setBusAttributeIfRequested
21
23
  #
22
24
  # @param [RServiceBus2::Handler] handler
23
- def set_bus_attribute_if_requested(handler)
25
+ def conditionally_set_bus_attribute(handler)
24
26
  if defined?(handler.bus)
25
27
  handler.bus = @host
26
- RServiceBus2.log 'Bus attribute set for: ' + handler.class.name
28
+ RServiceBus2.log "Bus attribute set for: #{handler.class.name}"
27
29
  end
28
30
 
29
31
  self
@@ -32,10 +34,10 @@ module RServiceBus2
32
34
  # setStateAttributeIfRequested
33
35
  #
34
36
  # @param [RServiceBus2::Handler] handler
35
- def set_state_attribute_if_requested(handler)
37
+ def conditionally_set_state_attribute(handler)
36
38
  if defined?(handler.state)
37
39
  handler.state = @state_manager.get(handler)
38
- RServiceBus2.log 'Bus attribute set for: ' + handler.class.name
40
+ RServiceBus2.log "Bus attribute set for: #{handler.class.name}"
39
41
  end
40
42
 
41
43
  self
@@ -50,29 +52,29 @@ module RServiceBus2
50
52
  self
51
53
  end
52
54
 
55
+ # rubocop:disable Metrics/AbcSize
53
56
  def interrogate_handler_for_app_resources(handler)
54
- RServiceBus2.rlog "Checking app resources for: #{handler.class.name}"
55
- RServiceBus2.rlog "If your attribute is not getting set, check that it is in the 'attr_accessor' list"
57
+ RServiceBus2.rlog "Checking app resources for: #{handler.class.name}\n" \
58
+ "If your attribute is not getting set, check that it is in the 'attr_accessor' list"
56
59
 
57
60
  @resource_list_by_handler_name[handler.class.name] = []
58
- @resource_manager.get_all.each do |k, v|
61
+ @resource_manager.all.each do |k, _v|
59
62
  next unless handler.class.method_defined?(k)
60
63
 
61
64
  @resource_list_by_handler_name[handler.class.name] << k
62
- RServiceBus2.log "Resource attribute, #{k}, found for: " +
63
- handler.class.name
65
+ RServiceBus2.log "Resource attribute, #{k}, found for: #{handler.class.name}"
64
66
  end
65
-
66
- self
67
67
  end
68
+ # rubocop:enable Metrics/AbcSize
68
69
 
69
70
  def add_handler(lc_msg_name, handler)
70
- msg_name = lc_msg_name.gsub(/(?<=_|^)(\w)/){$1.upcase}.gsub(/(?:_)(\w)/,'\1') # Turn snake_case string to CamelCase
71
+ # Turn snake_case string to CamelCase
72
+ msg_name = lc_msg_name.gsub(/(?<=_|^)(\w)/) { Regexp.last_match(1).upcase }.gsub(/(?:_)(\w)/, '\1')
71
73
  @handler_list[msg_name] = [] if @handler_list[msg_name].nil?
72
- return unless @handler_list[msg_name].index{ |x| x.class.name == handler.class.name }.nil?
74
+ return unless @handler_list[msg_name].index { |x| x.instance_of(handler) }.nil?
73
75
 
74
76
  @handler_list[msg_name] << handler
75
- set_bus_attribute_if_requested(handler)
77
+ conditionally_set_bus_attribute(handler)
76
78
  check_if_state_attribute_requested(handler)
77
79
  interrogate_handler_for_app_resources(handler)
78
80
  end
@@ -86,28 +88,32 @@ module RServiceBus2
86
88
 
87
89
  list = []
88
90
  @handler_list[msg_name].each do |handler|
89
- list = list + @resource_list_by_handler_name[handler.class.name] unless @resource_list_by_handler_name[handler.class.name].nil?
91
+ unless @resource_list_by_handler_name[handler.class.name].nil?
92
+ list += @resource_list_by_handler_name[handler.class.name]
93
+ end
90
94
  end
91
95
  list.uniq!
92
96
  end
93
97
 
94
- def set_resources_for_handlers_needed_to_process_msg(msg_name)
98
+ # rubocop:disable Metrics/AbcSize
99
+ def conditionally_set_resources_for_handlers(msg_name)
95
100
  @handler_list[msg_name].each do |handler|
96
- set_state_attribute_if_requested(handler)
97
-
101
+ conditionally_set_state_attribute(handler)
98
102
  next if @resource_list_by_handler_name[handler.class.name].nil?
103
+
99
104
  @resource_list_by_handler_name[handler.class.name].each do |k|
100
105
  handler.instance_variable_set("@#{k}", @resource_manager.get(k).get_resource)
101
- RServiceBus2.rlog "App resource attribute, #{k}, set for: " + handler.class.name
106
+ RServiceBus2.rlog "App resource attribute, #{k}, set for: #{handler.class.name}"
102
107
  end
103
108
  end
104
109
  end
110
+ # rubocop:enable Metrics/AbcSize
105
111
 
106
112
  def get_handler_list_for_msg(msg_name)
107
113
  return [] if @handler_list[msg_name].nil?
108
114
 
109
- list = get_list_of_resources_needed_to_process_msg(msg_name)
110
- set_resources_for_handlers_needed_to_process_msg(msg_name)
115
+ # list = get_list_of_resources_needed_to_process_msg(msg_name)
116
+ conditionally_set_resources_for_handlers(msg_name)
111
117
 
112
118
  @handler_list[msg_name]
113
119
  end
@@ -116,16 +122,16 @@ module RServiceBus2
116
122
  @handler_list.key?(msg_name)
117
123
  end
118
124
 
119
- def get_stats
125
+ def stats
120
126
  list = []
121
- @handler_list.each do |k, v|
127
+ @handler_list.each do |_k, v|
122
128
  list << v.inspect
123
129
  end
124
130
 
125
131
  list
126
132
  end
127
133
 
128
- def get_list_of_msg_names
134
+ def msg_names
129
135
  @handler_list.keys
130
136
  end
131
137
  end
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Helper functions
1
4
  module RServiceBus2
2
5
  def self.convert_dto_to_hash(obj)
3
6
  hash = {}
@@ -35,7 +38,7 @@ module RServiceBus2
35
38
  end
36
39
 
37
40
  def self.get_value(name, default = nil)
38
- value = (ENV[name].nil? || ENV[name] == '') ? default : ENV[name]
41
+ value = ENV[name].nil? || ENV[name] == '' ? default : ENV[name]
39
42
  log "Env value: #{name}: #{value}"
40
43
  value
41
44
  end
@@ -50,7 +53,6 @@ module RServiceBus2
50
53
  agent = RServiceBus2::Agent.new
51
54
  Audit.new(agent).audit_to_queue(msg)
52
55
  agent.send_msg(msg, queue_name, response_queue)
53
-
54
56
  rescue QueueNotFoundForMsg => e
55
57
  msg = "\n"
56
58
  msg = "#{msg}*** Queue not found for, #{e.message}\n"
@@ -76,10 +78,12 @@ module RServiceBus2
76
78
 
77
79
  def self.check_environment_variable(string)
78
80
  return false if ENV[string].nil?
81
+ return false if ENV[string] == ''
79
82
  return true if ENV[string] == true || ENV[string] =~ (/(true|t|yes|y|1)$/i)
80
83
  return false if ENV[string] == false ||
81
84
  ENV[string].nil? ||
82
85
  ENV[string] =~ (/(false|f|no|n|0)$/i)
83
- fail ArgumentError, "invalid value for Environment Variable: \"#{string}\""
86
+
87
+ raise ArgumentError, "invalid value for Environment Variable: \"#{string}\""
84
88
  end
85
89
  end
@@ -1,10 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RServiceBus2
2
4
  class NoHandlerFound < StandardError
3
5
  end
6
+
4
7
  class ClassNotFoundForMsg < StandardError
5
8
  end
9
+
6
10
  class NoMsgToProcess < StandardError
7
11
  end
12
+
8
13
  class PropertyNotSet < StandardError
9
14
  end
10
15
 
@@ -14,9 +19,8 @@ module RServiceBus2
14
19
 
15
20
  # Provides a thin logging veneer
16
21
  # @param [String] string Log entry
17
- # @param [Boolean] ver Indicator for a verbose log entry
18
- def log(string, ver = false)
19
- RServiceBus2.log(string, ver)
22
+ def log(string)
23
+ RServiceBus2.log(string)
20
24
  end
21
25
 
22
26
  # Thin veneer for Configuring external resources
@@ -26,19 +30,6 @@ module RServiceBus2
26
30
  self,
27
31
  @state_manager,
28
32
  @saga_storage)
29
- self
30
- end
31
-
32
- # Thin veneer for Configuring SendAt
33
- def configure_send_at_manager
34
- @send_at_manager = SendAtManager.new(self)
35
- self
36
- end
37
-
38
- # Thin veneer for Configuring state
39
- def configure_state_manager
40
- @state_manager = StateManager.new
41
- self
42
33
  end
43
34
 
44
35
  # Thin veneer for Configuring state
@@ -48,25 +39,6 @@ module RServiceBus2
48
39
 
49
40
  uri = URI.parse(string)
50
41
  @saga_storage = SagaStorage.get(uri)
51
- self
52
- end
53
-
54
- # Thin veneer for Configuring Cron
55
- def configure_circuit_breaker
56
- @circuit_breaker = CircuitBreaker.new(self)
57
- self
58
- end
59
-
60
- # Thin veneer for Configuring external resources
61
- def configure_monitors
62
- @monitors = ConfigureMonitor.new(self, @resource_manager).get_monitors(ENV)
63
- self
64
- end
65
-
66
- # Thin veneer for Configuring the Message Queue
67
- def connect_to_mq
68
- @mq = MQ.get
69
- self
70
42
  end
71
43
 
72
44
  # Subscriptions are specified by adding events to the
@@ -74,11 +46,9 @@ module RServiceBus2
74
46
  def send_subscriptions
75
47
  log 'Send Subscriptions'
76
48
 
77
- @endpoint_mapping.get_subscription_endpoints.each do |event_name|
49
+ @endpoint_mapping.subscription_endpoints.each do |event_name|
78
50
  subscribe(event_name)
79
51
  end
80
-
81
- self
82
52
  end
83
53
 
84
54
  # Load and configure Message Handlers
@@ -90,8 +60,6 @@ module RServiceBus2
90
60
  @config.handler_path_list.each do |path|
91
61
  @handler_loader.load_handlers_from_path(path)
92
62
  end
93
-
94
- self
95
63
  end
96
64
 
97
65
  # Load and configure Sagas
@@ -103,14 +71,6 @@ module RServiceBus2
103
71
  @config.saga_path_list.each do |path|
104
72
  @saga_loader.load_sagas_from_path(path)
105
73
  end
106
-
107
- self
108
- end
109
-
110
- # Thin veneer for Configuring Cron
111
- def configure_cron_manager
112
- @cron_manager = CronManager.new(self, @handler_manager.get_list_of_msg_names)
113
- self
114
74
  end
115
75
 
116
76
  # Load Contracts
@@ -121,62 +81,50 @@ module RServiceBus2
121
81
  require path
122
82
  RServiceBus2.rlog "Loaded Contract: #{path}"
123
83
  end
124
-
125
- self
126
84
  end
127
85
 
128
86
  # For each directory given, find and load all librarys
129
87
  def load_libs
130
88
  log 'Load Libs'
131
89
  @config.lib_list.each do |path|
132
- $:.unshift path
90
+ $LOAD_PATH.unshift path
133
91
  end
134
-
135
- self
136
92
  end
137
93
 
138
94
  # Load, configure and initialise Subscriptions
139
95
  def configure_subscriptions
140
96
  subscription_storage = ConfigureSubscriptionStorage.new.get(@config.app_name, @config.subscription_uri)
141
97
  @subscription_manager = SubscriptionManager.new(subscription_storage)
142
- self
143
- end
144
-
145
- # Initialise statistics monitor
146
- def configure_statistics
147
- @stats = StatisticManager.new( self )
148
- self
149
98
  end
150
99
 
151
100
  def initialize
152
101
  RServiceBus2.rlog "Current directory: #{Dir.pwd}"
153
- @config = ConfigFromEnv.new.load_host_section
154
- .load_contracts
155
- .load_handler_path_list
156
- .load_saga_path_list
157
- .load_libs
158
- .load_working_dir_list
102
+ @config = ConfigFromEnv.new
103
+ .load_host_section
104
+ .load_contracts
105
+ .load_handler_path_list
106
+ .load_saga_path_list
107
+ .load_libs
108
+ .load_working_dir_list
159
109
 
160
- connect_to_mq
110
+ @mq = MQ.get
161
111
 
162
112
  @endpoint_mapping = EndpointMapping.new.configure(@mq.local_queue_name)
163
113
 
164
- self.configure_statistics
165
- .load_contracts
166
- .load_libs
167
- .configure_send_at_manager
168
- .configure_state_manager
169
- .configure_saga_storage
170
- .configure_app_resource
171
- .configure_circuit_breaker
172
- .configure_monitors
173
- .load_handlers
174
- .load_sagas
175
- .configure_cron_manager
176
- .configure_subscriptions
177
- .send_subscriptions
178
-
179
- self
114
+ @stats = StatisticManager.new(self)
115
+ load_contracts
116
+ load_libs
117
+ @send_at_manager = SendAtManager.new(self)
118
+ @state_manager = StateManager.new
119
+ configure_saga_storage
120
+ configure_app_resource
121
+ @circuit_breaker = CircuitBreaker.new(self)
122
+ @monitors = ConfigureMonitor.new(self, @resource_manager).get_monitors(ENV)
123
+ load_handlers
124
+ load_sagas
125
+ @cron_manager = CronManager.new(self, @handler_manager.msg_names)
126
+ configure_subscriptions
127
+ send_subscriptions
180
128
  end
181
129
 
182
130
  # Ignition
@@ -185,10 +133,10 @@ module RServiceBus2
185
133
  log "Watching, #{@mq.local_queue_name}"
186
134
  $0 = "rservicebus - #{@mq.local_queue_name}"
187
135
  unless @config.forward_received_messages_to.nil?
188
- log 'Forwarding all received messages to: ' + @config.forward_received_messages_to.to_s
136
+ log "Forwarding all received messages to: #{@config.forward_received_messages_to}"
189
137
  end
190
138
  unless @config.forward_sent_messages_to.nil?
191
- log 'Forwarding all sent messages to: ' + @config.forward_sent_messages_to.to_s
139
+ log "Forwarding all sent messages to: #{@config.forward_sent_messages_to}"
192
140
  end
193
141
 
194
142
  start_listening_to_endpoints
@@ -258,7 +206,6 @@ module RServiceBus2
258
206
  _send_already_wrapped_and_serialised(serialized_object,
259
207
  @config.error_queue_name)
260
208
  @mq.ack
261
-
262
209
  rescue PropertyNotSet => e
263
210
  # This has been re-rasied from a rescue in the handler
264
211
  puts "*** #{e.message}"
@@ -266,7 +213,6 @@ module RServiceBus2
266
213
  property_name = e.message[10, e.message.index(',', 10) - 10]
267
214
  puts "*** Ensure the environment variable, RSB_#{property_name},
268
215
  has been set at startup."
269
-
270
216
  rescue StandardError => e
271
217
  sleep 0.5
272
218
 
@@ -275,7 +221,7 @@ module RServiceBus2
275
221
  puts e.backtrace
276
222
  puts '***'
277
223
 
278
- if retries > 0
224
+ if retries.positive?
279
225
  retries -= 1
280
226
  @mq.return_to_queue
281
227
  else
@@ -293,7 +239,7 @@ module RServiceBus2
293
239
  abort
294
240
  end
295
241
 
296
- error_string = e.message + '. ' + e.backtrace.join('. ')
242
+ error_string = "#{e.message}. #{e.backtrace.join('. ')}"
297
243
  @msg.add_error_msg(@mq.local_queue_name, error_string)
298
244
  serialized_object = YAML.dump(@msg)
299
245
  _send_already_wrapped_and_serialised(serialized_object, @config.error_queue_name)
@@ -318,7 +264,6 @@ module RServiceBus2
318
264
 
319
265
  @send_at_manager.process
320
266
  @circuit_breaker.success
321
-
322
267
  rescue StandardError => e
323
268
  if e.message == 'SIGTERM' || e.message == 'SIGINT'
324
269
  puts 'Exiting on request ...'
@@ -326,7 +271,7 @@ module RServiceBus2
326
271
  else
327
272
  puts '*** This is really unexpected.'
328
273
  message_loop = false
329
- puts 'Message: ' + e.message
274
+ puts "Message: #{e.message}"
330
275
  puts e.backtrace
331
276
  end
332
277
  end
@@ -338,33 +283,29 @@ module RServiceBus2
338
283
  @resource_manager.begin
339
284
  msg_name = @msg.msg.class.name
340
285
  handler_list = @handler_manager.get_handler_list_for_msg(msg_name)
341
- RServiceBus2.rlog 'Handler found for: ' + msg_name
286
+ RServiceBus2.rlog "Handler found for: #{msg_name}"
342
287
  begin
343
288
  @queue_for_msgs_to_be_sent_on_complete = []
344
289
 
345
290
  log "Started processing msg, #{msg_name}"
346
291
  handler_list.each do |handler|
347
- begin
348
- log "Handler, #{handler.class.name}, Started"
349
- handler.handle(@msg.msg)
350
- log "Handler, #{handler.class.name}, Finished"
351
- rescue PropertyNotSet => e
352
- raise PropertyNotSet.new( "Property, #{e.message}, not set for, #{handler.class.name}" )
353
- rescue StandardError => e
354
- puts "E #{e.message}"
355
- log 'An error occurred in Handler: ' + handler.class.name
356
- raise e
357
- end
292
+ log "Handler, #{handler.class.name}, Started"
293
+ handler.handle(@msg.msg)
294
+ log "Handler, #{handler.class.name}, Finished"
295
+ rescue PropertyNotSet => e
296
+ raise PropertyNotSet, "Property, #{e.message}, not set for, #{handler.class.name}"
297
+ rescue StandardError => e
298
+ puts "E #{e.message}"
299
+ log "An error occurred in Handler: #{handler.class.name}"
300
+ raise e
358
301
  end
359
302
 
360
- if @saga_manager.handle(@msg) == false && handler_list.length == 0
361
- fail NoHandlerFound, msg_name
362
- end
303
+ raise NoHandlerFound, msg_name if @saga_manager.handle(@msg) == false && handler_list.length.zero?
304
+
363
305
  @resource_manager.commit(msg_name)
364
306
 
365
307
  send_queued_msgs
366
308
  log "Finished processing msg, #{msg_name}"
367
-
368
309
  rescue StandardError => e
369
310
  @resource_manager.rollback(msg_name)
370
311
  @queue_for_msgs_to_be_sent_on_complete = nil
@@ -381,9 +322,7 @@ module RServiceBus2
381
322
  def _send_already_wrapped_and_serialised(serialized_object, queue_name)
382
323
  RServiceBus2.rlog 'Bus._send_already_wrapped_and_serialised'
383
324
 
384
- unless @config.forward_sent_messages_to.nil?
385
- @mq.send(@config.forward_sent_messages_to, serialized_object)
386
- end
325
+ @mq.send(@config.forward_sent_messages_to, serialized_object) unless @config.forward_sent_messages_to.nil?
387
326
 
388
327
  @mq.send(queue_name, serialized_object)
389
328
  end
@@ -400,8 +339,8 @@ module RServiceBus2
400
339
  RServiceBus2.rlog "Sending, #{msg.class.name} to, #{queue_name}"
401
340
  else
402
341
  parts = queue_name.split('@')
403
- r_msg.set_remote_queue_name(parts[0])
404
- r_msg.set_remote_host_name(parts[1])
342
+ r_msg.remote_queue_name = parts[0]
343
+ r_msg.remote_host_name = parts[1]
405
344
  q = 'transport-out'
406
345
  RServiceBus2.rlog "Sending, #{msg.class.name} to, #{queue_name}, via #{q}"
407
346
  end
@@ -422,19 +361,20 @@ module RServiceBus2
422
361
 
423
362
  def queue_msg_for_send_on_complete(msg, queue_name, timestamp = nil)
424
363
  correlation_id = @saga_data.nil? ? nil : @saga_data.correlation_id
425
- correlation_id = (!@msg.nil? && !@msg.correlation_id.nil?) ? @msg.correlation_id : correlation_id
426
- @queue_for_msgs_to_be_sent_on_complete << Hash['msg', msg, 'queue_name', queue_name, 'correlation_id', correlation_id, 'timestamp',timestamp ]
364
+ correlation_id = !@msg.nil? && !@msg.correlation_id.nil? ? @msg.correlation_id : correlation_id
365
+ @queue_for_msgs_to_be_sent_on_complete <<
366
+ Hash['msg', msg, 'queue_name', queue_name, 'correlation_id', correlation_id, 'timestamp', timestamp]
427
367
  end
428
368
 
429
369
  # Sends a msg back across the bus
430
370
  # Reply queues are specified in each msg. It works like
431
371
  # email, where the reply address can actually be anywhere
432
372
  # @param [RServiceBus2::Message] msg msg to be sent
433
- def reply(msg)
434
- RServiceBus2.rlog 'Reply with: ' + msg.class.name + ' To: ' + @msg.return_address
373
+ def reply(msg, timestamp = nil)
374
+ RServiceBus2.rlog "Reply with: #{msg.class.name} To: #{@msg.return_address}"
435
375
  @stats.inc_total_reply
436
376
 
437
- queue_msg_for_send_on_complete(msg, @msg.return_address)
377
+ queue_msg_for_send_on_complete(msg, @msg.return_address, timestamp)
438
378
  end
439
379
 
440
380
  def get_endpoint_for_msg(msg_name)
@@ -443,21 +383,20 @@ module RServiceBus2
443
383
 
444
384
  return @mq.local_queue_name if @handler_manager.can_msg_be_handled_locally(msg_name)
445
385
 
446
- log 'No end point mapping found for: ' + msg_name
447
- log '**** Check environment variable MessageEndpointMappings contains an entry named : ' + msg_name
448
- raise 'No end point mapping found for: ' + msg_name
386
+ log "No end point mapping found for: #{msg_name}"
387
+ log "**** Check environment variable MessageEndpointMappings contains an entry named: #{msg_name}"
388
+ raise "No end point mapping found for: #{msg_name}"
449
389
  end
450
390
 
451
-
452
391
  # Send a msg across the bus
453
392
  # msg destination is specified at the infrastructure level
454
393
  # @param [RServiceBus2::Message] msg msg to be sent
455
- def send( msg, timestamp=nil )
394
+ def send(msg, timestamp = nil)
456
395
  RServiceBus2.rlog 'Bus.Send'
457
396
  @stats.inc_total_sent
458
397
 
459
398
  msg_name = msg.class.name
460
- queue_name = self.get_endpoint_for_msg(msg_name)
399
+ queue_name = get_endpoint_for_msg(msg_name)
461
400
  queue_msg_for_send_on_complete(msg, queue_name, timestamp)
462
401
  end
463
402
 
@@ -476,7 +415,7 @@ module RServiceBus2
476
415
  # Sends a subscription request across the Bus
477
416
  # @param [String] eventName event to be subscribes to
478
417
  def subscribe(event_name)
479
- RServiceBus2.rlog 'Bus.Subscribe: ' + event_name
418
+ RServiceBus2.rlog "Bus.Subscribe: #{event_name}"
480
419
 
481
420
  queue_name = get_endpoint_for_msg(event_name)
482
421
  subscription = MessageSubscription.new(event_name)