rservicebus 0.1.57 → 0.1.58

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rservicebus.rb CHANGED
@@ -35,6 +35,7 @@ require "rservicebus/CronManager"
35
35
  require "rservicebus/CircuitBreaker"
36
36
 
37
37
  require "rservicebus/AppResource"
38
+ require "rservicebus/ResourceManager"
38
39
 
39
40
  require "rservicebus/SubscriptionManager"
40
41
  require "rservicebus/SubscriptionStorage"
@@ -42,8 +43,14 @@ require "rservicebus/ConfigureSubscriptionStorage"
42
43
 
43
44
  require "rservicebus/ConfigureMonitor"
44
45
 
45
- require 'rservicebus/Agent'
46
+ require "rservicebus/Agent"
46
47
 
48
+ require "rservicebus/SagaLoader.rb"
49
+ require "rservicebus/Saga/Manager.rb"
50
+ require "rservicebus/Saga/Data.rb"
51
+ require "rservicebus/Saga/Base.rb"
52
+
53
+ require "rservicebus/SagaStorage"
47
54
 
48
55
  module RServiceBus
49
56
 
@@ -1,4 +1,5 @@
1
1
  require 'net/scp'
2
+ require 'net/sftp'
2
3
 
3
4
  module RServiceBus
4
5
 
@@ -19,10 +20,23 @@ module RServiceBus
19
20
  end
20
21
 
21
22
  end
22
-
23
+
23
24
  def close
24
25
  end
25
26
 
27
+ def delete( path, filepattern )
28
+ RServiceBus.log "Host: #{@uri.host}, User: #{@uri.user}, File Pattern: #{filepattern}, Destination: #{@uri.path}", true
29
+ Net::SSH.start( @uri.host, @uri.user ) do |ssh|
30
+ ssh.sftp.connect do |sftp|
31
+ files = sftp.dir.glob(path, filepattern)
32
+ sftp.dir.foreach(path){
33
+ |file|
34
+ sftp.remove("#{path}/#{file.name}")
35
+ }
36
+ end
37
+ end
38
+ end
39
+
26
40
  end
27
41
 
28
42
  class AppResource_ScpUpload<AppResource
@@ -2,11 +2,12 @@ module RServiceBus
2
2
 
3
3
  #Marshals configuration information for an rservicebus host
4
4
  class Config
5
- attr_reader :appName, :messageEndpointMappings, :handlerPathList, :errorQueueName, :maxRetries, :forwardReceivedMessagesTo, :subscriptionUri, :statOutputCountdown, :contractList, :libList, :forwardSentMessagesTo, :mqHost
5
+ attr_reader :appName, :messageEndpointMappings, :handlerPathList, :sagaPathList, :errorQueueName, :maxRetries, :forwardReceivedMessagesTo, :subscriptionUri, :statOutputCountdown, :contractList, :libList, :forwardSentMessagesTo, :mqHost
6
6
 
7
7
  @appName
8
8
  @messageEndpointMappings
9
9
  @handlerPathList
10
+ @sagaPathList
10
11
  @contractList
11
12
 
12
13
  @errorQueueName
@@ -50,14 +51,25 @@ module RServiceBus
50
51
 
51
52
  return self
52
53
  end
53
-
54
+
55
+ def loadSagaPathList()
56
+ path = self.getValue( "SAGAPATH", "./Saga" )
57
+ @sagaPathList = Array.new
58
+ path.split( ";" ).each do |path|
59
+ path = path.strip.chomp( "/" )
60
+ @sagaPathList << path
61
+ end
62
+
63
+ return self
64
+ end
65
+
54
66
  def loadHostSection()
55
67
  @appName = self.getValue( "APPNAME", "RServiceBus" )
56
68
  @errorQueueName = self.getValue( "ERROR_QUEUE_NAME", "error" )
57
69
  @maxRetries = self.getValue( "MAX_RETRIES", "5" ).to_i
58
70
  @statOutputCountdown = self.getValue( "STAT_OUTPUT_COUNTDOWN", "100" ).to_i
