torquebox-messaging 2.3.2-java → 3.0.0.beta1-java

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 (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