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.
Files changed (75) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +48 -0
  3. data/bin/{rservicebus2 → rservicebus} +2 -1
  4. data/lib/rservicebus.rb +15 -54
  5. data/lib/rservicebus/Agent.rb +21 -0
  6. data/lib/rservicebus/Config.rb +125 -0
  7. data/lib/rservicebus/ErrorMessage.rb +14 -0
  8. data/lib/rservicebus/HandlerLoader.rb +100 -0
  9. data/lib/rservicebus/Host.rb +340 -0
  10. data/lib/rservicebus/Message.rb +29 -0
  11. data/lib/rservicebus/Subscription.rb +13 -0
  12. data/lib/rservicebus/helper_functions.rb +8 -81
  13. metadata +23 -150
  14. checksums.yaml +0 -7
  15. data/bin/return_messages_to_source_queue +0 -114
  16. data/bin/rsb_ctl +0 -38
  17. data/bin/rservicebus2-create +0 -107
  18. data/bin/rservicebus2-init +0 -104
  19. data/bin/rservicebus2-transport +0 -16
  20. data/bin/send_empty_message +0 -15
  21. data/lib/rservicebus/agent.rb +0 -54
  22. data/lib/rservicebus/appresource.rb +0 -65
  23. data/lib/rservicebus/appresource/dir.rb +0 -29
  24. data/lib/rservicebus/appresource/file.rb +0 -8
  25. data/lib/rservicebus/appresource/fluiddb.rb +0 -24
  26. data/lib/rservicebus/appresource_configure.rb +0 -33
  27. data/lib/rservicebus/audit.rb +0 -28
  28. data/lib/rservicebus/circuitbreaker.rb +0 -79
  29. data/lib/rservicebus/config.rb +0 -168
  30. data/lib/rservicebus/cron_manager.rb +0 -76
  31. data/lib/rservicebus/endpointmapping.rb +0 -72
  32. data/lib/rservicebus/errormessage.rb +0 -14
  33. data/lib/rservicebus/handler_loader.rb +0 -162
  34. data/lib/rservicebus/handler_manager.rb +0 -131
  35. data/lib/rservicebus/host.rb +0 -487
  36. data/lib/rservicebus/message.rb +0 -78
  37. data/lib/rservicebus/message/statisticoutput.rb +0 -7
  38. data/lib/rservicebus/message/subscription.rb +0 -10
  39. data/lib/rservicebus/message/verboseoutput.rb +0 -7
  40. data/lib/rservicebus/monitor.rb +0 -61
  41. data/lib/rservicebus/monitor/csvdir.rb +0 -52
  42. data/lib/rservicebus/monitor/dir.rb +0 -139
  43. data/lib/rservicebus/monitor/dirnotifier.rb +0 -101
  44. data/lib/rservicebus/monitor/message.rb +0 -11
  45. data/lib/rservicebus/monitor/xmldir.rb +0 -11
  46. data/lib/rservicebus/monitor_configure.rb +0 -71
  47. data/lib/rservicebus/mq.rb +0 -98
  48. data/lib/rservicebus/mq/beanstalk.rb +0 -72
  49. data/lib/rservicebus/resource_manager.rb +0 -69
  50. data/lib/rservicebus/saga/base.rb +0 -17
  51. data/lib/rservicebus/saga/data.rb +0 -20
  52. data/lib/rservicebus/saga/manager.rb +0 -128
  53. data/lib/rservicebus/saga_loader.rb +0 -118
  54. data/lib/rservicebus/saga_storage.rb +0 -18
  55. data/lib/rservicebus/saga_storage/dir.rb +0 -87
  56. data/lib/rservicebus/saga_storage/inmemory.rb +0 -37
  57. data/lib/rservicebus/sendat_manager.rb +0 -33
  58. data/lib/rservicebus/sendat_storage.rb +0 -20
  59. data/lib/rservicebus/sendat_storage/file.rb +0 -37
  60. data/lib/rservicebus/sendat_storage/inmemory.rb +0 -20
  61. data/lib/rservicebus/state_manager.rb +0 -30
  62. data/lib/rservicebus/state_storage.rb +0 -18
  63. data/lib/rservicebus/state_storage/dir.rb +0 -66
  64. data/lib/rservicebus/state_storage/inmemory.rb +0 -25
  65. data/lib/rservicebus/statistic_manager.rb +0 -86
  66. data/lib/rservicebus/stats.rb +0 -68
  67. data/lib/rservicebus/subscription_manager.rb +0 -31
  68. data/lib/rservicebus/subscription_storage.rb +0 -39
  69. data/lib/rservicebus/subscription_storage/file.rb +0 -42
  70. data/lib/rservicebus/subscription_storage/redis.rb +0 -69
  71. data/lib/rservicebus/subscription_storage_configure.rb +0 -19
  72. data/lib/rservicebus/test.rb +0 -2
  73. data/lib/rservicebus/test/bus.rb +0 -32
  74. data/lib/rservicebus/transporter.rb +0 -142
  75. data/lib/rservicebus/usermessage/withpayload.rb +0 -10
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- rservicebus2 is copyrighted free software by all contributors, see logs in
1
+ RServiceBus is copyrighted free software by all contributors, see logs in
2
2
  revision control for names and email addresses of all of them.