59
71
  @subscriptionUri = self.getValue( "SUBSCRIPTION_URI", "file:///tmp/#{appName}_subscriptions.yaml" )
60
-
72
+
61
73
  auditQueueName = self.getValue( "AUDIT_QUEUE_NAME" )
62
74
  if auditQueueName.nil? then
63
75
  @forwardSentMessagesTo = self.getValue( "FORWARD_SENT_MESSAGES_TO" )
@@ -66,22 +78,22 @@ module RServiceBus
66
78
  @forwardSentMessagesTo = auditQueueName
67
79
  @forwardReceivedMessagesTo = auditQueueName
68
80
  end
69
-
81
+
70
82
  return self
71
83
  end
72
84
 
73
85
  def ensureContractFileExists( path )
74
86
  if !( File.exists?( path ) ||
75
87
  File.exists?( "#{path}.rb" ) ) then
76
- puts "Error while processing contracts"
77
- puts "*** path, #{path}, provided does not exist as a file"
78
- abort()
88
+ puts "Error while processing contracts"
89
+ puts "*** path, #{path}, provided does not exist as a file"
90
+ abort()
79
91
  end
80
92
  if !( File.extname( path ) == "" ||
81
93
  File.extname( path ) == ".rb" ) then
82
- puts "Error while processing contracts"
83
- puts "*** path, #{path}, should point to a ruby file, with extention .rb"
84
- abort()
94
+ puts "Error while processing contracts"
95
+ puts "*** path, #{path}, should point to a ruby file, with extention .rb"
96
+ abort()
85
97
  end
86
98
  end
87
99
 
@@ -134,7 +146,7 @@ module RServiceBus
134
146
  end
135
147
  return self
136
148
  end
137
-
149
+
138
150
  def configureMq
139
151
  @mqHost = self.getValue( "MQ", "beanstalk://localhost" )
140
152
  return self
@@ -153,7 +165,7 @@ module RServiceBus
153
165
  pathList.split( ";" ).each do |path|
154
166
 
155
167
  path = path.strip.chomp( "/" )
156
-
168
+
157
169
  if !Dir.exists?( "#{path}" ) then
158
170
  puts "Error while processing working directory list"
159
171
  puts "*** path, #{path}, does not exist"
@@ -5,56 +5,57 @@ module RServiceBus
5
5
  #Configure AppResources for an rservicebus host
6
6
  class ConfigureAppResource
7
7
 
8
- def getResources( env, host )
9
- resources = Hash.new
8
+ def getResources( env, host, stateManager, sagaStorage )
9
+ resourceManager = ResourceManager.new( stateManager, sagaStorage )
10
+
10
11
 
11
12
  env.each do |k,v|
12
13
  if v.is_a?(String) and
13
14
  k.start_with?( "RSBFDB_" ) then
14
15
  uri = URI.parse( v )
15
16
  require "rservicebus/AppResource/FluidDb"
16
- resources[k.sub( "RSBFDB_", "" )] = AppResource_FluidDb.new( host, uri )
17
+ resourceManager.add k.sub( "RSBFDB_", "" ), AppResource_FluidDb.new( host, uri )
17
18
  elsif v.is_a?(String) and
18
19
  k.start_with?( "RSB_" ) then
19
20
  uri = URI.parse( v )
20
21
  case uri.scheme
21
22
  when "redis"
22
23
  require "rservicebus/AppResource/Redis"
23
- resources[k.sub( "RSB_", "" )] = AppResource_Redis.new( host, uri )
24
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_Redis.new( host, uri )
24
25
 
25
26
  when "mysql"
26
27
  require "rservicebus/AppResource/Mysql"
27
- resources[k.sub( "RSB_", "" )] = AppResource_Mysql.new( host, uri )
28
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_Mysql.new( host, uri )
28
29
 
29
30
  when "fluiddbmysql"
30
31
  require "rservicebus/AppResource/FluidDbMysql"
31
- resources[k.sub( "RSB_", "" )] = AppResource_FluidDbMysql.new( host, uri )
32
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_FluidDbMysql.new( host, uri )
32
33
  when "fluiddbmysql2"
