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.
Files changed (44) hide show
  1. data/lib/hornetq-commons-2.3.0.CR1.jar +0 -0
  2. data/lib/hornetq-core-client-2.3.0.CR1.jar +0 -0
  3. data/lib/hornetq-jms-client-2.3.0.CR1.jar +0 -0
  4. data/lib/hornetq-journal-2.3.0.CR1.jar +0 -0
  5. data/lib/jboss-logging-3.1.2.GA.jar +0 -0
  6. data/lib/jboss-logmanager-1.4.0.Final.jar +0 -0
  7. data/lib/netty-3.6.2.Final.jar +0 -0
  8. data/lib/torquebox/messaging/backgroundable.rb +16 -8
  9. data/lib/torquebox/messaging/backgroundable_processor.rb +2 -1
  10. data/lib/torquebox/messaging/connection.rb +21 -74
  11. data/lib/torquebox/messaging/connection_factory.rb +52 -13
  12. data/lib/torquebox/messaging/datamapper_marshaling.rb +1 -0
  13. data/lib/torquebox/messaging/destination.rb +77 -8
  14. data/lib/torquebox/messaging/echo_processor.rb +1 -0
  15. data/lib/torquebox/messaging/edn_message.rb +0 -11
  16. data/lib/torquebox/messaging/future_responder.rb +2 -2
  17. data/lib/torquebox/messaging/json_message.rb +0 -24
  18. data/lib/torquebox/messaging/marshal_base64_message.rb +0 -18
  19. data/lib/torquebox/messaging/marshal_message.rb +4 -5
  20. data/lib/torquebox/messaging/message.rb +10 -0
  21. data/lib/torquebox/messaging/message_processor.rb +162 -3
  22. data/lib/torquebox/messaging/processor_middleware/chain.rb +1 -0
  23. data/lib/torquebox/messaging/processor_middleware/default_middleware.rb +1 -0
  24. data/lib/torquebox/messaging/processor_middleware/with_transaction.rb +1 -0
  25. data/lib/torquebox/messaging/queue.rb +210 -41
  26. data/lib/torquebox/messaging/session.rb +4 -8
  27. data/lib/torquebox/messaging/task.rb +8 -6
  28. data/lib/torquebox/messaging/topic.rb +23 -11
  29. data/lib/torquebox/messaging/xa_connection.rb +22 -25
  30. data/lib/torquebox/messaging/xa_connection_factory.rb +2 -17
  31. data/lib/torquebox/messaging/xa_session.rb +21 -0
  32. data/lib/torquebox-messaging.jar +0 -0
  33. data/lib/torquebox-messaging.rb +9 -5
  34. data/licenses/cc0-1.0.txt +121 -0
  35. data/spec/backgroundable_spec.rb +21 -0
  36. data/spec/destination_spec.rb +81 -14
  37. data/spec/message_processor_spec.rb +151 -1
  38. data/spec/task_spec.rb +8 -1
  39. metadata +51 -65
  40. data/lib/hornetq-core-2.2.21.Final.jar +0 -0
  41. data/lib/hornetq-jms-2.2.21.Final.jar +0 -0
  42. data/lib/netty-3.2.6.Final.jar +0 -0
  43. data/licenses/lgpl-2.1.txt +0 -502
  44. data/spec/json_message_spec.rb +0 -50
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(ClassMethods)
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 {ClassMethods#always_background}.
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 ClassMethods
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 {ClassMethods#always_background}.
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
- extend TorqueBox::Injectors
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\.9\./ ? method.to_sym : method.to_s)
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
- def initialize(jms_connection)
25
+ attr_accessor :jms_connection
26
+
27
+ def initialize(jms_connection, connection_factory)
27
28
  @jms_connection = jms_connection
28
- @tm = fetch('transaction-manager')
29
+ @connection_factory = connection_factory
30
+ @tm = TorqueBox.fetch('transaction-manager')
29
31
  end
30
32
 
31
33
  def start
32
- @jms_connection.start
34
+ jms_connection.start
33
35
  end
34
36
 
35
37
  def close
36
- @jms_connection.close
38
+ jms_connection.close
37
39
  end
38
40
 
39
41
  def client_id
40
- @jms_connection.client_id
42
+ jms_connection.client_id
41
43
  end
42
44
 
43
45
  def client_id=(client_id)
44
- @jms_connection.client_id = client_id
46
+ jms_connection.client_id = client_id
45
47
  end
46
-
47
- def with_session(enlist_tx = true)
48
- if !enlist_tx || (current.nil? && !transaction)
49
- begin
50
- yield activate( create_session )
51
- ensure
52
- deactivate
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 sessions
62
- Thread.current[:session] ||= []
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 create_xa_session
79
- jms_session = @jms_connection.create_xa_session()
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
- connection = create_connection( options )
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
- begin
42
- result = block.call( connection )
43
- ensure
44
- connection.close
45
- end
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 create_connection(options)
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
- Connection.new( @internal_connection_factory.create_connection( username, password ) )
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)
@@ -21,6 +21,7 @@
21
21
  # class name of the resource, and use Resource.get to _load it.
22
22
  module TorqueBox
23
23
  module Messaging
24
+ # @api private
24
25
  module DataMapper
25
26
 
26
27
  def self.included(base)
@@ -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(depth)
43
- return self.name.queue_name if self.name.respond_to?( :queue_name )
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
- @name = destination
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
- connection_factory.with_new_connection( connect_options ) do |connection|
111
- connection.with_session(transactional) do |session|
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