rservicebus 0.0.01 → 0.0.2
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.
- data/LICENSE +1 -1
- data/README.md +48 -0
- data/bin/{rservicebus2 → rservicebus} +2 -1
- data/lib/rservicebus.rb +15 -54
- data/lib/rservicebus/Agent.rb +21 -0
- data/lib/rservicebus/Config.rb +125 -0
- data/lib/rservicebus/ErrorMessage.rb +14 -0
- data/lib/rservicebus/HandlerLoader.rb +100 -0
- data/lib/rservicebus/Host.rb +340 -0
- data/lib/rservicebus/Message.rb +29 -0
- data/lib/rservicebus/Subscription.rb +13 -0
- data/lib/rservicebus/helper_functions.rb +8 -81
- metadata +23 -150
- checksums.yaml +0 -7
- data/bin/return_messages_to_source_queue +0 -114
- data/bin/rsb_ctl +0 -38
- data/bin/rservicebus2-create +0 -107
- data/bin/rservicebus2-init +0 -104
- data/bin/rservicebus2-transport +0 -16
- data/bin/send_empty_message +0 -15
- data/lib/rservicebus/agent.rb +0 -54
- data/lib/rservicebus/appresource.rb +0 -65
- data/lib/rservicebus/appresource/dir.rb +0 -29
- data/lib/rservicebus/appresource/file.rb +0 -8
- data/lib/rservicebus/appresource/fluiddb.rb +0 -24
- data/lib/rservicebus/appresource_configure.rb +0 -33
- data/lib/rservicebus/audit.rb +0 -28
- data/lib/rservicebus/circuitbreaker.rb +0 -79
- data/lib/rservicebus/config.rb +0 -168
- data/lib/rservicebus/cron_manager.rb +0 -76
- data/lib/rservicebus/endpointmapping.rb +0 -72
- data/lib/rservicebus/errormessage.rb +0 -14
- data/lib/rservicebus/handler_loader.rb +0 -162
- data/lib/rservicebus/handler_manager.rb +0 -131
- data/lib/rservicebus/host.rb +0 -487
- data/lib/rservicebus/message.rb +0 -78
- data/lib/rservicebus/message/statisticoutput.rb +0 -7
- data/lib/rservicebus/message/subscription.rb +0 -10
- data/lib/rservicebus/message/verboseoutput.rb +0 -7
- data/lib/rservicebus/monitor.rb +0 -61
- data/lib/rservicebus/monitor/csvdir.rb +0 -52
- data/lib/rservicebus/monitor/dir.rb +0 -139
- data/lib/rservicebus/monitor/dirnotifier.rb +0 -101
- data/lib/rservicebus/monitor/message.rb +0 -11
- data/lib/rservicebus/monitor/xmldir.rb +0 -11
- data/lib/rservicebus/monitor_configure.rb +0 -71
- data/lib/rservicebus/mq.rb +0 -98
- data/lib/rservicebus/mq/beanstalk.rb +0 -72
- data/lib/rservicebus/resource_manager.rb +0 -69
- data/lib/rservicebus/saga/base.rb +0 -17
- data/lib/rservicebus/saga/data.rb +0 -20
- data/lib/rservicebus/saga/manager.rb +0 -128
- data/lib/rservicebus/saga_loader.rb +0 -118
- data/lib/rservicebus/saga_storage.rb +0 -18
- data/lib/rservicebus/saga_storage/dir.rb +0 -87
- data/lib/rservicebus/saga_storage/inmemory.rb +0 -37
- data/lib/rservicebus/sendat_manager.rb +0 -33
- data/lib/rservicebus/sendat_storage.rb +0 -20
- data/lib/rservicebus/sendat_storage/file.rb +0 -37
- data/lib/rservicebus/sendat_storage/inmemory.rb +0 -20
- data/lib/rservicebus/state_manager.rb +0 -30
- data/lib/rservicebus/state_storage.rb +0 -18
- data/lib/rservicebus/state_storage/dir.rb +0 -66
- data/lib/rservicebus/state_storage/inmemory.rb +0 -25
- data/lib/rservicebus/statistic_manager.rb +0 -86
- data/lib/rservicebus/stats.rb +0 -68
- data/lib/rservicebus/subscription_manager.rb +0 -31
- data/lib/rservicebus/subscription_storage.rb +0 -39
- data/lib/rservicebus/subscription_storage/file.rb +0 -42
- data/lib/rservicebus/subscription_storage/redis.rb +0 -69
- data/lib/rservicebus/subscription_storage_configure.rb +0 -19
- data/lib/rservicebus/test.rb +0 -2
- data/lib/rservicebus/test/bus.rb +0 -32
- data/lib/rservicebus/transporter.rb +0 -142
- data/lib/rservicebus/usermessage/withpayload.rb +0 -10
@@ -1,14 +0,0 @@
|
|
1
|
-
module RServiceBus
|
2
|
-
|
3
|
-
# Error Message
|
4
|
-
class ErrorMessage
|
5
|
-
attr_reader :occurredat, :source_queue, :error_msg
|
6
|
-
|
7
|
-
def initialize(source_queue, error_msg)
|
8
|
-
@occurredat = DateTime.now
|
9
|
-
|
10
|
-
@source_queue = source_queue
|
11
|
-
@error_msg = error_msg
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,162 +0,0 @@
|
|
1
|
-
module RServiceBus
|
2
|
-
# Given a directory, this class is responsible for finding
|
3
|
-
# msgnames,
|
4
|
-
# handlernames, and
|
5
|
-
# loading handlers
|
6
|
-
class HandlerLoader
|
7
|
-
attr_reader :handlerList
|
8
|
-
|
9
|
-
# Constructor
|
10
|
-
#
|
11
|
-
# @param [RServiceBus::Host] host instance
|
12
|
-
# @param [Hash] appResources As hash[k,v] where k is the name of a
|
13
|
-
# resource, and v is the resource
|
14
|
-
def initialize(host, handler_manager)
|
15
|
-
@host = host
|
16
|
-
|
17
|
-
@handler_manager = handler_manager
|
18
|
-
|
19
|
-
@list_of_loaded_paths = {}
|
20
|
-
end
|
21
|
-
|
22
|
-
# Cleans the given path to ensure it can be used for as a parameter for the require statement.
|
23
|
-
# @param [String] file_path the path to be cleaned
|
24
|
-
def get_require_path(file_path)
|
25
|
-
file_path = './' + file_path unless file_path.start_with?('/')
|
26
|
-
|
27
|
-
return file_path.sub('.rb', '') if File.exist?(file_path)
|
28
|
-
|
29
|
-
abort('Filepath, ' + file_path + ", given for MessageHandler require
|
30
|
-
doesn't exist")
|
31
|
-
end
|
32
|
-
|
33
|
-
# Instantiate the handler named in handlerName from the file name in
|
34
|
-
# file_path. Exceptions will be raised if encountered when loading handlers.
|
35
|
-
# This is a load time activity, so handlers should load correctly. As much
|
36
|
-
# information as possible is returned to enable the handler to be fixed,
|
37
|
-
# or configuration corrected.
|
38
|
-
# @param [String] handler_name name of the handler to instantiate
|
39
|
-
# @param [String] file_path the path to the file to be loaded
|
40
|
-
# @return [RServiceBus::Handler] the loader
|
41
|
-
def load_handler_from_file(handler_name, file_path)
|
42
|
-
require_path = get_require_path(file_path)
|
43
|
-
|
44
|
-
require require_path
|
45
|
-
begin
|
46
|
-
handler = Object.const_get(handler_name).new
|
47
|
-
rescue StandardError => e
|
48
|
-
puts 'Expected class name: ' + handler_name + ', not found after
|
49
|
-
require: ' + require_path
|
50
|
-
puts '**** Check in ' + file_path + ' that the class is named : ' +
|
51
|
-
handler_name
|
52
|
-
puts '( In case its not that )'
|
53
|
-
raise e
|
54
|
-
end
|
55
|
-
|
56
|
-
handler
|
57
|
-
end
|
58
|
-
|
59
|
-
# Wrapper function
|
60
|
-
#
|
61
|
-
# @param [String] file_path
|
62
|
-
# @param [String] handler_name
|
63
|
-
# @returns [RServiceBus::Handler] handler
|
64
|
-
def load_handler(msg_name, file_path, handler_name)
|
65
|
-
if @list_of_loaded_paths.key?(file_path)
|
66
|
-
RServiceBus.log "Not reloading, #{file_path}"
|
67
|
-
return
|
68
|
-
end
|
69
|
-
|
70
|
-
begin
|
71
|
-
RServiceBus.rlog 'file_path: ' + file_path
|
72
|
-
RServiceBus.rlog 'handler_name: ' + handler_name
|
73
|
-
|
74
|
-
handler = load_handler_from_file(handler_name, file_path)
|
75
|
-
RServiceBus.log 'Loaded Handler: ' + handler_name
|
76
|
-
|
77
|
-
@handler_manager.add_handler(msg_name, handler)
|
78
|
-
|
79
|
-
@list_of_loaded_paths[file_path] = 1
|
80
|
-
rescue StandardError => e
|
81
|
-
puts 'Exception loading handler from file: ' + file_path
|
82
|
-
puts e.message
|
83
|
-
puts e.backtrace[0]
|
84
|
-
abort
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# This method is overloaded for unit tests
|
89
|
-
#
|
90
|
-
# @param [String] path directory to check
|
91
|
-
# @return [Array] a list of paths to files found in the given path
|
92
|
-
def get_list_of_files_for_dir(path)
|
93
|
-
list = Dir[path + '/*']
|
94
|
-
RServiceBus.rlog "HandlerLoader.getListOfFilesForDir. path: #{path},
|
95
|
-
list: #{list}"
|
96
|
-
list
|
97
|
-
end
|
98
|
-
|
99
|
-
# Multiple handlers for the same msg can be placed inside a top level
|
100
|
-
# directory. The msg name is than taken from the directory, and the
|
101
|
-
# handlers from the files inside that directory
|
102
|
-
#
|
103
|
-
# @param [String] msg_name name of message
|
104
|
-
# @param [String] base_dir directory to check for handlers of [msg_name]
|
105
|
-
def load_handlers_from_second_level_path(msg_name, base_dir)
|
106
|
-
get_list_of_files_for_dir(base_dir).each do |file_path|
|
107
|
-
next if file_path.end_with?('.')
|
108
|
-
|
109
|
-
ext_name = File.extname(file_path)
|
110
|
-
if !File.directory?(file_path) && ext_name == '.rb'
|
111
|
-
file_name = File.basename(file_path).sub('.rb', '')
|
112
|
-
handler_name = "MessageHandler_#{msg_name}_#{file_name}"
|
113
|
-
|
114
|
-
load_handler(msg_name, file_path, handler_name)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
self
|
119
|
-
end
|
120
|
-
|
121
|
-
# Extract the top level dir or file name as it is the msg name
|
122
|
-
#
|
123
|
-
# @param [String] file_path path to check - this can be a directory or file
|
124
|
-
def get_msg_name(file_path)
|
125
|
-
base_name = File.basename(file_path)
|
126
|
-
ext_name = File.extname(base_name)
|
127
|
-
file_name = base_name.sub(ext_name, '')
|
128
|
-
|
129
|
-
msg_name = file_name
|
130
|
-
end
|
131
|
-
|
132
|
-
# Load top level handlers from the given directory
|
133
|
-
#
|
134
|
-
# @param [String] baseDir directory to check - should not have trailing slash
|
135
|
-
def load_handlers_from_top_level_path(base_dir)
|
136
|
-
RServiceBus.rlog "HandlerLoader.loadHandlersFromTopLevelPath. baseDir: #{base_dir}"
|
137
|
-
get_list_of_files_for_dir(base_dir).each do |file_path|
|
138
|
-
unless file_path.end_with?('.')
|
139
|
-
msg_name = get_msg_name(file_path)
|
140
|
-
if File.directory?(file_path)
|
141
|
-
load_handlers_from_second_level_path(msg_name, file_path)
|
142
|
-
else
|
143
|
-
handler_name = "MessageHandler_#{msg_name}"
|
144
|
-
load_handler(msg_name, file_path, handler_name)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
self
|
150
|
-
end
|
151
|
-
|
152
|
-
# Entry point for loading handlers
|
153
|
-
#
|
154
|
-
# @param [String] baseDir directory to check - should not have trailing
|
155
|
-
# slash
|
156
|
-
def load_handlers_from_path(base_dir)
|
157
|
-
load_handlers_from_top_level_path(base_dir)
|
158
|
-
|
159
|
-
self
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
@@ -1,131 +0,0 @@
|
|
1
|
-
module RServiceBus
|
2
|
-
# Given a directory, this class is responsible for finding
|
3
|
-
# msgnames,
|
4
|
-
# handlernames, and
|
5
|
-
# loading handlers
|
6
|
-
class HandlerManager
|
7
|
-
# Constructor
|
8
|
-
#
|
9
|
-
# @param [RServiceBus::Host] host instance
|
10
|
-
# @param [Hash] app_resources As hash[k,v] where k is the name of a resource, and v is the resource
|
11
|
-
def initialize(host, resource_manager, state_manager)
|
12
|
-
@host = host
|
13
|
-
@resource_manager = resource_manager
|
14
|
-
@state_manager = state_manager
|
15
|
-
|
16
|
-
@handler_list = {}
|
17
|
-
@resource_list_by_handler_name = {}
|
18
|
-
end
|
19
|
-
|
20
|
-
# setBusAttributeIfRequested
|
21
|
-
#
|
22
|
-
# @param [RServiceBus::Handler] handler
|
23
|
-
def set_bus_attribute_if_requested(handler)
|
24
|
-
if defined?(handler.bus)
|
25
|
-
handler.bus = @host
|
26
|
-
RServiceBus.log 'Bus attribute set for: ' + handler.class.name
|
27
|
-
end
|
28
|
-
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
# setStateAttributeIfRequested
|
33
|
-
#
|
34
|
-
# @param [RServiceBus::Handler] handler
|
35
|
-
def set_state_attribute_if_requested(handler)
|
36
|
-
if defined?(handler.State)
|
37
|
-
handler.State = @state_manager.get(handler)
|
38
|
-
RServiceBus.log 'Bus attribute set for: ' + handler.class.name
|
39
|
-
end
|
40
|
-
|
41
|
-
self
|
42
|
-
end
|
43
|
-
|
44
|
-
# checkIfStateAttributeRequested
|
45
|
-
#
|
46
|
-
# @param [RServiceBus::Handler] handler
|
47
|
-
def check_if_state_attribute_requested(handler)
|
48
|
-
@state_manager.Required if defined?(handler.state)
|
49
|
-
|
50
|
-
self
|
51
|
-
end
|
52
|
-
|
53
|
-
def interrogate_handler_for_app_resources(handler)
|
54
|
-
RServiceBus.rlog "Checking app resources for: #{handler.class.name}"
|
55
|
-
RServiceBus.rlog "If your attribute is not getting set, check that it is in the 'attr_accessor' list"
|
56
|
-
|
57
|
-
@resource_list_by_handler_name[handler.class.name] = []
|
58
|
-
@resource_manager.get_all.each do |k, v|
|
59
|
-
next unless handler.class.method_defined?(k)
|
60
|
-
|
61
|
-
@resource_list_by_handler_name[handler.class.name] << k
|
62
|
-
RServiceBus.log "Resource attribute, #{k}, found for: " +
|
63
|
-
handler.class.name
|
64
|
-
end
|
65
|
-
|
66
|
-
self
|
67
|
-
end
|
68
|
-
|
69
|
-
def add_handler(msg_name, handler)
|
70
|
-
@handler_list[msg_name] = [] if @handler_list[msg_name].nil?
|
71
|
-
return unless @handler_list[msg_name].index{ |x| x.class.name == handler.class.name }.nil?
|
72
|
-
|
73
|
-
@handler_list[msg_name] << handler
|
74
|
-
set_bus_attribute_if_requested(handler)
|
75
|
-
check_if_state_attribute_requested(handler)
|
76
|
-
interrogate_handler_for_app_resources(handler)
|
77
|
-
end
|
78
|
-
|
79
|
-
# As named
|
80
|
-
#
|
81
|
-
# @param [String] msgName
|
82
|
-
# @param [Array] appResources A list of appResource
|
83
|
-
def get_list_of_resources_needed_to_process_msg(msg_name)
|
84
|
-
return [] if @handler_list[msg_name].nil?
|
85
|
-
|
86
|
-
list = []
|
87
|
-
@handler_list[msg_name].each do |handler|
|
88
|
-
list = list + @resource_list_by_handler_name[handler.class.name] unless @resource_list_by_handler_name[handler.class.name].nil?
|
89
|
-
end
|
90
|
-
list.uniq!
|
91
|
-
end
|
92
|
-
|
93
|
-
def set_resources_for_handlers_needed_to_process_msg(msg_name)
|
94
|
-
@handler_list[msg_name].each do |handler|
|
95
|
-
set_state_attribute_if_requested(handler)
|
96
|
-
|
97
|
-
next if @resource_list_by_handler_name[handler.class.name].nil?
|
98
|
-
@resource_list_by_handler_name[handler.class.name].each do |k|
|
99
|
-
handler.instance_variable_set("@#{k}", @resource_manager.get(k).get_resource)
|
100
|
-
RServiceBus.rlog "App resource attribute, #{k}, set for: " + handler.class.name
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def get_handler_list_for_msg(msg_name)
|
106
|
-
return [] if @handler_list[msg_name].nil?
|
107
|
-
|
108
|
-
list = get_list_of_resources_needed_to_process_msg(msg_name)
|
109
|
-
set_resources_for_handlers_needed_to_process_msg(msg_name)
|
110
|
-
|
111
|
-
@handler_list[msg_name]
|
112
|
-
end
|
113
|
-
|
114
|
-
def can_msg_be_handled_locally(msg_name)
|
115
|
-
@handler_list.key?(msg_name)
|
116
|
-
end
|
117
|
-
|
118
|
-
def get_stats
|
119
|
-
list = []
|
120
|
-
@handler_list.each do |k, v|
|
121
|
-
list << v.inspect
|
122
|
-
end
|
123
|
-
|
124
|
-
list
|
125
|
-
end
|
126
|
-
|
127
|
-
def get_list_of_msg_names
|
128
|
-
@handler_list.keys
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
data/lib/rservicebus/host.rb
DELETED
@@ -1,487 +0,0 @@
|
|
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
|