33
34
  require "rservicebus/AppResource/FluidDbMysql2"
34
- resources[k.sub( "RSB_", "" )] = AppResource_FluidDbMysql2.new( host, uri )
35
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_FluidDbMysql2.new( host, uri )
35
36
  when "fluiddbpgsql"
36
37
  require "rservicebus/AppResource/FluidDbPgsql"
37
- resources[k.sub( "RSB_", "" )] = AppResource_FluidDbPgsql.new( host, uri )
38
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_FluidDbPgsql.new( host, uri )
38
39
  when "fluiddbtinytds"
39
40
  require "rservicebus/AppResource/FluidDbTinyTds"
40
- resources[k.sub( "RSB_", "" )] = AppResource_FluidDbTinyTds.new( host, uri )
41
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_FluidDbTinyTds.new( host, uri )
41
42
 
42
43
  when "fluiddbfirebird"
43
44
  require "rservicebus/AppResource/FluidDbFirebird"
44
- resources[k.sub( "RSB_", "" )] = AppResource_FluidDbFirebird.new( host, uri )
45
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_FluidDbFirebird.new( host, uri )
45
46
 
46
47
  when "dir"
47
48
  require "rservicebus/AppResource/Dir"
48
- resources[k.sub( "RSB_", "" )] = AppResource_Dir.new( host, uri )
49
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_Dir.new( host, uri )
49
50
  when "file"
50
51
  require "rservicebus/AppResource/File"
51
- resources[k.sub( "RSB_", "" )] = AppResource_File.new( host, uri )
52
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_File.new( host, uri )
52
53
  when "scpupload"
53
54
  require "rservicebus/AppResource/ScpUpload"
54
- resources[k.sub( "RSB_", "" )] = AppResource_ScpUpload.new( host, uri )
55
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_ScpUpload.new( host, uri )
55
56
  when "smbfile"
56
57
  require "rservicebus/AppResource/SmbFile"
57
- resources[k.sub( "RSB_", "" )] = AppResource_SmbFile.new( host, uri )
58
+ resourceManager.add k.sub( "RSB_", "" ), AppResource_SmbFile.new( host, uri )
58
59
  else
59
60
  abort("Scheme, #{uri.scheme}, not recognised when configuring app resource, #{k}=#{v}");
60
61
  end
@@ -62,7 +63,7 @@ module RServiceBus
62
63
 
63
64
  end
64
65
 
65
- return resources
66
+ return resourceManager
66
67
  end
67
68
 
68
69
  end
@@ -3,7 +3,7 @@ module RServiceBus
3
3
  require 'rservicebus/Monitor'
4
4
  require 'rservicebus/Monitor/Message'
5
5
 
6
- #Configure AppResources for an rservicebus host
6
+ #Configure Monitors for an rservicebus host
7
7
  class ConfigureMonitor
8
8
 
9
9
  @resourceList
@@ -11,10 +11,10 @@ module RServiceBus
11
11
  # Constructor
12
12
  #
13
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 )
14
+ # @param [Hash] resourceManager As hash[k,v] where k is the name of a resource, and v is the resource
15
+ def initialize( host, resourceManager )
16
16
  @host = host
17
- @appResources = appResources
17
+ @resourceManager = resourceManager
18
18
 
19
19
  @handlerList = Hash.new
20
20
  @resourceList = Hash.new
@@ -23,11 +23,10 @@ module RServiceBus
23
23
  # Assigns appropriate resources to writable attributes in the handler that match keys in the resource hash
24
24
  #
25
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
26
  def setAppResources( monitor )
28
27
  RServiceBus.rlog "Checking app resources for: #{monitor.class.name}"
29
28
  RServiceBus.rlog "If your attribute is not getting set, check that it is in the 'attr_accessor' list"
30
- @appResources.each do |k,v|
29
+ @resourceManager.getAll.each do |k,v|
31
30
  if monitor.class.method_defined?( k ) then
32
31
  monitor.instance_variable_set( "@#{k}", v.getResource() )
33
32
  @resourceList[monitor.class.name] = Array.new if @resourceList[monitor.class.name].nil?
