torquebox-messaging 2.3.2-java → 3.0.0.beta1-java
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/hornetq-commons-2.3.0.CR1.jar +0 -0
- data/lib/hornetq-core-client-2.3.0.CR1.jar +0 -0
- data/lib/hornetq-jms-client-2.3.0.CR1.jar +0 -0
- data/lib/hornetq-journal-2.3.0.CR1.jar +0 -0
- data/lib/jboss-logging-3.1.2.GA.jar +0 -0
- data/lib/jboss-logmanager-1.4.0.Final.jar +0 -0
- data/lib/netty-3.6.2.Final.jar +0 -0
- data/lib/torquebox/messaging/backgroundable.rb +16 -8
- data/lib/torquebox/messaging/backgroundable_processor.rb +2 -1
- data/lib/torquebox/messaging/connection.rb +21 -74
- data/lib/torquebox/messaging/connection_factory.rb +52 -13
- data/lib/torquebox/messaging/datamapper_marshaling.rb +1 -0
- data/lib/torquebox/messaging/destination.rb +77 -8
- data/lib/torquebox/messaging/echo_processor.rb +1 -0
- data/lib/torquebox/messaging/edn_message.rb +0 -11
- data/lib/torquebox/messaging/future_responder.rb +2 -2
- data/lib/torquebox/messaging/json_message.rb +0 -24
- data/lib/torquebox/messaging/marshal_base64_message.rb +0 -18
- data/lib/torquebox/messaging/marshal_message.rb +4 -5
- data/lib/torquebox/messaging/message.rb +10 -0
- data/lib/torquebox/messaging/message_processor.rb +162 -3
- data/lib/torquebox/messaging/processor_middleware/chain.rb +1 -0
- data/lib/torquebox/messaging/processor_middleware/default_middleware.rb +1 -0
- data/lib/torquebox/messaging/processor_middleware/with_transaction.rb +1 -0
- data/lib/torquebox/messaging/queue.rb +210 -41
- data/lib/torquebox/messaging/session.rb +4 -8
- data/lib/torquebox/messaging/task.rb +8 -6
- data/lib/torquebox/messaging/topic.rb +23 -11
- data/lib/torquebox/messaging/xa_connection.rb +22 -25
- data/lib/torquebox/messaging/xa_connection_factory.rb +2 -17
- data/lib/torquebox/messaging/xa_session.rb +21 -0
- data/lib/torquebox-messaging.jar +0 -0
- data/lib/torquebox-messaging.rb +9 -5
- data/licenses/cc0-1.0.txt +121 -0
- data/spec/backgroundable_spec.rb +21 -0
- data/spec/destination_spec.rb +81 -14
- data/spec/message_processor_spec.rb +151 -1
- data/spec/task_spec.rb +8 -1
- metadata +51 -65
- data/lib/hornetq-core-2.2.21.Final.jar +0 -0
- data/lib/hornetq-jms-2.2.21.Final.jar +0 -0
- data/lib/netty-3.2.6.Final.jar +0 -0
- data/licenses/lgpl-2.1.txt +0 -502
- data/spec/json_message_spec.rb +0 -50
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -28,10 +28,13 @@ module TorqueBox
|
|
28
28
|
# Backgroundable provides mechanism for executing an object's
|
29
29
|
# methods asynchronously.
|
30
30
|
module Backgroundable
|
31
|
+
# @!parse extend BackgroundableClassMethods
|
32
|
+
|
33
|
+
# @api private
|
31
34
|
MUTEX = Mutex.new
|
32
35
|
|
33
36
|
def self.included(base)
|
34
|
-
base.extend(
|
37
|
+
base.extend(BackgroundableClassMethods)
|
35
38
|
base.extend(FutureStatus)
|
36
39
|
base.send(:include, FutureStatus)
|
37
40
|
end
|
@@ -42,7 +45,7 @@ module TorqueBox
|
|
42
45
|
end
|
43
46
|
|
44
47
|
# Allows you to background any method that has not been marked
|
45
|
-
# as a backgrounded method via {
|
48
|
+
# as a backgrounded method via {BackgroundableClassMethods#always_background}.
|
46
49
|
# @param [Hash] options that are passed through to
|
47
50
|
# {TorqueBox::Messaging::Destination#publish}
|
48
51
|
# @return [Future]
|
@@ -50,7 +53,7 @@ module TorqueBox
|
|
50
53
|
BackgroundProxy.new(self, options)
|
51
54
|
end
|
52
55
|
|
53
|
-
module
|
56
|
+
module BackgroundableClassMethods
|
54
57
|
|
55
58
|
# Marks methods to always be backgrounded. Takes one or more
|
56
59
|
# method symbols, and an optional options hash as the final
|
@@ -75,7 +78,7 @@ module TorqueBox
|
|
75
78
|
end
|
76
79
|
|
77
80
|
# Allows you to background any method that has not been marked
|
78
|
-
# as a backgrounded method via {
|
81
|
+
# as a backgrounded method via {BackgroundableClassMethods#always_background}.
|
79
82
|
# @param [Hash] options that are passed through to
|
80
83
|
# {TorqueBox::Messaging::Destination#publish}
|
81
84
|
# @return [Future]
|
@@ -83,16 +86,19 @@ module TorqueBox
|
|
83
86
|
BackgroundProxy.new(self, options)
|
84
87
|
end
|
85
88
|
|
89
|
+
# @api private
|
86
90
|
def method_added(method)
|
87
91
|
super
|
88
92
|
__method_added(method)
|
89
93
|
end
|
90
94
|
|
95
|
+
# @api private
|
91
96
|
def singleton_method_added(method)
|
92
97
|
super
|
93
98
|
__method_added(method)
|
94
99
|
end
|
95
100
|
|
101
|
+
# @api private
|
96
102
|
def __enable_backgroundable_newrelic_tracing(method)
|
97
103
|
method = method.to_s
|
98
104
|
if Backgroundable.newrelic_available?
|
@@ -170,6 +176,7 @@ module TorqueBox
|
|
170
176
|
|
171
177
|
end
|
172
178
|
|
179
|
+
# @api private
|
173
180
|
class BackgroundProxy
|
174
181
|
def initialize(receiver, options)
|
175
182
|
@receiver = receiver
|
@@ -183,9 +190,9 @@ module TorqueBox
|
|
183
190
|
end
|
184
191
|
end
|
185
192
|
|
193
|
+
# @api private
|
186
194
|
module Util
|
187
|
-
|
188
|
-
|
195
|
+
|
189
196
|
class << self
|
190
197
|
def publish_message(receiver, method, args, options = { })
|
191
198
|
queue_name = Task.queue_name( "torquebox_backgroundable" )
|
@@ -195,9 +202,10 @@ module TorqueBox
|
|
195
202
|
queue.publish( {:receiver => receiver,
|
196
203
|
:future_id => future.correlation_id,
|
197
204
|
:future_queue => queue_name,
|
205
|
+
:future_ttl => options[:future_ttl],
|
198
206
|
:method => method,
|
199
207
|
:args => args}, options )
|
200
|
-
|
208
|
+
|
201
209
|
future
|
202
210
|
rescue javax.jms.InvalidDestinationException => ex
|
203
211
|
raise RuntimeError.new("The Backgroundable queue is not available. Did you disable it by setting its concurrency to 0?")
|
@@ -230,7 +238,7 @@ module TorqueBox
|
|
230
238
|
end
|
231
239
|
|
232
240
|
def methods_include?(methods, method)
|
233
|
-
method = (RUBY_VERSION =~ /^1\.
|
241
|
+
method = (RUBY_VERSION =~ /^1\.8\./ ? method.to_s : method.to_sym)
|
234
242
|
methods.include?(method)
|
235
243
|
end
|
236
244
|
end
|
@@ -21,6 +21,7 @@ require 'torquebox/messaging/future_responder'
|
|
21
21
|
|
22
22
|
module TorqueBox
|
23
23
|
module Messaging
|
24
|
+
# @api private
|
24
25
|
class BackgroundableProcessor < MessageProcessor
|
25
26
|
|
26
27
|
def self.log_newrelic_notice(klass)
|
@@ -30,7 +31,7 @@ module TorqueBox
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def on_message(hash)
|
33
|
-
FutureResponder.new( Queue.new( hash[:future_queue] ), hash[:future_id] ).respond do
|
34
|
+
FutureResponder.new( Queue.new( hash[:future_queue] ), hash[:future_id], hash[:future_ttl] ).respond do
|
34
35
|
klass = hash[:receiver].class
|
35
36
|
if klass.respond_to?( :__enable_backgroundable_newrelic_tracing )
|
36
37
|
klass.__enable_backgroundable_newrelic_tracing( hash[:method] )
|
@@ -21,106 +21,53 @@ require 'torquebox/messaging/session'
|
|
21
21
|
module TorqueBox
|
22
22
|
module Messaging
|
23
23
|
class Connection
|
24
|
-
include TorqueBox::Injectors
|
25
24
|
|
26
|
-
|
25
|
+
attr_accessor :jms_connection
|
26
|
+
|
27
|
+
def initialize(jms_connection, connection_factory)
|
27
28
|
@jms_connection = jms_connection
|
28
|
-
@
|
29
|
+
@connection_factory = connection_factory
|
30
|
+
@tm = TorqueBox.fetch('transaction-manager')
|
29
31
|
end
|
30
32
|
|
31
33
|
def start
|
32
|
-
|
34
|
+
jms_connection.start
|
33
35
|
end
|
34
36
|
|
35
37
|
def close
|
36
|
-
|
38
|
+
jms_connection.close
|
37
39
|
end
|
38
40
|
|
39
41
|
def client_id
|
40
|
-
|
42
|
+
jms_connection.client_id
|
41
43
|
end
|
42
44
|
|
43
45
|
def client_id=(client_id)
|
44
|
-
|
46
|
+
jms_connection.client_id = client_id
|
45
47
|
end
|
46
|
-
|
47
|
-
def with_session(
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
elsif transaction && (!current.respond_to?(:transaction) || current.transaction != transaction)
|
55
|
-
yield activate( create_xa_session )
|
56
|
-
else
|
57
|
-
yield( current )
|
48
|
+
|
49
|
+
def with_session(&block)
|
50
|
+
begin
|
51
|
+
session = create_session
|
52
|
+
result = block.call( session )
|
53
|
+
ensure
|
54
|
+
session.close
|
58
55
|
end
|
56
|
+
result
|
59
57
|
end
|
60
58
|
|
61
|
-
def
|
62
|
-
|
63
|
-
end
|
64
|
-
def current
|
65
|
-
sessions.last
|
66
|
-
end
|
67
|
-
def activate(session)
|
68
|
-
sessions.push(session) && current
|
69
|
-
end
|
70
|
-
def deactivate
|
71
|
-
sessions.pop.close
|
59
|
+
def create_session
|
60
|
+
Session.new( jms_connection.create_session( false, Session::AUTO_ACK ) )
|
72
61
|
end
|
73
62
|
|
74
63
|
def transaction
|
75
64
|
@tm && @tm.transaction
|
76
65
|
end
|
77
66
|
|
78
|
-
def
|
79
|
-
|
80
|
-
transaction.enlist_resource( jms_session.xa_resource )
|
81
|
-
session = TransactedSession.new( jms_session, transaction, self )
|
82
|
-
transaction.registerSynchronization( session )
|
83
|
-
session
|
84
|
-
end
|
85
|
-
|
86
|
-
def create_session
|
87
|
-
Session.new( @jms_connection.create_session( false, Session::AUTO_ACK ) )
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
class TransactedSession < Session
|
93
|
-
include javax.transaction.Synchronization
|
94
|
-
attr_reader :transaction
|
95
|
-
|
96
|
-
def initialize( jms_session, transaction, connection )
|
97
|
-
super( jms_session )
|
98
|
-
@transaction = transaction
|
99
|
-
@connection = connection.extend(TransactedConnection)
|
100
|
-
end
|
101
|
-
|
102
|
-
def close
|
103
|
-
# eat the close, until tx completes
|
104
|
-
end
|
105
|
-
|
106
|
-
def beforeCompletion
|
107
|
-
# required interface
|
108
|
-
end
|
109
|
-
|
110
|
-
def afterCompletion(status)
|
111
|
-
@connection.deactivate
|
112
|
-
@connection.complete!
|
67
|
+
def deactivate
|
68
|
+
@connection_factory.deactivate
|
113
69
|
end
|
114
|
-
end
|
115
70
|
|
116
|
-
module TransactedConnection
|
117
|
-
def close
|
118
|
-
super if @complete
|
119
|
-
end
|
120
|
-
def complete!
|
121
|
-
@complete = true
|
122
|
-
close
|
123
|
-
end
|
124
71
|
end
|
125
72
|
|
126
73
|
end
|
@@ -23,7 +23,7 @@ module TorqueBox
|
|
23
23
|
class ConnectionFactory
|
24
24
|
|
25
25
|
attr_reader :internal_connection_factory
|
26
|
-
|
26
|
+
|
27
27
|
def self.new(internal_connection_factory = nil)
|
28
28
|
return internal_connection_factory if internal_connection_factory.is_a?( ConnectionFactory )
|
29
29
|
super
|
@@ -31,31 +31,70 @@ module TorqueBox
|
|
31
31
|
|
32
32
|
def initialize(internal_connection_factory = nil)
|
33
33
|
@internal_connection_factory = internal_connection_factory
|
34
|
+
@tm = TorqueBox.fetch('transaction-manager')
|
34
35
|
end
|
35
36
|
|
36
|
-
def with_new_connection(options, &block)
|
37
|
+
def with_new_connection(options, enlist_tx = true, &block)
|
37
38
|
client_id = options[:client_id]
|
38
|
-
|
39
|
+
create_internal_connection_factory( options )
|
40
|
+
if !enlist_tx || (current.nil? && !transaction)
|
41
|
+
connection = create_connection( options )
|
42
|
+
connection.client_id = client_id if client_id
|
43
|
+
begin
|
44
|
+
connection.start
|
45
|
+
result = block.call( connection )
|
46
|
+
ensure
|
47
|
+
connection.close
|
48
|
+
end
|
49
|
+
elsif transaction && (!current.respond_to?(:session_transaction) || current.session_transaction != transaction)
|
50
|
+
result = block.call( activate( create_xa_connection( options ), client_id ) )
|
51
|
+
# XaSession's afterCompletion callback deactivates XA connections
|
52
|
+
else
|
53
|
+
result = block.call( current )
|
54
|
+
end
|
55
|
+
result
|
56
|
+
end
|
57
|
+
|
58
|
+
def connections
|
59
|
+
Thread.current[:torquebox_connection] ||= []
|
60
|
+
end
|
61
|
+
|
62
|
+
def current
|
63
|
+
connections.last
|
64
|
+
end
|
65
|
+
|
66
|
+
def activate(connection, client_id)
|
39
67
|
connection.client_id = client_id if client_id
|
40
68
|
connection.start
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
return result
|
69
|
+
connections.push(connection) && current
|
70
|
+
end
|
71
|
+
|
72
|
+
def deactivate
|
73
|
+
connections.pop.close
|
47
74
|
end
|
48
75
|
|
49
|
-
def
|
76
|
+
def transaction
|
77
|
+
@tm && @tm.transaction
|
78
|
+
end
|
79
|
+
|
80
|
+
def create_internal_connection_factory(options)
|
50
81
|
host = options[:host] || "localhost"
|
51
82
|
port = options[:port] || 5445
|
52
|
-
username = options[:username]
|
53
|
-
password = options[:password]
|
54
83
|
if !@internal_connection_factory
|
55
84
|
@internal_connection_factory = create_connection_factory( host, port )
|
56
85
|
end
|
86
|
+
end
|
57
87
|
|
58
|
-
|
88
|
+
def create_connection(options={})
|
89
|
+
username = options[:username]
|
90
|
+
password = options[:password]
|
91
|
+
Connection.new( @internal_connection_factory.create_connection( username, password ), self )
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_xa_connection(options={})
|
95
|
+
username = options[:username]
|
96
|
+
password = options[:password]
|
97
|
+
XaConnection.new( @internal_connection_factory.create_xa_connection( username, password ), self )
|
59
98
|
end
|
60
99
|
|
61
100
|
def create_connection_factory(host, port)
|
@@ -24,11 +24,11 @@ require 'torquebox/messaging/ext/javax_jms_queue_browser'
|
|
24
24
|
module TorqueBox
|
25
25
|
module Messaging
|
26
26
|
class Destination
|
27
|
-
include TorqueBox::Injectors
|
28
27
|
include Enumerable
|
29
28
|
|
30
29
|
attr_reader :connection_factory
|
31
30
|
attr_reader :name
|
31
|
+
attr_reader :java_destination
|
32
32
|
attr_accessor :enumerable_options
|
33
33
|
attr_accessor :connect_options
|
34
34
|
|
@@ -39,9 +39,8 @@ module TorqueBox
|
|
39
39
|
:critical => 9
|
40
40
|
}
|
41
41
|
|
42
|
-
def _dump(
|
43
|
-
|
44
|
-
self.name.to_s
|
42
|
+
def _dump(level)
|
43
|
+
name
|
45
44
|
end
|
46
45
|
|
47
46
|
def self._load(str)
|
@@ -52,7 +51,7 @@ module TorqueBox
|
|
52
51
|
raise ArgumentError, "destination cannot be nil" unless destination
|
53
52
|
if connection_factory_or_options.nil? || connection_factory_or_options.is_a?( Hash )
|
54
53
|
options = connection_factory_or_options
|
55
|
-
connection_factory = fetch( 'connection-factory' )
|
54
|
+
connection_factory = TorqueBox.fetch( 'connection-factory' )
|
56
55
|
unless options.nil?
|
57
56
|
# Don't use our internal connection factory if the user
|
58
57
|
# has specified a host or port to connect to
|
@@ -64,10 +63,50 @@ module TorqueBox
|
|
64
63
|
@connection_factory = ConnectionFactory.new( connection_factory_or_options )
|
65
64
|
@connect_options = {}
|
66
65
|
end
|
67
|
-
|
66
|
+
|
67
|
+
|
68
|
+
if destination.is_a?(javax.jms.Destination )
|
69
|
+
if destination.is_a?(javax.jms.Queue)
|
70
|
+
@name = destination.queue_name
|
71
|
+
else
|
72
|
+
@name = destination.topic_name
|
73
|
+
end
|
74
|
+
|
75
|
+
@java_destination = destination
|
76
|
+
else
|
77
|
+
@name = destination
|
78
|
+
end
|
79
|
+
|
80
|
+
|
68
81
|
@enumerable_options = {}
|
69
82
|
end
|
70
83
|
|
84
|
+
# Stops the destination.
|
85
|
+
#
|
86
|
+
# @note This is an asynchronous method.
|
87
|
+
# @return [java.util.concurrent.CountDownLatch] The latch to wait for the task completion
|
88
|
+
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
|
89
|
+
def stop
|
90
|
+
TorqueBox::Messaging::Destination.with_destinationizer do |destinationizer|
|
91
|
+
destinationizer.remove_destination(name)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Stops the destination.
|
96
|
+
#
|
97
|
+
# @note This is a synchronous method.
|
98
|
+
# @return [Boolean] true if the destination was successfully stopped, false otherwise
|
99
|
+
# @see TorqueBox::Messaging::Destination.stop
|
100
|
+
def stop_sync
|
101
|
+
latch = stop
|
102
|
+
TorqueBox::Messaging::Destination.wait_for_latch(latch)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Publishes a message to the destination
|
106
|
+
#
|
107
|
+
# @param message The message to publish
|
108
|
+
# @param options Optional parameters (a Hash)
|
109
|
+
# @return [void]
|
71
110
|
def publish(message, options = {})
|
72
111
|
wait_for_destination(options[:startup_timeout]) do
|
73
112
|
with_session(options) do |session|
|
@@ -107,8 +146,15 @@ module TorqueBox
|
|
107
146
|
|
108
147
|
def with_session(opts = {})
|
109
148
|
transactional = opts.fetch(:tx, true)
|
110
|
-
|
111
|
-
|
149
|
+
|
150
|
+
# https://issues.jboss.org/browse/TORQUE-1033
|
151
|
+
# If there is no encoding for the message, set the default one
|
152
|
+
# for the destination. If the encoding for destination isn't set
|
153
|
+
# it won't hurt
|
154
|
+
opts[:encoding] = @connect_options[:encoding] if opts[:encoding].nil?
|
155
|
+
|
156
|
+
connection_factory.with_new_connection(connect_options, transactional) do |connection|
|
157
|
+
connection.with_session do |session|
|
112
158
|
yield session
|
113
159
|
end
|
114
160
|
end
|
@@ -194,6 +240,29 @@ module TorqueBox
|
|
194
240
|
def lookup(name)
|
195
241
|
list.find { |destination| destination.name == name }
|
196
242
|
end
|
243
|
+
|
244
|
+
# @api private
|
245
|
+
def with_destinationizer
|
246
|
+
service_name = TorqueBox::MSC.deployment_unit.service_name.append('torquebox').append('messaging').append('destinationizer')
|
247
|
+
|
248
|
+
TorqueBox::ServiceRegistry.lookup(service_name) do |destinationizer|
|
249
|
+
yield destinationizer
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
# @api private
|
254
|
+
def wait_for_latch(latch)
|
255
|
+
if latch
|
256
|
+
begin
|
257
|
+
# Wait for the services to come up for up to 30 seconds
|
258
|
+
latch.await(45, java.util.concurrent.TimeUnit::SECONDS)
|
259
|
+
rescue
|
260
|
+
return false
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
true
|
265
|
+
end
|
197
266
|
end
|
198
267
|
|
199
268
|
end
|