rservicebus 0.0.41 → 0.0.42

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rservicebus.rb CHANGED
@@ -6,6 +6,7 @@ require "yaml"
6
6
  require "uuidtools"
7
7
  require "redis"
8
8
  require "json"
9
+ require "uri"
9
10
 
10
11
  require "rservicebus/helper_functions"
11
12
  require "rservicebus/ErrorMessage"
@@ -26,6 +27,8 @@ require "rservicebus/SubscriptionManager"
26
27
  require "rservicebus/SubscriptionStorage"
27
28
  require "rservicebus/ConfigureSubscriptionStorage"
28
29
 
30
+ require "rservicebus/ConfigureMonitor"
31
+
29
32
  require 'rservicebus/Agent'
30
33
 
31
34
 
@@ -118,13 +118,15 @@ class Config
118
118
  #Expected format;
119
119
  # /one/two/Contracts
120
120
  def loadContracts()
121
- if self.getValue( "CONTRACTS", "./Contract" ).nil? then
121
+ @contractList = Array.new
122
+
123
+ #This is a guard clause in case no Contracts have been specified
124
+ #If any guard clauses have been specified, then execution should drop to the second block
125
+ if self.getValue( "CONTRACTS" ).nil? then
122
126
  return self
123
127
  end
124
- @contractList = Array.new
125
128
 
126
129
  self.getValue( "CONTRACTS", "./Contract" ).split( ";" ).each do |path|
127
- log "Loading contracts from, #{path}"
128
130
  self.ensureContractFileExists( path )
129
131
  @contractList << path
130
132
  end
@@ -7,7 +7,7 @@ module RServiceBus
7
7
 
8
8
  def getResources( env )
9
9
  resources = Hash.new
10
-
10
+
11
11
  env.each do |k,v|
12
12
  if v.is_a?(String) and
13
13
  k.start_with?( "RSB_" ) then
@@ -0,0 +1,82 @@
1
+ module RServiceBus
2
+
3
+ require 'rservicebus/Monitor'
4
+ require 'rservicebus/Monitor/Message'
5
+
6
+ #Configure AppResources for an rservicebus host
7
+ class ConfigureMonitor
8
+
9
+ @resourceList
10
+
11
+ # Constructor
12
+ #
13
+ # @param [RServiceBus::Host] host instance
14
+ # @param [Hash] appResources As hash[k,v] where k is the name of a resource, and v is the resource
15
+ def initialize( host, appResources )
16
+ @host = host
17
+ @appResources = appResources
18
+
19
+ @handlerList = Hash.new
20
+ @resourceList = Hash.new
21
+ end
22
+
23
+ # Assigns appropriate resources to writable attributes in the handler that match keys in the resource hash
24
+ #
25
+ # @param [RServiceBus::Handler] handler
26
+ ## @param [Hash] appResources As hash[k,v] where k is the name of a resource, and v is the resource
27
+ def setAppResources( monitor )
28
+ @host.log "Checking app resources for: #{monitor.class.name}", true
29
+ @host.log "If your attribute is not getting set, check that it is in the 'attr_accessor' list", true
30
+ @appResources.each do |k,v|
31
+ if monitor.class.method_defined?( k ) then
32
+ monitor.instance_variable_set( "@#{k}", v.getResource() )
33
+ @resourceList[monitor.class.name] = Array.new if @resourceList[monitor.class.name].nil?
34
+ @resourceList[monitor.class.name] << v
35
+ @host.log "App resource attribute, #{k}, set for: " + monitor.class.name
36
+ end
37
+ end
38
+
39
+ return self
40
+ end
41
+
42
+
43
+ def getMonitors( env )
44
+ monitors = Array.new
45
+
46
+ env.each do |k,v|
47
+ if v.is_a?(String) and
48
+ k.start_with?( "RSBOB_" ) then
49
+ uri = URI.parse( v )
50
+ name = k.sub( "RSBOB_", "" )
51
+ monitor = nil?
52
+ case uri.scheme
53
+ when "csvdir"
54
+ require "rservicebus/Monitor/CsvDir"
55
+ monitor = Monitor_CsvDir.new( @host, name, uri )
56
+
57
+ when "xmldir"
58
+ require "rservicebus/Monitor/XmlDir"
59
+ monitor = Monitor_XmlDir.new( @host, name, uri )
60
+
61
+ when "dir"
62
+ require "rservicebus/Monitor/Dir"
63
+ monitor = Monitor_Dir.new( @host, name, uri )
64
+
65
+ when "csvperlinedir"
66
+ require "rservicebus/Monitor/CsvPerLine"
67
+ monitor = Monitor_CsvPerLineDir.new( @host, name, uri )
68
+ else
69
+ abort("Scheme, #{uri.scheme}, not recognised when configuring Monitor, #{k}=#{v}");
70
+ end
71
+ self.setAppResources( monitor )
72
+ monitors << monitor
73
+ end
74
+
75
+ end
76
+
77
+ return monitors
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -22,6 +22,8 @@ class HandlerLoader
22
22
 