@@ -10,9 +10,9 @@ module RServiceBus
10
10
  #
11
11
  # @param [RServiceBus::Host] host instance
12
12
  # @param [Hash] appResources As hash[k,v] where k is the name of a resource, and v is the resource
13
- def initialize( host, appResources, stateManager )
13
+ def initialize( host, resourceManager, stateManager )
14
14
  @host = host
15
- @appResources = appResources
15
+ @resourceManager = resourceManager
16
16
  @stateManager = stateManager
17
17
 
18
18
  @handlerList = Hash.new
@@ -56,9 +56,9 @@ module RServiceBus
56
56
  def interrogateHandlerForAppResources( handler )
57
57
  RServiceBus.rlog "Checking app resources for: #{handler.class.name}"
58
58
  RServiceBus.rlog "If your attribute is not getting set, check that it is in the 'attr_accessor' list"
59
-
59
+
60
60
  @resourceListByHandlerName[handler.class.name] = Array.new
61
- @appResources.each do |k,v|
61
+ @resourceManager.getAll.each do |k,v|
62
62
  if handler.class.method_defined?( k ) then
63
63
  @resourceListByHandlerName[handler.class.name] << k
64
64
  RServiceBus.log "Resource attribute, #{k}, found for: " + handler.class.name
@@ -78,26 +78,13 @@ module RServiceBus
78
78
  self.interrogateHandlerForAppResources( handler )
79
79
  end
80
80
 
81
- # Assigns appropriate resources to writable attributes in the handler that match keys in the resource hash
81
+ # As named
82
82
  #
83
- # @param [RServiceBus::Handler] handler
84
- ## @param [Hash] appResources As hash[k,v] where k is the name of a resource, and v is the resource
85
- def setAppResources_to_be_removed( handler )
86
- RServiceBus.rlog "Checking app resources for: #{handler.class.name}"
87
- RServiceBus.rlog "If your attribute is not getting set, check that it is in the 'attr_accessor' list"
88
- @appResources.each do |k,v|
89
- if handler.class.method_defined?( k ) then
90
- v._connect
91
- # v.Begin
92
- handler.instance_variable_set( "@#{k}", v.getResource() )
93
- RServiceBus.log "App resource attribute, #{k}, set for: " + handler.class.name
94
- end
95
- end
96
-
97
- return self
98
- end
99
-
83
+ # @param [String] msgName
84
+ ## @param [Array] appResources A list of appResource
100
85
  def getListOfResourcesNeededToProcessMsg( msgName )
86
+ return Array.new if @handlerList[msgName].nil?
87
+
101
88
  list = Array.new
102
89
  @handlerList[msgName].each do |handler|
103
90
  list = list + @resourceListByHandlerName[handler.class.name] unless @resourceListByHandlerName[handler.class.name].nil?
@@ -106,14 +93,14 @@ module RServiceBus
106
93
 
107
94
  return list
108
95
  end
109
-
96
+
110
97
  def setResourcesForHandlersNeededToProcessMsg( msgName )
111
98
  @handlerList[msgName].each do |handler|
112
99
  self.setStateAttributeIfRequested( handler )
113
100
 
114
101
  next if @resourceListByHandlerName[handler.class.name].nil?
115
102
  @resourceListByHandlerName[handler.class.name].each do |k|
116
- handler.instance_variable_set( "@#{k}", @appResources[k].getResource() )
103
+ handler.instance_variable_set( "@#{k}", @resourceManager.get(k).getResource() )
117
104
  RServiceBus.rlog "App resource attribute, #{k}, set for: " + handler.class.name
118
105
  end
119
106
  end
@@ -121,54 +108,16 @@ module RServiceBus
121
108
  end
122
109
 
123
110
  def getHandlerListForMsg( msgName )
124
- raise NoHandlerFound.new( msgName ) if @handlerList[msgName].nil?
125
-
126
- @stateManager.Begin
111
+ # raise NoHandlerFound.new( msgName ) if @handlerList[msgName].nil?
112
+ return Array.new if @handlerList[msgName].nil?
113
+
114
+
127
115
  list = self.getListOfResourcesNeededToProcessMsg( msgName )