3
3
 
4
4
  You can redistribute it and/or modify it under either the terms of the
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ #RServiceBus
2
+
3
+ A Ruby implementation of NServiceBus
4
+
5
+ Where I started this project to increase my knowledge of NServiceBus, it is now
6
+ proving to be a workable framework.
7
+
8
+
9
+ ##Principles
10
+ *Why are you doing it and what can go wrong
11
+ *Dont solve infrastructure problems with software
12
+ *Infrastructure in this case refers to anything not specific to the application domain
13
+
14
+ ##Points of view in the framework
15
+ * Bus
16
+ * Handler
17
+ * Client
18
+
19
+ #Platform
20
+ * Messages
21
+ * MessageHandler
22
+ * MessageHandling
23
+ * Queues
24
+ * Transport
25
+ * Transactions
26
+
27
+ ##Message
28
+ * Yaml
29
+ * Unique Message ID's
30
+
31
+ ##Queues
32
+ * Durable
33
+ * Store & Forward
34
+ * Queues specified by config, determined by message type
35
+
36
+ ##Transport
37
+ * RabbitMQ
38
+
39
+ ##MessageHandler
40
+ * Name by convention - Handler name matchs filename
41
+ * Handlers are dynamically loaded
42
+ * If a handler fails to load, the service wont start - infrastructure problem
43
+
44
+ ##MessageHandling
45
+ * Transactions are good, use them
46
+ * Given transactions, the first to do on error is retry
47
+ * Once we've used up retry, put the message on an error queue to process later - it's a logic problem
48
+
@@ -8,7 +8,8 @@ require 'rubygems'
8
8
  require 'rservicebus'
9
9
 
10
10
  def run_rservicebus()
11
- RServiceBus::Host.new().run()
11
+ RServiceBus::Host.new()
12
+ .run()
12
13
  end
13
14
 
14
15
  run_rservicebus
data/lib/rservicebus.rb CHANGED
@@ -1,59 +1,20 @@
1
- # Add the currently running directory to the start of the load path
2
- # $:.unshift File.dirname(__FILE__) + '/../../lib'
1
+ require "rubygems"
2
+ require 'beanstalk-client'
3
+ require "yaml"
4
+ require "uuidtools"
5
+ require "redis"
6
+ require "json"
7
+
8
+ require "rservicebus/helper_functions"
9
+ require "rservicebus/Agent"
10
+ require "rservicebus/ErrorMessage"
11
+ require "rservicebus/Message"
12
+ require "rservicebus/Subscription"
13
+ require "rservicebus/HandlerLoader"
14
+ require "rservicebus/Host"
3
15
 
4
- # Don't buffer stdout
5
- $stdout.sync = true
6
16
 