23
23
  @handlerList
24
24
  @resourceList
25
+
26
+ @listOfLoadedPaths
25
27
 
26
28
  # Constructor
27
29
  #
@@ -33,6 +35,8 @@ class HandlerLoader
33
35
 
34
36
  @handlerList = Hash.new
35
37
  @resourceList = Hash.new
38
+
39
+ @listOfLoadedPaths = Hash.new
36
40
  end
37
41
 
38
42
  # Cleans the given path to ensure it can be used for as a parameter for the require statement.
@@ -110,7 +114,12 @@ class HandlerLoader
110
114
  # @param [String] filePath
111
115
  # @param [String] handlerName
112
116
  # @returns [RServiceBus::Handler] handler
113
- def loadAndConfigureHandler(filePath, handlerName)
117
+ def loadAndConfigureHandler(msgName, filePath, handlerName)
118
+ if @listOfLoadedPaths.has_key?( filePath ) then
119
+ @host.log "Not reloading, #{filePath}"
120
+ return
121
+ end
122
+
114
123
  begin
115
124
  @host.log "filePath: " + filePath, true
116
125
  @host.log "handlerName: " + handlerName, true
@@ -120,7 +129,10 @@ class HandlerLoader
120
129
  self.setAppResources( handler )
121
130
  @host.log "Loaded Handler: " + handlerName
122
131
 
123
- return handler
132
+ @handlerList[msgName] = Array.new unless @handlerList.has_key?( msgName )
133
+ @handlerList[msgName] << handler;
134
+
135
+ @listOfLoadedPaths[filePath] = 1
124
136
  rescue Exception => e
125
137
  puts "Exception loading handler from file: " + filePath
126
138
  puts e.message
@@ -155,12 +167,7 @@ class HandlerLoader
155
167
  fileName = File.basename( filePath ).sub( ".rb", "" )
156
168
  handlerName = "MessageHandler_#{msgName}_#{fileName}"
157
169
 
158
- handler = self.loadAndConfigureHandler( filePath, handlerName )
159
- if !@handlerList.has_key?( msgName ) then
160
- @handlerList[msgName] = Array.new
161
- end
162
-
163
- @handlerList[msgName] << handler;
170
+ self.loadAndConfigureHandler( msgName, filePath, handlerName )
164
171
  end
165
172
  end
166
173
  end
@@ -194,13 +201,7 @@ class HandlerLoader
194
201
  self.loadHandlersFromSecondLevelPath( msgName, filePath )
195
202
  else
196
203
  handlerName = "MessageHandler_#{msgName}"
197
- handler = self.loadAndConfigureHandler( filePath, handlerName )
198
-
199
- if !@handlerList.has_key?( msgName ) then
200
- @handlerList[msgName] = Array.new
201
- end
202
-
203
- @handlerList[msgName] << handler;
204
+ self.loadAndConfigureHandler( msgName, filePath, handlerName )
204
205
  end
205
206
  end
206
207
  end
@@ -33,14 +33,21 @@ module RServiceBus
33
33
  puts "[#{type}] #{timestamp} :: #{string}"
34
34
  end
35
35
  end
36
-
36
+
37
37
  #Thin veneer for Configuring external resources
38
38
  #
39
39
  def configureAppResource
40
40
  @appResources = ConfigureAppResource.new.getResources( ENV )
41
41
  return self;
42
42
  end
43
-
43
+
44
+ #Thin veneer for Configuring external resources
45
+ #
46
+ def configureMonitors
47
+ @monitors = ConfigureMonitor.new( self, @appResources ).getMonitors( ENV )
48
+ return self;
49
+ end
50
+
44
51
  #Thin veneer for Configuring the Message Queue
45
52
  #
46
53
  def connectToMq
@@ -48,7 +55,7 @@ module RServiceBus
48
55
 
49
56
  return self