128
- list.each do |resourceName|
129
- r = @appResources[resourceName]
130
- r._connect
131
- r.Begin
132
- RServiceBus.rlog "Preparing resource: #{resourceName}. Begin"
133
- end
134
-
135
116
  self.setResourcesForHandlersNeededToProcessMsg( msgName )
136
117
 
137
118
  return @handlerList[msgName]
138
119
  end
139
120
 
140
- def commitResourcesUsedToProcessMsg( msgName )
141
- RServiceBus.rlog "HandlerManager.commitResourcesUsedToProcessMsg, #{msgName}"
142
- list = self.getListOfResourcesNeededToProcessMsg( msgName )
143
- list.each do |resourceName|
144
- r = @appResources[resourceName]
145
- RServiceBus.rlog "Commit resource, #{r.class.name}"
146
- r.Commit
147
- r.finished
148
- end
149
- @stateManager.Commit
150
- end
151
-
152
- def rollbackResourcesUsedToProcessMsg( msgName )
153
- RServiceBus.rlog "HandlerManager.rollbackResourcesUsedToProcessMsg, #{msgName}"
154
- list = self.getListOfResourcesNeededToProcessMsg( msgName )
155
- list.each do |resourceName|
156
- begin
157
- r = @appResources[resourceName]
158
- RServiceBus.rlog "Rollback resource, #{r.class.name}"
159
- r.Rollback
160
- r.finished
161
- rescue Exception => e1
162
- @host.log "Caught nested exception rolling back, #{r.class.name}, for msg, #{msgName}"
163
- @host.log "****"
164
- @host.log e1.message
165
- @host.log e1.backtrace
166
- @host.log "****"
167
- end
168
- end
169
-
170
- end
171
-
172
121
  def canMsgBeHandledLocally( msgName )
173
122
  return @handlerList.has_key?(msgName)
174
123
  end
@@ -9,9 +9,12 @@ module RServiceBus
9
9
  end
10
10
  class PropertyNotSet<StandardError
11
11
  end
12
-
12
+
13
13
  #Host process for rservicebus
14
14
  class Host
15
+ attr_accessor :sagaData
16
+
17
+ @sagaData
15
18
 
16
19
  @handlerList
17
20
  @resourceListByHandlerName
@@ -20,7 +23,7 @@ module RServiceBus
20
23
 
21
24
  @mq
22
25
 
23
- @appResources
26
+ @resourceManager
24
27
 
25
28
  @config
26
29
 
@@ -30,8 +33,8 @@ module RServiceBus
30
33
 
31
34
 
32
35
  @queueForMsgsToBeSentOnComplete
33
-
34
-
36
+
37
+
35
38
  #Provides a thin logging veneer
36
39
  #
37
40
  # @param [String] string Log entry
@@ -39,11 +42,11 @@ module RServiceBus
39
42
  def log(string, ver=false)
40
43
  RServiceBus.log( string, ver )
41
44
  end
42
-
45
+
43
46
  #Thin veneer for Configuring external resources
44
47
  #
45
48
  def configureAppResource
46
- @appResources = ConfigureAppResource.new.getResources( ENV, self )
49
+ @resourceManager = ConfigureAppResource.new.getResources( ENV, self, @stateManager, @sagaStorage )
47
50
  return self;
48
51
  end
49
52
 
@@ -54,18 +57,31 @@ module RServiceBus
54
57
  return self;
55
58
  end
56
59
 
60
+ #Thin veneer for Configuring state
61
+ #
62
+ def configureSagaStorage
63
+ string = RServiceBus.getValue( "SAGA_URI" )
64
+ if string.nil? then
65
+ string = "dir:///tmp"
66
+ end
67
+
68
+ uri = URI.parse( string )
69
+ @sagaStorage = SagaStorage.Get( uri )
70
+ return self;
71
+ end
72
+
57
73
  #Thin veneer for Configuring Cron
58
74
  #
59
75
  def configureCircuitBreaker
60
76
  @circuitBreaker = CircuitBreaker.new( self )
