rservicebus 0.0.6 → 0.0.7
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/lib/rservicebus/Agent.rb +10 -0
- data/lib/rservicebus/AppResource.rb +9 -0
- data/lib/rservicebus/Config.rb +4 -7
- data/lib/rservicebus/ConfigureAppResource.rb +1 -0
- data/lib/rservicebus/HandlerLoader.rb +139 -40
- data/lib/rservicebus/Host.rb +4 -28
- data/lib/rservicebus/Message.rb +13 -0
- data/lib/rservicebus/RedisAppResource.rb +1 -0
- data/lib/rservicebus/Test/Bus.rb +4 -4
- metadata +3 -2
data/lib/rservicebus/Agent.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module RServiceBus
|
2
2
|
require 'beanstalk-client'
|
3
3
|
|
4
|
+
#A means for a stand-alone process to interact with the bus, without being a full
|
5
|
+
#rservicebus application
|
4
6
|
class Agent
|
5
7
|
@beanstalk
|
6
8
|
|
@@ -8,6 +10,11 @@ class Agent
|
|
8
10
|
@beanstalk = Beanstalk::Pool.new(url)
|
9
11
|
end
|
10
12
|
|
13
|
+
# Put a msg on the bus
|
14
|
+
#
|
15
|
+
# @param [Object] messageObj The msg to be sent
|
16
|
+
# @param [String] queueName the name of the queue to be send the msg to
|
17
|
+
# @param [String] returnAddress the name of a queue to send replies to
|
11
18
|
def sendMsg(messageObj, queueName, returnAddress=nil)
|
12
19
|
msg = RServiceBus::Message.new( messageObj, returnAddress )
|
13
20
|
serialized_object = YAML::dump(msg)
|
@@ -16,6 +23,9 @@ class Agent
|
|
16
23
|
@beanstalk.put( serialized_object )
|
17
24
|
end
|
18
25
|
|
26
|
+
# Gives an agent a mean to receive replies
|
27
|
+
#
|
28
|
+
# @param [String] queueName the name of the queue to monitor for messages
|
19
29
|
def checkForReply( queueName )
|
20
30
|
@beanstalk.watch queueName
|
21
31
|
job = @beanstalk.reserve
|
@@ -1,12 +1,21 @@
|
|
1
1
|
require "uri"
|
2
2
|
|
3
|
+
# Wrapper base class for resources used by applications, allowing rservicebus to configure the resource
|
4
|
+
# - dependency injection.
|
5
|
+
#
|
3
6
|
class AppResource
|
4
7
|
@uri
|
5
8
|
|
9
|
+
# Resources are attached resources, and can be specified using the URI syntax.
|
10
|
+
#
|
11
|
+
# @param [String] uri a location for the resource to which we will attach, eg redis://127.0.0.1/foo
|
6
12
|
def initialize( uri )
|
7
13
|
@uri = uri
|
8
14
|
end
|
9
15
|
|
16
|
+
# The method which actually configures the resource.
|
17
|
+
#
|
18
|
+
# @return [Object] the configured object.
|
10
19
|
def getResource
|
11
20
|
raise "Method, getResource, needs to be implemented for resource"
|
12
21
|
end
|
data/lib/rservicebus/Config.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
module RServiceBus
|
2
2
|
|
3
|
+
#Collects and reports configuration information for an rservicebus host
|
3
4
|
class Config
|
4
|
-
#host:
|
5
|
-
## @appName: CreateUser
|
6
|
-
## errorQueueName: error
|
7
|
-
#
|
8
5
|
attr_reader :appName, :messageEndpointMappings, :handlerPathList, :localQueueName, :errorQueueName, :maxRetries, :forwardReceivedMessagesTo, :verbose, :beanstalkHost
|
9
6
|
|
10
7
|
@appName
|
@@ -50,7 +47,7 @@ class Config
|
|
50
47
|
end
|
51
48
|
|
52
49
|
def loadHandlerPathList()
|
53
|
-
path = self.getValue( "MSGHANDLERPATH", "MessageHandler" )
|
50
|
+
path = self.getValue( "MSGHANDLERPATH", "./MessageHandler" )
|
54
51
|
handlerPathList = Array.new
|
55
52
|
path.split( ";" ).each do |path|
|
56
53
|
path = path.strip.chomp( "/" )
|
@@ -74,11 +71,11 @@ class Config
|
|
74
71
|
end
|
75
72
|
|
76
73
|
def loadContracts()
|
77
|
-
if self.getValue( "CONTRACTS" ).nil? then
|
74
|
+
if self.getValue( "CONTRACTS", "./Contract" ).nil? then
|
78
75
|
return self
|
79
76
|
end
|
80
77
|
|
81
|
-
self.getValue( "CONTRACTS" ).split( ";" ).each do |path|
|
78
|
+
self.getValue( "CONTRACTS", "./Contract" ).split( ";" ).each do |path|
|
82
79
|
puts "Loading contracts from, #{path}"
|
83
80
|
require path
|
84
81
|
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
module RServiceBus
|
2
2
|
|
3
|
+
#Given a directory, this class is responsible for finding
|
4
|
+
# msgnames,
|
5
|
+
# handlernames, and
|
6
|
+
# loading handlers
|
3
7
|
class HandlerLoader
|
4
8
|
|
5
|
-
attr_reader :
|
9
|
+
attr_reader :handlerList
|
6
10
|
|
7
11
|
@host
|
8
12
|
@appResources
|
@@ -16,28 +20,22 @@ class HandlerLoader
|
|
16
20
|
@messageName
|
17
21
|
@handler
|
18
22
|
|
23
|
+
@handlerList
|
24
|
+
|
25
|
+
# Constructor
|
26
|
+
#
|
27
|
+
# @param [RServiceBus::Host] host instance
|
28
|
+
# @param [Hash] appResources As hash[k,v] where k is the name of a resource, and v is the resource
|
19
29
|
def initialize( host, appResources )
|
20
30
|
@host = host
|
21
31
|
@appResources = appResources
|
32
|
+
|
33
|
+
@handlerList = Hash.new
|
22
34
|
end
|
23
35
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
return name.match( /(.+)\./ )[1]
|
28
|
-
end
|
29
|
-
|
30
|
-
if name.count( "/" ) == 1 then
|
31
|
-
return name.match( /\/(.+)\./ )[1]
|
32
|
-
end
|
33
|
-
|
34
|
-
puts "Filepath, " + fileName + ", not in the expected format."
|
35
|
-
puts "Expected format either,"
|
36
|
-
puts "MessageHandler/Hello.rb, or"
|
37
|
-
puts "MessageHandler/Hello/One.rb, or"
|
38
|
-
abort();
|
39
|
-
end
|
40
|
-
|
36
|
+
# Cleans the given path to ensure it can be used for as a parameter for the require statement.
|
37
|
+
#
|
38
|
+
# @param [String] filePath the path to be cleaned
|
41
39
|
def getRequirePath( filePath )
|
42
40
|
if !filePath.start_with?( "/" ) then
|
43
41
|
filePath = "./" + filePath
|
@@ -50,12 +48,17 @@ class HandlerLoader
|
|
50
48
|
abort( "Filepath, " + filePath + ", given for MessageHandler require doesn't exist" );
|
51
49
|
end
|
52
50
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
# Instantiate the handler named in handlerName from the file name in filePath
|
52
|
+
# Exceptions will be raised if encountered when loading handlers. This is a load time activity,
|
53
|
+
# so handlers should load correctly. As much information as possible is returned
|
54
|
+
# to enable the handler to be fixed, or configuration corrected.
|
55
|
+
#
|
56
|
+
# @param [String] handlerName name of the handler to instantiate
|
57
|
+
# @param [String] filePath the path to the file to be loaded
|
58
|
+
# @return [RServiceBus::Handler] the loader
|
59
|
+
def loadHandlerFromFile( handlerName, filePath )
|
60
|
+
requirePath = self.getRequirePath( filePath )
|
57
61
|
|
58
|
-
def loadHandlerFromFile( requirePath, handlerName, filePath )
|
59
62
|
require requirePath
|
60
63
|
begin
|
61
64
|
handler = Object.const_get(handlerName).new();
|
@@ -69,40 +72,50 @@ class HandlerLoader
|
|
69
72
|
return handler
|
70
73
|
end
|
71
74
|
|
72
|
-
|
75
|
+
# setBusAttributeIfRequested
|
76
|
+
#
|
77
|
+
# @param [RServiceBus::Handler] handler
|
78
|
+
def setBusAttributeIfRequested( handler )
|
73
79
|
if defined?( handler.Bus ) then
|
74
80
|
handler.Bus = @host
|
75
|
-
@host.log "Bus attribute set for: " +
|
81
|
+
@host.log "Bus attribute set for: " + handler.class.name
|
76
82
|
end
|
83
|
+
|
84
|
+
return self
|
77
85
|
end
|
78
86
|
|
79
|
-
|
80
|
-
|
87
|
+
# Assigns appropriate resources to writable attributes in the handler that match keys in the resource hash
|
88
|
+
#
|
89
|
+
# @param [RServiceBus::Handler] handler
|
90
|
+
# @param [Hash] appResources As hash[k,v] where k is the name of a resource, and v is the resource
|
91
|
+
def setAppResources( handler, appResources )
|
92
|
+
@host.log "Checking app resources for: #{handler.class.name}", true
|
81
93
|
appResources.each do |k,v|
|
82
94
|
if handler.class.method_defined?( k ) then
|
83
95
|
handler.instance_variable_set( "@#{k}", v.getResource() )
|
84
|
-
@host.log "App resource attribute, #{k}, set for: " +
|
96
|
+
@host.log "App resource attribute, #{k}, set for: " + handler.class.name
|
85
97
|
end
|
86
98
|
end
|
99
|
+
|
100
|
+
return self
|
87
101
|
end
|
88
102
|
|
89
|
-
|
103
|
+
# Wrapper function
|
104
|
+
#
|
105
|
+
# @param [String] filePath
|
106
|
+
# @param [String] handlerName
|
107
|
+
# @returns [RServiceBus::Handler] handler
|
108
|
+
def loadAndConfigureHandler(filePath, handlerName)
|
90
109
|
begin
|
91
|
-
requirePath = self.getRequirePath( filePath )
|
92
|
-
messageName = self.getMessageName( baseDir, filePath )
|
93
|
-
handlerName = self.getHandlerName( baseDir, filePath )
|
94
|
-
|
95
110
|
@host.log "filePath: " + filePath, true
|
96
|
-
@host.log "requirePath: " + requirePath, true
|
97
|
-
@host.log "messageName: " + messageName, true
|
98
111
|
@host.log "handlerName: " + handlerName, true
|
99
112
|
|
100
|
-
handler = self.loadHandlerFromFile(
|
101
|
-
self.setBusAttributeIfRequested( handler
|
102
|
-
self.setAppResources( handler,
|
103
|
-
@host.log "Loaded Handler: " + handlerName
|
113
|
+
handler = self.loadHandlerFromFile( handlerName, filePath )
|
114
|
+
self.setBusAttributeIfRequested( handler )
|
115
|
+
self.setAppResources( handler, @appResources )
|
116
|
+
@host.log "Loaded Handler: " + handlerName
|
104
117
|
|
105
|
-
return
|
118
|
+
return handler
|
106
119
|
rescue Exception => e
|
107
120
|
puts "Exception loading handler from file: " + filePath
|
108
121
|
puts e.message
|
@@ -113,6 +126,92 @@ class HandlerLoader
|
|
113
126
|
|
114
127
|
end
|
115
128
|
|
129
|
+
#This method is overloaded for unit tests
|
130
|
+
#
|
131
|
+
# @param [String] path directory to check
|
132
|
+
# @return [Array] a list of paths to files found in the given path
|
133
|
+
def getListOfFilesForDir( path )
|
134
|
+
return Dir[path + "/*"];
|
135
|
+
end
|
136
|
+
|
137
|
+
#Multiple handlers for the same msg can be placed inside a top level directory.
|
138
|
+
#The msg name is than taken from the directory, and the handlers from the files inside that
|
139
|
+
#directory
|
140
|
+
#
|
141
|
+
# @param [String] msgName name of message
|
142
|
+
# @param [String] baseDir directory to check for handlers of the given msgName
|
143
|
+
def loadHandlersFromSecondLevelPath(msgName, baseDir)
|
144
|
+
self.getListOfFilesForDir(baseDir).each do |filePath|
|
145
|
+
if !filePath.end_with?( "." ) then
|
146
|
+
extName = File.extname( filePath )
|
147
|
+
if !File.directory?( filePath ) &&
|
148
|
+
extName == ".rb" then
|
149
|
+
|
150
|
+
fileName = File.basename( filePath ).sub( ".rb", "" )
|
151
|
+
handlerName = "MessageHandler_#{msgName}_#{fileName}"
|
152
|
+
|
153
|
+
handler = self.loadAndConfigureHandler( filePath, handlerName )
|
154
|
+
if !@handlerList.has_key?( msgName ) then
|
155
|
+
@handlerList[msgName] = Array.new
|
156
|
+
end
|
157
|
+
|
158
|
+
@handlerList[msgName] << handler;
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
return self
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
#Extract the top level dir or file name as it is the msg name
|
168
|
+
#
|
169
|
+
# @param [String] filePath path to check - this can be a directory or file
|
170
|
+
def getMsgName( filePath )
|
171
|
+
baseName = File.basename( filePath )
|
172
|
+
extName = File.extname( baseName )
|
173
|
+
fileName = baseName.sub( extName, "" )
|
174
|
+
|
175
|
+
msgName = fileName
|
176
|
+
|
177
|
+
return msgName
|
178
|
+
end
|
179
|
+
|
180
|
+
#Load top level handlers from the given directory
|
181
|
+
#
|
182
|
+
# @param [String] baseDir directory to check - should not have trailing slash
|
183
|
+
def loadHandlersFromTopLevelPath(baseDir)
|
184
|
+
self.getListOfFilesForDir(baseDir).each do |filePath|
|
185
|
+
if !filePath.end_with?( "." ) then
|
186
|
+
|
187
|
+
msgName = self.getMsgName( filePath )
|
188
|
+
if File.directory?( filePath ) then
|
189
|
+
self.loadHandlersFromSecondLevelPath( msgName, filePath )
|
190
|
+
else
|
191
|
+
handlerName = "MessageHandler_#{msgName}"
|
192
|
+
handler = self.loadAndConfigureHandler( filePath, handlerName )
|
193
|
+
|
194
|
+
if !@handlerList.has_key?( msgName ) then
|
195
|
+
@handlerList[msgName] = Array.new
|
196
|
+
end
|
197
|
+
|
198
|
+
@handlerList[msgName] << handler;
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
return self
|
204
|
+
end
|
205
|
+
|
206
|
+
#Entry point for loading handlers
|
207
|
+
#
|
208
|
+
# @param [String] baseDir directory to check - should not have trailing slash
|
209
|
+
def loadHandlersFromPath(baseDir)
|
210
|
+
self.loadHandlersFromTopLevelPath(baseDir)
|
211
|
+
|
212
|
+
return self
|
213
|
+
end
|
214
|
+
|
116
215
|
end
|
117
216
|
|
118
217
|
end
|
data/lib/rservicebus/Host.rb
CHANGED
@@ -67,40 +67,16 @@ class Host
|
|
67
67
|
return self
|
68
68
|
end
|
69
69
|
|
70
|
-
def loadHandlersFromPath(baseDir, subDir="")
|
71
|
-
log "Load Message Handlers from baseDir, " + baseDir + ", subDir, " + subDir
|
72
|
-
log "Checking, " + baseDir, true
|
73
|
-
handlerLoader = HandlerLoader.new( self, @appResources )
|
74
|
-
|
75
|
-
@handlerList = {};
|
76
|
-
Dir[baseDir + "/" + subDir + "*"].each do |filePath|
|
77
|
-
if !filePath.end_with?( "." ) then
|
78
|
-
log "Filepath, " + filePath, true
|
79
|
-
|
80
|
-
if File.directory?( filePath ) then
|
81
|
-
self.loadHandlersFromPath( filePath.sub( baseDir ) )
|
82
|
-
else
|
83
|
-
messageName, handler = handlerLoader.loadHandler( baseDir, filePath )
|
84
|
-
|
85
|
-
if !@handlerList.has_key?( messageName ) then
|
86
|
-
@handlerList[messageName] = Array.new
|
87
|
-
end
|
88
|
-
|
89
|
-
@handlerList[messageName] << handler;
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
return self
|
95
|
-
end
|
96
|
-
|
97
70
|
def loadHandlers()
|
98
71
|
log "Load Message Handlers"
|
72
|
+
handlerLoader = HandlerLoader.new( self, @appResources )
|
99
73
|
|
100
74
|
@config.handlerPathList.each do |path|
|
101
|
-
|
75
|
+
handlerLoader.loadHandlersFromPath(path)
|
102
76
|
end
|
103
77
|
|
78
|
+
@handlerList = handlerLoader.handlerList
|
79
|
+
|
104
80
|
return self
|
105
81
|
end
|
106
82
|
|
data/lib/rservicebus/Message.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
module RServiceBus
|
2
2
|
|
3
|
+
#This is the top level message that is passed around the bus
|
3
4
|
class Message
|
4
5
|
|
5
6
|
attr_reader :returnAddress, :msgId
|
6
7
|
|
8
|
+
# Constructor
|
9
|
+
#
|
10
|
+
# @param [Object] msg The calling function msg to be sent
|
11
|
+
# @param [Object] returnAddress A queue that the receiving message handler can send replies to
|
7
12
|
def initialize( msg, returnAddress )
|
8
13
|
@_msg=YAML::dump(msg)
|
9
14
|
@returnAddress=returnAddress
|
@@ -12,10 +17,18 @@ class Message
|
|
12
17
|
@errorList = Array.new
|
13
18
|
end
|
14
19
|
|
20
|
+
# Capture information when an exception has occurred, to help with diagnosing the error.
|
21
|
+
# Once the error has been diagnosed, the msg may be able to be returned to the sourceQueue
|
22
|
+
#
|
23
|
+
# @param [Object] sourceQueue The name of the queue to return the msg to
|
24
|
+
# @param [Object] errorString A queue that the receiving message handler can send replies to
|
15
25
|
def addErrorMsg( sourceQueue, errorString )
|
16
26
|
@errorList << RServiceBus::ErrorMessage.new( sourceQueue, errorString )
|
17
27
|
end
|
18
28
|
|
29
|
+
# Convenience function
|
30
|
+
#
|
31
|
+
# @return [String]
|
19
32
|
def getLastErrorMsg
|
20
33
|
return @errorList.last
|
21
34
|
end
|
data/lib/rservicebus/Test/Bus.rb
CHANGED
@@ -6,7 +6,7 @@ class Test_Bus
|
|
6
6
|
@sendList
|
7
7
|
@replyList
|
8
8
|
@logList
|
9
|
-
|
9
|
+
|
10
10
|
def initialize
|
11
11
|
@publishList = Array.new
|
12
12
|
@sendList = Array.new
|
@@ -22,9 +22,9 @@ class Test_Bus
|
|
22
22
|
@sendList << msg
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def Reply( msg )
|
26
|
+
@replyList << msg
|
27
|
+
end
|
28
28
|
|
29
29
|
def log( string, verbose=false )
|
30
30
|
item = Hash.new
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rservicebus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-20 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A ruby implementation of NServiceBus
|
15
15
|
email: guy@guyirvine.com
|
@@ -61,3 +61,4 @@ signing_key:
|
|
61
61
|
specification_version: 3
|
62
62
|
summary: RServiceBus
|
63
63
|
test_files: []
|
64
|
+
has_rdoc:
|