50
57
  end
51
-
58
+
52
59
  #Subscriptions are specified by adding events to the
53
60
  #msg endpoint mapping
54
61
  def sendSubscriptions
@@ -70,11 +77,11 @@ module RServiceBus
70
77
  def loadHandlers()
71
78
  log "Load Message Handlers"
72
79
  @handlerLoader = HandlerLoader.new( self, @appResources )
73
-
80
+
74
81
  @config.handlerPathList.each do |path|
75
82
  @handlerLoader.loadHandlersFromPath(path)
76
83
  end
77
-
84
+
78
85
  @handlerList = @handlerLoader.handlerList
79
86
  @resourceByHandlerNameList = @handlerLoader.resourceList
80
87
 
@@ -85,9 +92,10 @@ module RServiceBus
85
92
  #
86
93
  def loadContracts()
87
94
  log "Load Contracts"
88
-
95
+
89
96
  @config.contractList.each do |path|
90
97
  require path
98
+ log "Loaded Contract: #{path}", true
91
99
  end
92
100
 
93
101
  return self
@@ -129,7 +137,6 @@ module RServiceBus
129
137
  end
130
138
 
131
139
  def initialize()
132
-
133
140
  @config = ConfigFromEnv.new
134
141
  .configureLogging()
135
142
  .loadHostSection()
@@ -141,11 +148,12 @@ module RServiceBus
141
148
  .loadWorkingDirList();
142
149
 
143
150
  self.configureStatistics()
144
- .configureAppResource()
145
- .connectToMq()
146
- .loadHandlers()
147
151
  .loadContracts()
148
152
  .loadLibs()
153
+ .configureAppResource()
154
+ .configureMonitors()
155
+ .loadHandlers()
156
+ .connectToMq()
149
157
  .configureSubscriptions()
150
158
  .sendSubscriptions()
151
159
 
@@ -212,7 +220,7 @@ module RServiceBus
212
220
  end
213
221
  tempResourceList.each {|k,resource| resource.reconnect }
214
222
  tempHandlerList.each {|k,handler| @handlerLoader.setAppResources( handler ) }
215
-
223
+
216
224
  if retries > 0 then
217
225
  retries = retries - 1
218
226
  @mq.returnToQueue
@@ -248,6 +256,12 @@ module RServiceBus
248
256
  rescue NoMsgToProcess => e
249
257
  #This exception is just saying there are no messages to process
250
258
  statOutputCountdown = 0
259
+
260
+ @monitors.each do |o|
261
+ o.Look
262
+ end
263
+
264
+
251
265
  rescue Exception => e
252
266
  if e.message == "SIGTERM" then
253
267
  puts "Exiting on request ..."
@@ -273,7 +287,7 @@ module RServiceBus
273
287
  puts "No handler found for: " + msgName
274
288
  puts YAML::dump(@msg)
275
289
  raise "No Handler Found"
276
-
290
+
277
291
  else
278
292
  log "Handler found for: " + msgName, true
279
293
  handlerList.each do |handler|
@@ -287,7 +301,7 @@ module RServiceBus
287
301
  end
288
302
  end
289
303
  end
290
-
304
+
291
305
  #Sends a msg across the bus
292
306
  #
293
307
  # @param [String] serialized_object serialized RServiceBus::Message