61
77
  return self;
62
78
  end
63
-
64
-
79
+
80
+
65
81
  #Thin veneer for Configuring external resources
66
82
  #
67
83
  def configureMonitors
68
- @monitors = ConfigureMonitor.new( self, @appResources ).getMonitors( ENV )
84
+ @monitors = ConfigureMonitor.new( self, @resourceManager ).getMonitors( ENV )
69
85
  return self;
70
86
  end
71
87
 
@@ -81,9 +97,9 @@ module RServiceBus
81
97
  #msg endpoint mapping
82
98
  def sendSubscriptions
83
99
  log "Send Subscriptions"
84
-
100
+
85
101
  @endpointMapping.getSubscriptionEndpoints.each { |eventName| self.Subscribe( eventName ) }
86
-
102
+
87
103
  return self
88
104
  end
89
105
 
@@ -91,7 +107,7 @@ module RServiceBus
91
107
  #
92
108
  def loadHandlers()
93
109
  log "Load Message Handlers"
94
- @handlerManager = HandlerManager.new( self, @appResources, @stateManager )
110
+ @handlerManager = HandlerManager.new( self, @resourceManager, @stateManager )
95
111
  @handlerLoader = HandlerLoader.new( self, @handlerManager )
96
112
 
97
113
  @config.handlerPathList.each do |path|
@@ -101,6 +117,19 @@ module RServiceBus
101
117
  return self
102
118
  end
103
119
 
120
+ #Load and configure Sagas
121
+ def loadSagas()
122
+ log "Load Sagas"
123
+ @sagaManager = Saga_Manager.new( self, @resourceManager, @sagaStorage )
124
+ @sagaLoader = SagaLoader.new( self, @sagaManager )
125
+
126
+ @config.sagaPathList.each do |path|
127
+ @sagaLoader.loadSagasFromPath(path)
128
+ end
129
+
130
+ return self
131
+ end
132
+
104
133
  #Thin veneer for Configuring Cron
105
134
  #
106
135
  def configureCronManager
@@ -155,25 +184,28 @@ module RServiceBus
155
184
  .loadHostSection()
156
185
  .loadContracts()
157
186
  .loadHandlerPathList()
187
+ .loadSagaPathList()
158
188
  .loadLibs()
159
189
  .loadWorkingDirList();
160
-
190
+
161
191
  self.connectToMq()
162
-
192
+
163
193
  @endpointMapping = EndpointMapping.new.Configure( @mq.localQueueName )
164
194
 
165
195
  self.configureStatistics()
166
196
  .loadContracts()
167
197
  .loadLibs()
168
- .configureAppResource()
169
198
  .configureStateManager()
199
+ .configureSagaStorage()
200
+ .configureAppResource()
170
201
  .configureCircuitBreaker()
171
202
  .configureMonitors()
172
203
  .loadHandlers()
204
+ .loadSagas()
173
205
  .configureCronManager()
174
206
  .configureSubscriptions()
175
207
  .sendSubscriptions()
176
-
208
+
177
209
 
178
210
  return self
179
211
  end
@@ -202,7 +234,7 @@ module RServiceBus
202
234
  # statOutputCountdown = 0
203
235
  messageLoop = true
204
236
  retries = @config.maxRetries
205
-
237
+
206
238
  while messageLoop do
207
239
  #Popping a msg off the queue should not be in the message handler, as it affects retry
208
240
  begin
@@ -219,10 +251,10 @@ module RServiceBus
219
251
  @msg = YAML::load(body)
220
252
  if @msg.msg.class.name == "RServiceBus::Message_Subscription" then
221
253
  @subscriptionManager.add( @msg.msg.eventName, @msg.returnAddress )
222
- elsif @msg.msg.class.name == "RServiceBus::Message_StatisticOutputOn" then
254
+ elsif @msg.msg.class.name == "RServiceBus::Message_StatisticOutputOn" then
223
255
  @stats.output = true
224
256
  log "Turn on Stats logging"
225
- elsif @msg.msg.class.name == "RServiceBus::Message_StatisticOutputOff" then
257
+ elsif @msg.msg.class.name == "RServiceBus::Message_StatisticOutputOff" then
226
258
  @stats.output = false
