rservicebus2 0.0.1

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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +64 -0
  3. data/bin/return_messages_to_source_queue +114 -0
  4. data/bin/rsb_ctl +38 -0
  5. data/bin/rservicebus2 +14 -0
  6. data/bin/rservicebus2-create +107 -0
  7. data/bin/rservicebus2-init +104 -0
  8. data/bin/rservicebus2-transport +16 -0
  9. data/bin/send_empty_message +15 -0
  10. data/lib/rservicebus.rb +59 -0
  11. data/lib/rservicebus/agent.rb +54 -0
  12. data/lib/rservicebus/appresource.rb +65 -0
  13. data/lib/rservicebus/appresource/dir.rb +29 -0
  14. data/lib/rservicebus/appresource/file.rb +8 -0
  15. data/lib/rservicebus/appresource/fluiddb.rb +24 -0
  16. data/lib/rservicebus/appresource_configure.rb +33 -0
  17. data/lib/rservicebus/audit.rb +28 -0
  18. data/lib/rservicebus/circuitbreaker.rb +79 -0
  19. data/lib/rservicebus/config.rb +168 -0
  20. data/lib/rservicebus/cron_manager.rb +76 -0
  21. data/lib/rservicebus/endpointmapping.rb +72 -0
  22. data/lib/rservicebus/errormessage.rb +14 -0
  23. data/lib/rservicebus/handler_loader.rb +162 -0
  24. data/lib/rservicebus/handler_manager.rb +131 -0
  25. data/lib/rservicebus/helper_functions.rb +85 -0
  26. data/lib/rservicebus/host.rb +487 -0
  27. data/lib/rservicebus/message.rb +78 -0
  28. data/lib/rservicebus/message/statisticoutput.rb +7 -0
  29. data/lib/rservicebus/message/subscription.rb +10 -0
  30. data/lib/rservicebus/message/verboseoutput.rb +7 -0
  31. data/lib/rservicebus/monitor.rb +61 -0
  32. data/lib/rservicebus/monitor/csvdir.rb +52 -0
  33. data/lib/rservicebus/monitor/dir.rb +139 -0
  34. data/lib/rservicebus/monitor/dirnotifier.rb +101 -0
  35. data/lib/rservicebus/monitor/message.rb +11 -0
  36. data/lib/rservicebus/monitor/xmldir.rb +11 -0
  37. data/lib/rservicebus/monitor_configure.rb +71 -0
  38. data/lib/rservicebus/mq.rb +98 -0
  39. data/lib/rservicebus/mq/beanstalk.rb +72 -0
  40. data/lib/rservicebus/resource_manager.rb +69 -0
  41. data/lib/rservicebus/saga/base.rb +17 -0
  42. data/lib/rservicebus/saga/data.rb +20 -0
  43. data/lib/rservicebus/saga/manager.rb +128 -0
  44. data/lib/rservicebus/saga_loader.rb +118 -0
  45. data/lib/rservicebus/saga_storage.rb +18 -0
  46. data/lib/rservicebus/saga_storage/dir.rb +87 -0
  47. data/lib/rservicebus/saga_storage/inmemory.rb +37 -0
  48. data/lib/rservicebus/sendat_manager.rb +33 -0
  49. data/lib/rservicebus/sendat_storage.rb +20 -0
  50. data/lib/rservicebus/sendat_storage/file.rb +37 -0
  51. data/lib/rservicebus/sendat_storage/inmemory.rb +20 -0
  52. data/lib/rservicebus/state_manager.rb +30 -0
  53. data/lib/rservicebus/state_storage.rb +18 -0
  54. data/lib/rservicebus/state_storage/dir.rb +66 -0
  55. data/lib/rservicebus/state_storage/inmemory.rb +25 -0
  56. data/lib/rservicebus/statistic_manager.rb +86 -0
  57. data/lib/rservicebus/stats.rb +68 -0
  58. data/lib/rservicebus/subscription_manager.rb +31 -0
  59. data/lib/rservicebus/subscription_storage.rb +39 -0
  60. data/lib/rservicebus/subscription_storage/file.rb +42 -0
  61. data/lib/rservicebus/subscription_storage/redis.rb +69 -0
  62. data/lib/rservicebus/subscription_storage_configure.rb +19 -0
  63. data/lib/rservicebus/test.rb +2 -0
  64. data/lib/rservicebus/test/bus.rb +32 -0
  65. data/lib/rservicebus/transporter.rb +142 -0
  66. data/lib/rservicebus/usermessage/withpayload.rb +10 -0
  67. metadata +184 -0