7
- require 'rubygems'
8
- require 'yaml'
9
- require 'uuidtools'
10
- require 'json'
11
- require 'uri'
12
-
13
- require 'rservicebus/helper_functions'
14
- require 'rservicebus/errormessage'
15
- require 'rservicebus/handler_loader'
16
- require 'rservicebus/handler_manager'
17
- require 'rservicebus/appresource_configure'
18
- require 'rservicebus/mq'
19
- require 'rservicebus/host'
20
- require 'rservicebus/config'
21
- require 'rservicebus/endpointmapping'
22
- require 'rservicebus/stats'
23
- require 'rservicebus/statistic_manager'
24
- require 'rservicebus/audit'
25
-
26
- require 'rservicebus/message'
27
- require 'rservicebus/message/subscription'
28
- require 'rservicebus/message/statisticoutput'
29
- require 'rservicebus/message/verboseoutput'
30
-
31
- require 'rservicebus/usermessage/withpayload'
32
-
33
- require 'rservicebus/state_manager'
34
- require 'rservicebus/cron_manager'
35
- require 'rservicebus/circuitbreaker'
36
-
37
- require 'rservicebus/appresource'
38
- require 'rservicebus/resource_manager'
39
-
40
- require 'rservicebus/subscription_manager'
41
- require 'rservicebus/subscription_storage'
42
- require 'rservicebus/subscription_storage_configure'
43
-
44
- require 'rservicebus/monitor_configure'
45
-
46
- require 'rservicebus/agent'
47
-
48
- require 'rservicebus/saga_loader.rb'
49
- require 'rservicebus/saga/manager.rb'
50
- require 'rservicebus/saga/data.rb'
51
- require 'rservicebus/saga/base.rb'
52
-
53
- require 'rservicebus/saga_storage'
17
+ module RServiceBus
54
18
 
55
- require 'rservicebus/sendat_manager'
56
19
 
57
- # Initial definition of the namespace
58
- module RServiceBus
59
20
  end