@@ -0,0 +1,64 @@
1
+ class Monitor
2
+
3
+ attr_accessor :Bus
4
+
5
+ @Bus
6
+ @uri
7
+ @connection
8
+ @MsgType
9
+
10
+ # The method which actually connects to the resource.
11
+ #
12
+ def connect(uri)
13
+ raise "Method, connect, needs to be implemented for resource"
14
+ end
15
+
16
+ # The method which actually connects to the resource.
17
+ #
18
+ def Look
19
+ raise "Method, Look, needs to be implemented for the Monitor"
20
+ end
21
+
22
+ def _connect
23
+ @connection = self.connect(@uri)
24
+ @Bus.log "#{self.class.name}. Connected to, #{@uri.to_s}" unless !ENV["QUIET"].nil?
25
+ end
26
+
27
+ # Resources are attached resources, and can be specified using the URI syntax.
28
+ #
29
+ # @param [String] uri a location for the resource to which we will attach, eg redis://127.0.0.1/foo
30
+ def initialize( bus, name, uri )
31
+ @Bus = bus
32
+ # @MsgType = Object.const_get( name )
33
+ newAnonymousClass = Class.new(Monitor_Message)
34
+ Object.const_set( name, newAnonymousClass )
35
+ @MsgType = Object.const_get( name )
36
+
37
+
38
+ @uri = uri
39
+ self._connect
40
+ end
41
+
42
+ # A notification that allows cleanup
43
+ def finished
44
+ end
45
+
46
+ # At least called in the Host rescue block, to ensure all network links are healthy
47
+ def reconnect
48
+ begin
49
+ self.finished
50
+ rescue Exception => e
51
+ puts "** Monitor. An error was raised while closing connection to, " + @uri.to_s
52
+ puts "Message: " + e.message
53
+ puts e.backtrace
54
+ end
55
+
56
+ self._connect
57
+ end
58
+
59
+ def send( payload )
60
+ msg = @MsgType.new( payload )
61
+
62
+ @Bus.Send( msg )
63
+ end
64
+ end
@@ -0,0 +1,11 @@
1
+ require 'rservicebus/Monitor/Dir'
2
+ require 'csv'
3
+
4
+ class Monitor_CsvDir<Monitor_Dir
5
+
6
+
7
+ def ProcessPath( path )
8
+ return CSV.read( path )
9
+ end
10
+
11
+ end
@@ -0,0 +1,13 @@
1
+ require 'rservicebus/Monitor/Dir'
2
+ require 'csv'
3
+
4
+ class Monitor_CsvPerLineDir<Monitor_Dir
5
+
6
+
7
+ def ProcessFile( file )
8
+ CSV.read( file ).each do |csvline|
9
+ self.send( csvline )
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,31 @@
1
+
2
+ class Monitor_Dir<Monitor
3
+
4
+ @Path
5
+
6
+ def connect(uri)
7
+ #Pass the path through the Dir object to check syntax on startup
8
+ inputDir = Dir.new( uri.path )
9
+ @Path = inputDir.path
10
+ end
11
+
12
+ def ProcessPath( path )
13
+ return IO.read( path )
14
+ end
15
+
16
+ def ProcessFile( file )
17
+ payload = self.ProcessPath( file )
18
+
19
+ self.send( payload )
20
+ end
21
+
22
+ def Look
23
+ Dir.glob( "#{@Path}/*" ).each do |file|
24
+ self.ProcessFile( file )
25
+
26
+ File.unlink( file )
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,10 @@
1
+ class Monitor_Message
2
+ attr_reader :payload
3
+
4
+ @payload
5
+
6
+ def initialize( payload )
7
+ @payload = payload
8
+ end
9
+
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'rservicebus/Monitor/Dir'
2
+ require 'xmlsimple'
3
+
4
+ class Monitor_XmlDir<Monitor_Dir
5
+
6
+
7
+ def ProcessPath( path )
8
+ # return Nokogiri::XML( File.open(path) )
9
+ return XmlSimple.xml_in( path )
10
+ end
11
+
12
+ end
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.41
4
+ version: 0.0.42
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: 2013-03-05 00:00:00.000000000 Z
12
+ date: 2013-03-09 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A Ruby interpretation of NServiceBus
15
15
  email: guy@guyirvine.com
@@ -36,6 +36,7 @@ files:
36
36
  - lib/rservicebus/AppResource.rb
37
37
  - lib/rservicebus/Config.rb
38
38
  - lib/rservicebus/ConfigureAppResource.rb
39
+ - lib/rservicebus/ConfigureMonitor.rb
39
40
  - lib/rservicebus/ConfigureMQ.rb
40
41
  - lib/rservicebus/ConfigureSubscriptionStorage.rb
41
42
  - lib/rservicebus/ErrorMessage.rb
@@ -44,6 +45,12 @@ files:
44
45
  - lib/rservicebus/Host.rb
45
46
  - lib/rservicebus/Message/Subscription.rb
46
47
  - lib/rservicebus/Message.rb
48
+ - lib/rservicebus/Monitor/CsvDir.rb
49
+ - lib/rservicebus/Monitor/CsvPerLine.rb
50
+ - lib/rservicebus/Monitor/Dir.rb
51
+ - lib/rservicebus/Monitor/Message.rb
52
+ - lib/rservicebus/Monitor/XmlDir.rb
53
+ - lib/rservicebus/Monitor.rb
47
54
  - lib/rservicebus/MQ/Beanstalk.rb
48
55
  - lib/rservicebus/MQ/Bunny.rb
49
56
  - lib/rservicebus/MQ.rb