227
259
  log "Turn off Stats logging"
228
260
  elsif @msg.msg.class.name == "RServiceBus::Message_VerboseOutputOn" then
@@ -231,10 +263,12 @@ module RServiceBus
231
263
  elsif @msg.msg.class.name == "RServiceBus::Message_VerboseOutputOff" then
232
264
  ENV.delete( "VERBOSE" )
233
265
  log "Turn off Verbose logging"
234
-
235
-
266
+
267
+
236
268
  else
269
+
237
270
  self.HandleMessage()
271
+
238
272
  if !@config.forwardReceivedMessagesTo.nil? then
239
273
  self._SendAlreadyWrappedAndSerialised(body,@config.forwardReceivedMessagesTo)
240
274
  end
@@ -248,11 +282,11 @@ module RServiceBus
248
282
  serialized_object = YAML::dump(@msg)
249
283
  self._SendAlreadyWrappedAndSerialised(serialized_object, @config.errorQueueName)
250
284
  @mq.ack
251
-
285
+
252
286
  rescue NoHandlerFound => e
253
287
  puts "*** Handler not found for msg, #{e.message}"
254
288
  puts "*** Ensure a handler named, #{e.message}, is present in the MessageHandler directory."
255
-
289
+
256
290
  @msg.addErrorMsg( @mq.localQueueName, e.message )
257
291
  serialized_object = YAML::dump(@msg)
258
292
  self._SendAlreadyWrappedAndSerialised(serialized_object, @config.errorQueueName)
@@ -279,7 +313,7 @@ module RServiceBus
279
313
  else
280
314
 
281
315
  @circuitBreaker.Failure
282
-
316
+
283
317
  @stats.incTotalErrored
284
318
  if e.class.name == "Beanstalk::NotConnected" then
285
319
  puts "Lost connection to beanstalkd."
@@ -342,13 +376,15 @@ module RServiceBus
342
376
  #Send the current msg to the appropriate handlers
343
377
  #
344
378
  def HandleMessage()
379
+ @resourceManager.Begin
345
380
  msgName = @msg.msg.class.name
346
381
  handlerList = @handlerManager.getHandlerListForMsg(msgName)
347
382
 
383
+
348
384
  RServiceBus.rlog "Handler found for: " + msgName
349
385
  begin
350
386
  @queueForMsgsToBeSentOnComplete = Array.new
351
-
387
+
352
388
  log "Started processing msg, #{msgName}"
353
389
  handlerList.each do |handler|
354
390
  begin
@@ -356,50 +392,60 @@ module RServiceBus
356
392
  handler.Handle( @msg.msg )
357
393
  log "Handler, #{handler.class.name}, Finished"
358
394
  rescue PropertyNotSet => e
359
- raise PropertyNotSet.new( "Property, #{e.message}, not set for, #{handler.class.name}" )
395
+ raise PropertyNotSet.new( "Property, #{e.message}, not set for, #{handler.class.name}" )
360
396
  rescue Exception => e
361
397
  puts "E #{e.message}"
362
398
  log "An error occurred in Handler: " + handler.class.name
363
399
  raise e
364
400
  end
365
401
  end
366
-
367
- @handlerManager.commitResourcesUsedToProcessMsg( msgName )
402
+
403
+
404
+ if @sagaManager.Handle( @msg ) == false then
405
+ raise NoHandlerFound.new( msgName ) if handlerList.length == 0
406
+ end
407
+
408
+
409
+
410
+ @resourceManager.Commit( msgName )
368
411
 
369
412
  self.sendQueuedMsgs
370
413
  log "Finished processing msg, #{msgName}"
371
414
 
372
415
  rescue Exception => e
373
416
 
374
- @handlerManager.rollbackResourcesUsedToProcessMsg( msgName )
417
+ @resourceManager.Rollback( msgName )
375
418
  @queueForMsgsToBeSentOnComplete = nil
376
419
 
377
420
  raise e
378
421
  end
379
422
  end
380
423
 