@@ -0,0 +1,21 @@
1
+ module RServiceBus
2
+ require 'beanstalk-client'
3
+
4
+ class Agent
5
+ @beanstalk
6
+
7
+ def initialize()
8
+ @beanstalk = Beanstalk::Pool.new(['localhost:11300'])
9
+ end
10
+
11
+ def sendMsg(messageObj, queueName, returnAddress=nil)
12
+ msg = RServiceBus::Message.new( messageObj, returnAddress )
13
+ serialized_object = YAML::dump(msg)
14
+
15
+ @beanstalk.use( queueName )
16
+ @beanstalk.put( serialized_object )
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,125 @@
1
+ module RServiceBus
2
+
3
+ class Config
4
+ #host:
5
+ ## @appName: CreateUser
6
+ ## errorQueueName: error
7
+ #
8
+
9
+ attr_reader :appName, :handlerPathList
10
+ @config
11
+ @appName
12
+
13
+ @handlerPathList
14
+
15
+ def getValue( name, default=nil )
16
+ if ENV[name].nil? then
17
+ return default
18
+ end
19
+
20
+ return ENV[name]
21
+ end
22
+
23
+ def loadMessageEndpointMappings( host )
24
+ mapping = self.getValue( "RSERVICEBUS_MESSAGEENDPOINTMAPPINGS" )
25
+
26
+ messageEndpointMappings=Hash.new
27
+ if !mapping.nil? then
28
+ mapping.split( ";" ).each do |line|
29
+ match = line.match( /(.+):(.+)/ )
30
+ messageEndpointMappings[match[0]] = match[1]
31
+ end
32
+ end
33
+
34
+ host.messageEndpointMappings=messageEndpointMappings
35
+ end
36
+
37
+ def loadHandlerPathList(host)
38
+ path = self.getValue( "RSERVICEBUS_MESSAGEHANDLERPATH", "MessageHandler" )
39
+
40
+ @handlerPathList = Array.new
41
+ path.split( ";" ).each do |path|
42
+ path = path.strip.chomp( "/" )
43
+ @handlerPathList << path
44
+ end
45
+
46
+ host.handlerPathList = @handlerPathList
47
+ end
48
+
49
+
50
+ def loadHostSection( host )
51
+ path = self.getValue( "RSERVICEBUS_APPNAME", "RServiceBus" )
52
+ localQueueName = self.getValue( "RSERVICEBUS_APPNAME", "RServiceBus" )
53
+ # @appName = self.getValue( "host", "appName", "RServiceBus" )
54
+ # host.appName = @appName
55
+ host.localQueueName = @appName
56
+ host.errorQueueName = self.getValue( "host", "errorQueueName", "error" )
57
+ host.maxRetries = self.getValue( "host", "maxRetries", 5 )
58
+ host.forwardReceivedMessagesTo = self.getValue( "host", "forwardReceivedMessagesTo", nil )
59
+
60
+ self.loadHandlerPathList(host)
61
+ end
62
+
63
+
64
+ def configureLogging( host )
65
+ logger = Logger.new "rservicebus." + @appName
66
+ loggingLevel = self.getLoggingLevel()
67
+
68
+ if self.getValue( "logger", "stdout", true ) != false then
69
+ Outputter.stdout.level = loggingLevel
70
+ logger.outputters = Outputter.stdout
71
+ end
72
+
73
+ fileName = self.getValue( "logger", "fileName", @appName + ".log" );
74
+ if fileName != false then
75
+ file = FileOutputter.new(@appName + ".file", :filename => fileName,:trunc => false)
76
+ file.level = loggingLevel
77
+ file.formatter = PatternFormatter.new(:pattern => self.getValue( "logger", "fileFormat", "[%l] %d :: %m" ))
78
+ logger.add( file )
79
+ end
80
+ host.logger = logger
81
+ end
82
+
83
+ def processConfig( host )
84
+ self.loadHostSection(host)
85
+ self.configureLogging(host)
86
+ self.loadMessageEndpointMappings( host )
87
+
88
+
89
+ return self
90
+ end
91
+
92
+ end
93
+
94
+
95
+ class ConfigFromFile<Config
96
+
97
+ def getConfigurationFilePath(configFilePath)
98
+ configFilePath = configFilePath.nil? ? "RServiceBus.yml" : configFilePath
99
+ if File.exists?(configFilePath) == false then
100
+ puts "Config file could not be found at: " + configFilePath
101
+ puts "(You can specifiy a config file with: ruby RServiceBus [your config file path]"
102
+ abort()
103
+ end
104
+
105
+ return configFilePath
106
+ end
107
+
108
+
109
+ def initialize(configFilePath )
110
+ configFilePath = self.getConfigurationFilePath(configFilePath)
111
+ @config = YAML.load_file(configFilePath)
112
+ end
113
+
114
+ end
115
+
116
+ class ConfigFromYAMLObject<Config
117
+
118
+ def initialize(config )
119
+ @config = config
120
+ end
121
+
122
+ end
123
+
124
+
125
+ end
@@ -0,0 +1,14 @@
1
+ module RServiceBus
2
+
3
+ class ErrorMessage
4
+
5
+ attr_reader :sourceQueue, :errorMsg
6
+
7
+ def initialize( sourceQueue, errorMsg )
8
+ @sourceQueue=sourceQueue
9
+ @errorMsg=errorMsg
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,100 @@
1
+ module RServiceBus
2
+
3
+ class HandlerLoader
4
+
5
+ attr_reader :messageName, :handler
6
+
7
+ @host
8
+
9
+ @baseDir
10
+ @filepath
11
+
12
+ @requirePath
13
+ @handlerName
14
+
15
+ @messageName
16
+ @handler
17
+
18
+ def initialize( baseDir, filePath, host )
19
+ @host = host
20
+
21
+ @baseDir = baseDir
22
+ @filePath = filePath
23
+ end
24
+
25
+ def getMessageName( baseDir, fileName )
26
+ name = fileName.sub( baseDir + "/", "" )
27
+ if name.count( "/" ) == 0 then
28
+ return name.match( /(.+)\./ )[1]
29
+ end
30
+
31
+ if name.count( "/" ) == 1 then
32
+ return name.match( /\/(.+)\./ )[1]
33
+ end
34
+
35
+ puts "Filepath, " + fileName + ", not in the expected format."
36
+ puts "Expected format either,"
37
+ puts "MessageHandler/Hello.rb, or"
38
+ puts "MessageHandler/Hello/One.rb, or"
39
+ abort();
40
+ end
41
+
42
+ def getRequirePath( filePath )
43
+ if File.exists?( filePath ) then
44
+ return filePath.sub( ".rb", "")
45
+ end
46
+
47
+ if File.exists?( "./" + filePath ) then
48
+ return "./" + filePath.sub( ".rb", "")
49
+ end
50
+
51
+ abort( "Filepath, " + filePath + ", given for MessageHandler require doesn't exist" );
52
+ end
53
+
54
+ def parseFilepath
55
+ @requirePath = self.getRequirePath( @filePath )
56
+ @messageName = self.getMessageName( @baseDir, @filePath )
57
+ @handlerName = @filePath.sub( ".rb", "").sub( @baseDir, "MessageHandler" ).gsub( "/", "_" )
58
+
59
+ puts @handlerName
60
+ puts @filePath + ":" + @messageName + ":" + @handlerName
61
+ end
62
+
63
+ def loadHandlerFromFile
64
+ require @requirePath
65
+ begin
66
+ @handler = Object.const_get(@handlerName).new();
67
+ rescue Exception => e
68
+ puts "Expected class name: " + @handlerName + ", not found after require: " + @requirePath
69
+ puts "**** Check in " + @filePath + " that the class is named : " + @handlerName
70
+ puts "( In case its not that )"
71
+ raise e
72
+ end
73
+ end
74
+
75
+ def setBusAttributeIfRequested
76
+ if defined?( @handler.Bus ) then
77
+ @handler.Bus = @host
78
+ puts "Bus attribute set for: " + @handlerName
79
+ end
80
+ end
81
+
82
+ def loadHandler()
83
+ begin
84
+ self.parseFilepath
85
+ self.loadHandlerFromFile
86
+ self.setBusAttributeIfRequested
87
+ puts "Loaded Handler: " + @handlerName + ", for, " + @messageName
88
+ rescue Exception => e
89
+ puts "Exception loading handler from file: " + @filePath
90
+ puts e.message
91
+ puts e.backtrace[0]
92
+
93
+ abort()
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ end
@@ -0,0 +1,340 @@
1
+ module RServiceBus
2
+
3
+ class Host
4
+
5
+ @appName
6
+
7
+ @handlerPathList
8
+ @handlerList
9
+
10
+ @errorQueueName
11
+ @maxRetries
12
+
13
+ @localQueueName
14
+
15
+ @forwardReceivedMessagesTo
16
+ @forwardReceivedMessagesToQueue
17
+
18
+ @messageEndpointMappings
19
+
20
+ @subscriptions
21
+
22
+ @beanstalk
23
+
24
+ @verbose
25
+
26
+ def log(string, ver=false)
27
+ type = ver ? "VERB" : "INFO"
28
+ if @verbose || !ver then
29
+ timestamp = Time.new.strftime( "%Y-%m-%d %H:%M:%S" )
30
+ puts "[#{type}] #{timestamp} :: #{string}"
31
+ end
32
+ end
33
+
34
+ def getValue( name, default=nil )
35
+ value = ENV["#{name}"].nil? ? default : ENV["#{name}"];
36
+ self.log "Env value: #{name}: #{value}", true
37
+ return value
38
+ end
39
+
40
+ def loadMessageEndpointMappings()
41
+ mapping = self.getValue( "MESSAGE_ENDPOINT_MAPPINGS" )
42
+
43
+ messageEndpointMappings=Hash.new
44
+ if !mapping.nil? then
45
+ mapping.split( ";" ).each do |line|
46
+ match = line.match( /(.+):(.+)/ )
47
+ messageEndpointMappings[match[0]] = match[1]
48
+ end
49
+ end
50
+
51
+ @messageEndpointMappings=messageEndpointMappings
52
+
53
+ return self
54
+ end
55
+
56
+ def loadHandlerPathList()
57
+ path = self.getValue( "MSGHANDLERPATH", "MessageHandler" )
58
+ handlerPathList = Array.new
59
+ path.split( ";" ).each do |path|
60
+ path = path.strip.chomp( "/" )
61
+ handlerPathList << path
62
+ end
63
+
64
+ @handlerPathList = handlerPathList
65
+
66
+ return self
67
+ end
68
+
69
+
70
+ def loadHostSection()
71
+ @appName = self.getValue( "APPNAME", "RServiceBus" )
72
+ @localQueueName = @appName
73
+ @errorQueueName = self.getValue( "ERROR_QUEUE_NAME", "error" )
74
+ @maxRetries = self.getValue( "MAX_RETRIES", "5" ).to_i
75
+ @forwardReceivedMessagesTo = self.getValue( "FORWARD_RECEIVED_MESSAGES_TO" )
76
+
77
+ return self
78
+ end
79
+
80
+ def loadContracts()
81
+ if self.getValue( "CONTRACTS" ).nil? then
82
+ return self
83
+ end
84
+
85
+ self.getValue( "CONTRACTS" ).split( ";" ) do |path|
86
+ require path
87
+ end
88
+ return self
89
+ end
90
+
91
+ def configureLogging()
92
+ @verbose = !self.getValue( "VERBOSE", nil ).nil?
93
+
94
+ return self
95
+ end
96
+
97
+ def configureBeanstalk
98
+ beanstalkHost = self.getValue( "BEANSTALK", "localhost:11300" )
99
+ @beanstalk = Beanstalk::Pool.new([beanstalkHost])
100
+
101
+ return self
102
+ end
103
+
104
+ def initialize()
105
+
106
+ self.loadHostSection()
107
+ .configureLogging()
108
+ .configureBeanstalk()
109
+ .loadContracts()
110
+ .loadMessageEndpointMappings()
111
+ .loadHandlerPathList()
112
+ .loadHandlers()
113
+ .loadSubscriptions()
114
+ .sendSubscriptions()
115
+
116
+ return self
117
+ end
118
+
119
+ def loadHandlersFromPath(baseDir, subDir="")
120
+ log "Load Message Handlers from baseDir, " + baseDir + ", subDir, " + subDir
121
+ log "Checking, " + baseDir, true
122
+
123
+ @handlerList = {};
124
+ Dir[baseDir + "/" + subDir + "*"].each do |filePath|
125
+ if !filePath.end_with?( "." ) then
126
+ log "Filepath, " + filePath, true
127
+
128
+ if File.directory?( filePath ) then
129
+ self.loadHandlersFromPath( filePath.sub( baseDir ) )
130
+ else
131
+ handlerLoader = HandlerLoader.new( baseDir, filePath, self )
132
+ handlerLoader.loadHandler
133
+
134
+ if !@handlerList.has_key?( handlerLoader.messageName ) then
135
+ @handlerList[handlerLoader.messageName] = Array.new
136
+ end
137
+
138
+ @handlerList[handlerLoader.messageName] << handlerLoader.handler;
139
+ end
140
+ end
141
+ end
142
+
143
+ return self
144
+ end
145
+
146
+ def loadHandlers()
147
+ log "Load Message Handlers"
148
+
149
+ @handlerPathList.each do |path|
150
+ self.loadHandlersFromPath(path)
151
+ end
152
+
153
+ return self
154
+ end
155
+
156
+ def sendSubscriptions
157
+ log "Send Subscriptions"
158
+ @messageEndpointMappings.each do |eventName,queueName|
159
+ log "Checking, " + eventName + " for Event", true
160
+ if eventName.end_with?( "Event" ) then
161
+ log eventName + ", is an event. About to send subscription to, " + queueName, true
162
+ self.Subscribe( eventName )
163
+ log "Subscribed to, " + eventName + " at, " + queueName
164
+ end
165
+ end
166
+
167
+ return self
168
+ end
169
+
170
+ def loadSubscriptions
171
+ log "Load subscriptions"
172
+ @subscriptions = Hash.new
173
+
174
+ redis = Redis.new
175
+
176
+ prefix = @appName + ".Subscriptions."
177
+ subscriptions = redis.keys prefix + "*Event"
178
+
179
+ subscriptions.each do |subscriptionName|
180
+ log "Loading subscription: " + subscriptionName, true
181
+ eventName = subscriptionName.sub( prefix, "" )
182
+ @subscriptions[eventName] = Array.new
183
+
184
+ log "Loading for event: " + eventName, true
185
+ subscription = redis.smembers subscriptionName
186
+ subscription.each do |subscriber|
187
+ log "Loading subscriber, " + subscriber + " for event, " + eventName, true
188
+ @subscriptions[eventName] << subscriber
189
+ end
190
+ end
191
+
192
+ return self
193
+ end
194
+
195
+ def addSubscrption( eventName, queueName )
196
+ log "Adding subscrption for, " + eventName + ", to, " + queueName
197
+ redis = Redis.new
198
+ key = @appName + ".Subscriptions." + eventName
199
+ redis.sadd key, queueName
200
+
201
+ if @subscriptions[eventName].nil? then
202
+ @subscriptions[eventName] = Array.new
203
+ end
204
+ @subscriptions[eventName] << queueName
205
+ end
206
+
207
+ def run
208
+ log "Starting the Host"
209
+
210
+ log "Watching, " + @localQueueName
211
+ @beanstalk.watch( @localQueueName )
212
+ if !@forwardReceivedMessagesTo.nil? then
213
+ log "Forwarding all received messages to: " + @forwardReceivedMessagesTo.to_s
214
+ end
215
+
216
+ self.StartListeningToEndpoints
217
+ end
218
+
219
+
220
+ def StartListeningToEndpoints
221
+ log "Waiting for messages. To exit press CTRL+C"
222
+
223
+ loop do
224
+ job = @beanstalk.reserve
225
+ body = job.body
226
+ retries = @maxRetries
227
+ begin
228
+ @msg = YAML::load(body)
229
+ if @msg.msg.class.name == "RServiceBus::Subscription" then
230
+ self.addSubscrption( @msg.msg.eventName, @msg.returnAddress )
231
+ else
232
+ self.HandleMessage()
233
+ if !@forwardReceivedMessagesTo.nil? then
234
+ self._SendAlreadyWrappedAndSerialised(body,@forwardReceivedMessagesTo)
235
+ end
236
+ end
237
+ job.delete
238
+ rescue Exception => e
239
+ retry if (retries -= 1) > 0
240
+
241
+ errorString = e.message + ". " + e.backtrace[0]
242
+ log errorString
243
+
244
+ @msg.addErrorMsg( @localQueueName, errorString )
245
+ serialized_object = YAML::dump(@msg)
246
+ self._SendAlreadyWrappedAndSerialised(serialized_object, @errorQueueName)
247
+ end
248
+ end
249
+ end
250
+
251
+ def HandleMessage()
252
+ msgName = @msg.msg.class.name
253
+ handlerList = @handlerList[msgName]
254
+
255
+ if handlerList == nil then
256
+ log "No handler found for: " + msgName
257
+ raise "No Handler Found"
258
+ else
259
+ log "Handler found for: " + msgName, true
260
+ handlerList.each do |handler|
261
+ begin
262
+ handler.Handle( @msg.msg )
263
+ rescue Exception => e
264
+ log "An error occured in Handler: " + handler.class.name
265
+ raise e
266
+ end
267
+ end
268
+ end
269
+ end
270
+
271
+ def _SendAlreadyWrappedAndSerialised( serialized_object, queueName )
272
+ log "Bus._SendAlreadyWrappedAndSerialised", true
273
+
274
+ @beanstalk.use( queueName )
275
+ @beanstalk.put( serialized_object )
276
+ end
277
+
278
+ def _SendNeedsWrapping( msg, queueName )
279
+ log "Bus._SendNeedsWrapping", true
280
+
281
+ rMsg = RServiceBus::Message.new( msg, @localQueueName )
282
+ serialized_object = YAML::dump(rMsg)
283
+ log "Sending: " + msg.class.name + " to: " + queueName, true
284
+ self._SendAlreadyWrappedAndSerialised( serialized_object, queueName )
285
+ end
286
+
287
+ def Reply( msg )
288
+ log "Reply with: " + msg.class.name + " To: " + @msg.returnAddress, true
289
+
290
+ self._SendNeedsWrapping( msg, @msg.returnAddress )
291
+ end
292
+
293
+
294
+ def Send( msg )
295
+ log "Bus.Send", true
296
+
297
+
298
+ msgName = msg.class.name
299
+ if !@messageEndpointMappings.has_key?( msgName ) then
300
+ log "No end point mapping found for: " + msgName
301
+ log "**** Check in RServiceBus.yml that the section MessageEndpointMappings contains an entry named : " + msgName
302
+ raise "No end point mapping found for: " + msgName
303
+ end
304
+
305
+ queueName = @messageEndpointMappings[msgName]
306
+
307
+ self._SendNeedsWrapping( msg, queueName )
308
+ end
309
+
310
+ def Publish( msg )
311
+ log "Bus.Publish", true
312
+
313
+
314
+ subscription = @subscriptions[msg.class.name]
315
+ if subscription.nil? then
316
+ log "No subscribers for event, " + msg.class.name
317
+ return
318
+ end
319
+
320
+ subscription.each do |subscriber|
321
+ self._SendNeedsWrapping( msg, subscriber )
322
+ end
323
+
324
+
325
+ end
326
+
327
+ def Subscribe( eventName )
328
+ log "Bus.Subscribe: " + eventName, true
329
+
330
+
331
+ queueName = @messageEndpointMappings[eventName]
332
+ subscription = Subscription.new( eventName )
333
+
334
+
335
+ self._SendNeedsWrapping( subscription, queueName )
336
+ end
337
+
338
+ end
339
+
340
+ end