rservicebus 0.0.01 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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