424
+ #######################################################################################################
425
+ # All msg sending Methods
426
+
381
427
  #Sends a msg across the bus
382
428
  #
383
429
  # @param [String] serialized_object serialized RServiceBus::Message
384
430
  # @param [String] queueName endpoint to which the msg will be sent
385
431
  def _SendAlreadyWrappedAndSerialised( serialized_object, queueName )
386
432
  RServiceBus.rlog "Bus._SendAlreadyWrappedAndSerialised"
387
-
433
+
388
434
  if !@config.forwardSentMessagesTo.nil? then
389
435
  @mq.send( @config.forwardSentMessagesTo, serialized_object )
390
436
  end
391
-
437
+
392
438
  @mq.send( queueName, serialized_object )
393
439
  end
394
-
440
+
395
441
  #Sends a msg across the bus
396
442
  #
397
443
  # @param [RServiceBus::Message] msg msg to be sent
398
444
  # @param [String] queueName endpoint to which the msg will be sent
399
- def _SendNeedsWrapping( msg, queueName )
445
+ def _SendNeedsWrapping( msg, queueName, correlationId )
400
446
  RServiceBus.rlog "Bus._SendNeedsWrapping"
401
-
402
- rMsg = RServiceBus::Message.new( msg, @mq.localQueueName )
447
+
448
+ rMsg = RServiceBus::Message.new( msg, @mq.localQueueName, correlationId )
403
449
  if queueName.index( "@" ).nil? then
404
450
  q = queueName
405
451
  RServiceBus.rlog "Sending, #{msg.class.name} to, queueName"
@@ -410,19 +456,21 @@ module RServiceBus
410
456
  q = 'transport-out'
411
457
  RServiceBus.rlog "Sending, #{msg.class.name} to, #{queueName}, via #{q}"
412
458
  end
413
-
459
+
414
460
  serialized_object = YAML::dump(rMsg)
415
461
  self._SendAlreadyWrappedAndSerialised( serialized_object, q )
416
462
  end
417
-
463
+
418
464
  def sendQueuedMsgs
419
465
  @queueForMsgsToBeSentOnComplete.each do |row|
420
- self._SendNeedsWrapping( row["msg"], row["queueName"] )
466
+ self._SendNeedsWrapping( row["msg"], row["queueName"], row["correlationId"] )
421
467
  end
422
468
  end
423
469
 
424
470
  def queueMsgForSendOnComplete( msg, queueName )
425
- @queueForMsgsToBeSentOnComplete << Hash["msg", msg, "queueName", queueName]
471
+ correlationId = sagaData.nil? ? nil : sagaData.correlationId
472
+ correlationId = @msg.correlationId.nil? ? correlationId : @msg.correlationId
473
+ @queueForMsgsToBeSentOnComplete << Hash["msg", msg, "queueName", queueName, "correlationId", correlationId]
426
474
  end
427
475
 
428
476
  #Sends a msg back across the bus
@@ -433,7 +481,7 @@ module RServiceBus
433
481
  def Reply( msg )
434
482
  RServiceBus.rlog "Reply with: " + msg.class.name + " To: " + @msg.returnAddress
435
483
  @stats.incTotalReply
436
-
484
+
437
485
  self.queueMsgForSendOnComplete( msg, @msg.returnAddress )
438
486
  end
439
487
 
@@ -447,8 +495,8 @@ module RServiceBus
447
495
  log "**** Check environment variable MessageEndpointMappings contains an entry named : " + msgName
448
496
  raise "No end point mapping found for: " + msgName
449
497
  end
450
-
451
-
498
+
499
+
452
500
  #Send a msg across the bus
453
501
  #msg destination is specified at the infrastructure level
454
502
  #
@@ -482,7 +530,7 @@ module RServiceBus
482
530
  # @param [String] eventName event to be subscribes to
483
531
  def Subscribe( eventName )
484
532
  RServiceBus.rlog "Bus.Subscribe: " + eventName
485
-
533
+
486
534
  queueName = self.getEndpointForMsg( eventName )
487
535
  subscription = Message_Subscription.new( eventName )
488
536