@@ -0,0 +1,85 @@
1
+ module RServiceBus
2
+ def self.convert_dto_to_hash(obj)
3
+ hash = {}
4
+ obj.instance_variables.each do |var|
5
+ hash[var.to_s.delete('@')] = obj.instance_variable_get(var)
6
+ end
7
+ hash
8
+ end
9
+
10
+ def self.convert_dto_to_json(obj)
11
+ convert_dto_to_hash(obj).to_json
12
+ end
13
+
14
+ def self.log(string, ver = false)
15
+ return if check_environment_variable('TESTING')
16
+
17
+ type = ver ? 'VERB' : 'INFO'
18
+ if check_environment_variable('VERBOSE') || !ver
19
+ timestamp = Time.new.strftime('%Y-%m-%d %H:%M:%S')
20
+ puts "[#{type}] #{timestamp} :: #{string}"
21
+ end
22
+ end
23
+
24
+ def self.rlog(string)
25
+ return unless check_environment_variable('RSBVERBOSE')
26
+
27
+ timestamp = Time.new.strftime('%Y-%m-%d %H:%M:%S')
28
+ puts "[RSB] #{timestamp} :: #{string}"
29
+ end
30
+
31
+ def self.create_anonymous_class(name_for_class)
32
+ new_anonymous_class = Class.new(Object)
33
+ Object.const_set(name_for_class, new_anonymous_class)
34
+ Object.const_get(name_for_class).new
35
+ end
36
+
37
+ def self.get_value(name, default = nil)
38
+ value = (ENV[name].nil? || ENV[name] == '') ? default : ENV[name]
39
+ log "Env value: #{name}: #{value}"
40
+ value
41
+ end
42
+
43
+ def self.send_msg(msg, response_queue = 'agent')
44
+ require 'rservicebus/endpointmapping'
45
+ endpoint_mapping = EndpointMapping.new
46
+ endpoint_mapping.configure
47
+ queue_name = endpoint_mapping.get(msg.class.name)
48
+
49
+ ENV['RSBMQ'] = 'beanstalk://localhost' if ENV['RSBMQ'].nil?
50
+ agent = RServiceBus::Agent.new
51
+ Audit.new(agent).audit_to_queue(msg)
52
+ agent.send_msg(msg, queue_name, response_queue)
53
+
54
+ rescue QueueNotFoundForMsg => e
55
+ msg = "\n"
56
+ msg = "#{msg}*** Queue not found for, #{e.message}\n"
57
+ msg = "#{msg}*** Ensure you have an environment variable set for this
58
+ Message Type, eg, \n"
59
+ msg = "#{msg}*** MESSAGE_ENDPOINT_MAPPINGS=#{e.message}:<QueueName>\n"
60
+ raise StandardError, msg
61
+ end
62
+
63
+ def self.check_for_reply(queue_name)
64
+ ENV['RSBMQ'] = 'beanstalk://localhost' if ENV['RSBMQ'].nil?
65
+ agent = RServiceBus::Agent.new
66
+ msg = agent.check_for_reply(queue_name)
67
+ Audit.new(agent).audit_incoming(msg)
68
+
69
+ msg
70
+ end
71
+
72
+ def self.tick(string)
73
+ puts "[TICK] #{Time.new.strftime('%Y-%m-%d %H:%M:%S.%6N')} ::
74
+ #{caller[0]}. #{string}"
75
+ end
76
+
77
+ def self.check_environment_variable(string)
78
+ return false if ENV[string].nil?
79
+ return true if ENV[string] == true || ENV[string] =~ (/(true|t|yes|y|1)$/i)
80
+ return false if ENV[string] == false ||
81
+ ENV[string].nil? ||
82
+ ENV[string] =~ (/(false|f|no|n|0)$/i)
83
+ fail ArgumentError, "invalid value for Environment Variable: \"#{string}\""
84
+ end
85
+ end
@@ -0,0 +1,487 @@
1
+ module RServiceBus
2
+ class NoHandlerFound < StandardError
3
+ end
4
+ class ClassNotFoundForMsg < StandardError
5
+ end
6
+ class NoMsgToProcess < StandardError
7
+ end
8
+ class PropertyNotSet < StandardError
9
+ end
10
+
11
+ # Host process for rservicebus
12
+ class Host
13
+ attr_accessor :sagaData
14
+
15
+ # Provides a thin logging veneer
16
+ # @param [String] string Log entry
17
+ # @param [Boolean] ver Indicator for a verbose log entry
18
+ def log(string, ver = false)
19
+ RServiceBus.log(string, ver)
20
+ end
21
+
22
+ # Thin veneer for Configuring external resources
23
+ def configure_app_resource
24
+ @resource_manager = ConfigureAppResource.new
25
+ .get_resources(ENV,
26
+ self,
27
+ @state_manager,
28
+ @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
+ end
43
+
44
+ # Thin veneer for Configuring state
45
+ def configure_saga_storage
46
+ string = RServiceBus.get_value('SAGA_URI')
47
+ string = 'dir:///tmp' if string.nil?
48
+
49
+ uri = URI.parse(string)
50
+ @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
+ end
71
+
72
+ # Subscriptions are specified by adding events to the
73
+ # msg endpoint mapping
74
+ def send_subscriptions
75
+ log 'Send Subscriptions'
76
+
77
+ @endpoint_mapping.get_subscription_endpoints.each do |event_name|
78
+ subscribe(event_name)
79
+ end
80
+
81
+ self
82
+ end
83
+
84
+ # Load and configure Message Handlers
85
+ def load_handlers
86
+ log 'Load Message Handlers'
87
+ @handler_manager = HandlerManager.new(self, @resource_manager, @state_manager)
88
+ @handler_loader = HandlerLoader.new(self, @handler_manager)
89
+
90
+ @config.handler_path_list.each do |path|
91
+ @handler_loader.load_handlers_from_path(path)
92
+ end
93
+
94
+ self
95
+ end
96
+
97
+ # Load and configure Sagas
98
+ def load_sagas
99
+ log 'Load Sagas'
100
+ @saga_manager = SagaManager.new(self, @resource_manager, @saga_storage)
101
+ @saga_loader = SagaLoader.new(self, @saga_manager)
102
+
103
+ @config.saga_path_list.each do |path|
104
+ @saga_loader.load_sagas_from_path(path)
105
+ 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
+ end
115
+
116
+ # Load Contracts
117
+ def load_contracts
118
+ log 'Load Contracts'
119
+
120
+ @config.contract_list.each do |path|
121
+ require path
122
+ RServiceBus.rlog "Loaded Contract: #{path}"
123
+ end
124
+
125
+ self
126
+ end
127
+
128
+ # For each directory given, find and load all librarys
129
+ def load_libs
130
+ log 'Load Libs'
131
+ @config.lib_list.each do |path|
132
+ $:.unshift path
133
+ end
134
+
135
+ self
136
+ end
137
+
138
+ # Load, configure and initialise Subscriptions
139
+ def configure_subscriptions
140
+ subscription_storage = ConfigureSubscriptionStorage.new.get(@config.app_name, @config.subscription_uri)
141
+ @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
+ end
150
+
151
+ def initialize
152
+ RServiceBus.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
159
+
160
+ connect_to_mq
161
+
162
+ @endpoint_mapping = EndpointMapping.new.configure(@mq.local_queue_name)
163
+
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
180
+ end
181
+
182
+ # Ignition
183
+ def run
184
+ log 'Starting the Host'
185
+ log "Watching, #{@mq.local_queue_name}"
186
+ $0 = "rservicebus - #{@mq.local_queue_name}"
187
+ unless @config.forward_received_messages_to.nil?
188
+ log 'Forwarding all received messages to: ' + @config.forward_received_messages_to.to_s
189
+ end
190
+ unless @config.forward_sent_messages_to.nil?
191
+ log 'Forwarding all sent messages to: ' + @config.forward_sent_messages_to.to_s
192
+ end
193
+
194
+ start_listening_to_endpoints
195
+ end
196
+
197
+ # Receive a msg, prep it, and handle any errors that may occur
198
+ # - Most of this should be queue independant
199
+ def start_listening_to_endpoints
200
+ log 'Waiting for messages. To exit press CTRL+C'
201
+ message_loop = true
202
+ retries = @config.max_retries
203
+
204
+ while message_loop
205
+ # Popping a msg off the queue should not be in the message handler,
206
+ # as it affects retry
207
+ begin
208
+ @stats.tick
209
+ if @circuit_breaker.broken
210
+ sleep 0.5
211
+ next
212
+ end
213
+
214
+ body = @mq.pop
215
+ begin
216
+ @stats.inc_total_processed
217
+ @msg = YAML.load(body)
218
+ case @msg.msg.class.name
219
+ when 'RServiceBus::MessageSubscription'
220
+ @subscription_manager.add(@msg.msg.event_name,
221
+ @msg.return_address)
222
+ when 'RServiceBus::MessageStatisticOutputOn'
223
+ @stats.output = true
224
+ log 'Turn on Stats logging'
225
+ when 'RServiceBus::MessageStatisticOutputOff'
226
+ @stats.output = false
227
+ log 'Turn off Stats logging'
228
+ when 'RServiceBus::MessageVerboseOutputOn'
229
+ ENV['VERBOSE'] = 'true'
230
+ log 'Turn on Verbose logging'
231
+ when 'RServiceBus::MessageVerboseOutputOff'
232
+ ENV.delete('VERBOSE')
233
+ log 'Turn off Verbose logging'
234
+ else
235
+ handle_message
236
+ unless @config.forward_received_messages_to.nil?
237
+ _send_already_wrapped_and_serialised(body, @config.forward_received_messages_to)
238
+ end
239
+ end
240
+ @mq.ack
241
+ rescue ClassNotFoundForMsg => e
242
+ puts "*** Class not found for msg, #{e.message}"
243
+ puts "*** Ensure, #{e.message}, is defined in Contract.rb, most
244
+ likely as 'Class #{e.message} end"
245
+
246
+ @msg.add_error_msg(@mq.local_queue_name, e.message)
247
+ serialized_object = YAML.dump(@msg)
248
+ _send_already_wrapped_and_serialised(serialized_object,
249
+ @config.error_queue_name)
250
+ @mq.ack
251
+ rescue NoHandlerFound => e
252
+ puts "*** Handler not found for msg, #{e.message}"
253
+ puts "*** Ensure a handler named, #{e.message}, is present in the
254
+ MessageHandler directory."
255
+
256
+ @msg.add_error_msg(@mq.local_queue_name, e.message)
257
+ serialized_object = YAML.dump(@msg)
258
+ _send_already_wrapped_and_serialised(serialized_object,
259
+ @config.error_queue_name)
260
+ @mq.ack
261
+
262
+ rescue PropertyNotSet => e
263
+ # This has been re-rasied from a rescue in the handler
264
+ puts "*** #{e.message}"
265
+ # "Property, #{e.message}, not set for, #{handler.class.name}"
266
+ property_name = e.message[10, e.message.index(',', 10) - 10]
267
+ puts "*** Ensure the environment variable, RSB_#{property_name},
268
+ has been set at startup."
269
+
270
+ rescue StandardError => e
271
+ sleep 0.5
272
+
273
+ puts '*** Exception occurred'
274
+ puts e.message
275
+ puts e.backtrace
276
+ puts '***'
277
+
278
+ if retries > 0
279
+ retries -= 1
280
+ @mq.return_to_queue
281
+ else
282
+ @circuit_breaker.failure
283
+ @stats.inc_total_errored
284
+ if e.class.name == 'Beanstalk::NotConnected'
285
+ puts 'Lost connection to beanstalkd.'
286
+ puts '*** Start or Restart beanstalkd and try again.'
287
+ abort
288
+ end
289
+
290
+ if e.class.name == 'Redis::CannotConnectError'
291
+ puts 'Lost connection to redis.'
292
+ puts '*** Start or Restart redis and try again.'
293
+ abort
294
+ end
295
+
296
+ error_string = e.message + '. ' + e.backtrace.join('. ')
297
+ @msg.add_error_msg(@mq.local_queue_name, error_string)
298
+ serialized_object = YAML.dump(@msg)
299
+ _send_already_wrapped_and_serialised(serialized_object, @config.error_queue_name)
300
+ @mq.ack
301
+ retries = @config.max_retries
302
+ end
303
+ end
304
+ rescue SystemExit, Interrupt
305
+ puts 'Exiting on request ...'
306
+ message_loop = false
307
+ rescue NoMsgToProcess => e
308
+ # This exception is just saying there are no messages to process
309
+ @queue_for_msgs_to_be_sent_on_complete = []
310
+ @monitors.each(&:look)
311
+ send_queued_msgs
312
+ @queue_for_msgs_to_be_sent_on_complete = nil
313
+
314
+ @queue_for_msgs_to_be_sent_on_complete = []
315
+ @cron_manager.run
316
+ send_queued_msgs
317
+ @queue_for_msgs_to_be_sent_on_complete = nil
318
+
319
+ @send_at_manager.process
320
+ @circuit_breaker.success
321
+
322
+ rescue StandardError => e
323
+ if e.message == 'SIGTERM' || e.message == 'SIGINT'
324
+ puts 'Exiting on request ...'
325
+ message_loop = false
326
+ else
327
+ puts '*** This is really unexpected.'
328
+ message_loop = false
329
+ puts 'Message: ' + e.message
330
+ puts e.backtrace
331
+ end
332
+ end
333
+ end
334
+ end
335
+
336
+ # Send the current msg to the appropriate handlers
337
+ def handle_message
338
+ @resource_manager.begin
339
+ msg_name = @msg.msg.class.name
340
+ handler_list = @handler_manager.get_handler_list_for_msg(msg_name)
341
+ RServiceBus.rlog 'Handler found for: ' + msg_name
342
+ begin
343
+ @queue_for_msgs_to_be_sent_on_complete = []
344
+
345
+ log "Started processing msg, #{msg_name}"
346
+ 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
358
+ end
359
+
360
+ if @saga_manager.handle(@msg) == false && handler_list.length == 0
361
+ fail NoHandlerFound, msg_name
362
+ end
363
+ @resource_manager.commit(msg_name)
364
+
365
+ send_queued_msgs
366
+ log "Finished processing msg, #{msg_name}"
367
+
368
+ rescue StandardError => e
369
+ @resource_manager.rollback(msg_name)
370
+ @queue_for_msgs_to_be_sent_on_complete = nil
371
+ raise e
372
+ end
373
+ end
374
+
375
+ #######################################################################################################
376
+ # All msg sending Methods
377
+
378
+ # Sends a msg across the bus
379
+ # @param [String] serialized_object serialized RServiceBus::Message
380
+ # @param [String] queue_name endpoint to which the msg will be sent
381
+ def _send_already_wrapped_and_serialised(serialized_object, queue_name)
382
+ RServiceBus.rlog 'Bus._send_already_wrapped_and_serialised'
383
+
384
+ unless @config.forward_sent_messages_to.nil?
385
+ @mq.send(@config.forward_sent_messages_to, serialized_object)
386
+ end
387
+
388
+ @mq.send(queue_name, serialized_object)
389
+ end
390
+
391
+ # Sends a msg across the bus
392
+ # @param [RServiceBus::Message] msg msg to be sent
393
+ # @param [String] queueName endpoint to which the msg will be sent
394
+ def _send_needs_wrapping(msg, queue_name, correlation_id)
395
+ RServiceBus.rlog 'Bus._send_needs_wrapping'
396
+
397
+ r_msg = RServiceBus::Message.new(msg, @mq.local_queue_name, correlation_id)
398
+ if queue_name.index('@').nil?
399
+ q = queue_name
400
+ RServiceBus.rlog "Sending, #{msg.class.name} to, #{queue_name}"
401
+ else
402
+ parts = queue_name.split('@')
403
+ r_msg.set_remote_queue_name(parts[0])
404
+ r_msg.set_remote_host_name(parts[1])
405
+ q = 'transport-out'
406
+ RServiceBus.rlog "Sending, #{msg.class.name} to, #{queue_name}, via #{q}"
407
+ end
408
+
409
+ serialized_object = YAML.dump(r_msg)
410
+ _send_already_wrapped_and_serialised(serialized_object, q)
411
+ end
412
+
413
+ def send_queued_msgs
414
+ @queue_for_msgs_to_be_sent_on_complete.each do |row|
415
+ if row['timestamp'].nil?
416
+ _send_needs_wrapping(row['msg'], row['queue_name'], row['correlation_id'])
417
+ else
418
+ @send_at_manager.add(row)
419
+ end
420
+ end
421
+ end
422
+
423
+ def queue_msg_for_send_on_complete(msg, queue_name, timestamp = nil)
424
+ 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 ]
427
+ end
428
+
429
+ # Sends a msg back across the bus
430
+ # Reply queues are specified in each msg. It works like
431
+ # email, where the reply address can actually be anywhere
432
+ # @param [RServiceBus::Message] msg msg to be sent
433
+ def reply(msg)
434
+ RServiceBus.rlog 'Reply with: ' + msg.class.name + ' To: ' + @msg.return_address
435
+ @stats.inc_total_reply
436
+
437
+ queue_msg_for_send_on_complete(msg, @msg.return_address)
438
+ end
439
+
440
+ def get_endpoint_for_msg(msg_name)
441
+ queue_name = @endpoint_mapping.get(msg_name)
442
+ return queue_name unless queue_name.nil?
443
+
444
+ return @mq.local_queue_name if @handler_manager.can_msg_be_handled_locally(msg_name)
445
+
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
449
+ end
450
+
451
+
452
+ # Send a msg across the bus
453
+ # msg destination is specified at the infrastructure level
454
+ # @param [RServiceBus::Message] msg msg to be sent
455
+ def send( msg, timestamp=nil )
456
+ RServiceBus.rlog 'Bus.Send'
457
+ @stats.inc_total_sent
458
+
459
+ msg_name = msg.class.name
460
+ queue_name = self.get_endpoint_for_msg(msg_name)
461
+ queue_msg_for_send_on_complete(msg, queue_name, timestamp)
462
+ end
463
+
464
+ # Sends an event to all subscribers across the bus
465
+ # @param [RServiceBus::Message] msg msg to be sent
466
+ def publish(msg)
467
+ RServiceBus.rlog 'Bus.Publish'
468
+ @stats.inc_total_published
469
+
470
+ subscriptions = @subscription_manager.get(msg.class.name)
471
+ subscriptions.each do |subscriber|
472
+ queue_msg_for_send_on_complete(msg, subscriber)
473
+ end
474
+ end
475
+
476
+ # Sends a subscription request across the Bus
477
+ # @param [String] eventName event to be subscribes to
478
+ def subscribe(event_name)
479
+ RServiceBus.rlog 'Bus.Subscribe: ' + event_name
480
+
481
+ queue_name = get_endpoint_for_msg(event_name)
482
+ subscription = MessageSubscription.new(event_name)
483
+
484
+ _send_needs_wrapping(subscription, queue_name, nil)
485
+ end
486
+ end
487
+ end