torquebox-messaging 1.1.1-java → 2.0.0.beta1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/lib/gem_hook.rb +26 -3
  2. data/lib/torquebox-messaging.jar +0 -0
  3. data/lib/torquebox-messaging.rb +2 -32
  4. data/lib/torquebox/messaging.rb +16 -0
  5. data/lib/torquebox/messaging/backgroundable.rb +32 -15
  6. data/lib/torquebox/messaging/backgroundable_processor.rb +32 -0
  7. data/lib/torquebox/messaging/connection.rb +127 -0
  8. data/lib/torquebox/messaging/connection_factory.rb +70 -0
  9. data/lib/torquebox/messaging/const_missing.rb +28 -0
  10. data/lib/torquebox/messaging/core.rb +27 -0
  11. data/lib/torquebox/messaging/destination.rb +68 -111
  12. data/lib/torquebox/messaging/ext/javax_jms_queue_browser.rb +1 -3
  13. data/lib/torquebox/messaging/future_responder.rb +10 -7
  14. data/lib/torquebox/messaging/json_message.rb +50 -0
  15. data/lib/torquebox/messaging/marshal_base64_message.rb +44 -0
  16. data/lib/torquebox/messaging/marshal_message.rb +43 -0
  17. data/lib/torquebox/messaging/message.rb +123 -0
  18. data/lib/torquebox/messaging/message_processor.rb +47 -0
  19. data/lib/torquebox/messaging/processor_wrapper.rb +38 -0
  20. data/lib/torquebox/messaging/queue.rb +61 -0
  21. data/lib/torquebox/messaging/session.rb +168 -0
  22. data/lib/torquebox/messaging/task.rb +7 -6
  23. data/lib/torquebox/messaging/text_message.rb +36 -0
  24. data/lib/torquebox/messaging/topic.rb +54 -0
  25. data/lib/torquebox/messaging/xa_connection.rb +58 -0
  26. data/lib/torquebox/messaging/xa_connection_factory.rb +59 -0
  27. data/lib/torquebox/messaging/xa_session.rb +30 -0
  28. data/licenses/lgpl-2.1.txt +7 -9
  29. data/spec/backgroundable_spec.rb +17 -24
  30. data/spec/destination_spec.rb +31 -318
  31. data/spec/future_responder_spec.rb +1 -1
  32. data/spec/json_message_spec.rb +50 -0
  33. data/spec/message_processor_spec.rb +54 -0
  34. data/spec/message_spec.rb +114 -0
  35. data/spec/task_spec.rb +11 -5
  36. metadata +38 -77
  37. data/lib/acl-spi-3.0.0.CR2.jar +0 -0
  38. data/lib/activation-1.1.jar +0 -0
  39. data/lib/authorization-spi-3.0.0.CR2.jar +0 -0
  40. data/lib/dtdparser-1.21.jar +0 -0
  41. data/lib/hornetq-core-2.1.2.Final.jar +0 -0
  42. data/lib/hornetq-jms-client-2.1.2.Final.jar +0 -0
  43. data/lib/hornetq-logging-2.1.2.Final.jar +0 -0
  44. data/lib/identity-spi-3.0.0.CR2.jar +0 -0
  45. data/lib/jaxb-api-2.1.9.jar +0 -0
  46. data/lib/jboss-common-core-2.2.17.GA.jar +0 -0
  47. data/lib/jboss-jms-api_1.1_spec-1.0.0.Final.jar +0 -0
  48. data/lib/jboss-logging-3.0.0.Beta4.jar +0 -0
  49. data/lib/jboss-reflect-2.2.0.GA.jar +0 -0
  50. data/lib/jbosssx-bare-3.0.0.CR2.jar +0 -0
  51. data/lib/jbossxacml-2.0.5.CR1.jar +0 -0
  52. data/lib/jbossxb-2.0.3.GA.jar +0 -0
  53. data/lib/jnp-client-5.0.5.Final.jar +0 -0
  54. data/lib/jruby-complete-1.6.3.jar +0 -0
  55. data/lib/netty-3.2.1.Final.jar +0 -0
  56. data/lib/picketbox-acl-impl-3.0.0.CR2.jar +0 -0
  57. data/lib/picketbox-bare-3.0.0.CR2.jar +0 -0
  58. data/lib/picketbox-identity-impl-3.0.0.CR2.jar +0 -0
  59. data/lib/picketbox-spi-bare-3.0.0.CR2.jar +0 -0
  60. data/lib/torquebox-base-core.jar +0 -0
  61. data/lib/torquebox-base-metadata.jar +0 -0
  62. data/lib/torquebox-base-spi.jar +0 -0
  63. data/lib/torquebox-mc-support.jar +0 -0
  64. data/lib/torquebox-messaging-core.jar +0 -0
  65. data/lib/torquebox/messaging/client.rb +0 -75
  66. data/lib/torquebox/messaging/ext/javax_jms_session.rb +0 -153
  67. data/lib/xercesImpl-2.9.1.jar +0 -0
  68. data/lib/xml-apis-1.3.04.jar +0 -0
  69. data/spec/client_spec.rb +0 -116
  70. data/spec/dispatcher-queues.yml +0 -4
  71. data/spec/dispatcher_not_running.rb +0 -54
  72. data/spec/ext/java_jmx_session_spec.rb +0 -71
  73. data/spec/queues.yml +0 -6
@@ -0,0 +1,123 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ module TorqueBox
19
+ module Messaging
20
+ class Message
21
+
22
+ attr_reader :jms_message
23
+
24
+ # if no encoding specified in the message itself assume the legacy encoding
25
+ DEFAULT_DECODE_ENCODING = :marshal_base64
26
+
27
+ # if no encoding specified when creating a message and no global
28
+ # defaut set use :marshal
29
+ DEFAULT_ENCODE_ENCODING = :marshal
30
+
31
+ ENCODING_PROPERTY = "__ContentEncoding__"
32
+
33
+ def initialize(jms_session, payload)
34
+ @jms_message = self.class::JMS_TYPE == :text ? jms_session.create_text_message :
35
+ jms_session.create_bytes_message
36
+ set_encoding
37
+ encode( payload )
38
+ end
39
+
40
+ def initialize_from_message(jms_message)
41
+ @jms_message = jms_message
42
+ end
43
+
44
+ def set_encoding
45
+ @jms_message.set_string_property( ENCODING_PROPERTY, self.class::ENCODING.to_s )
46
+ end
47
+
48
+ def populate_message_headers(options)
49
+ return if options.nil?
50
+ options.each do |key, value|
51
+ case key.to_s
52
+ when 'correlation_id' then @jms_message.setJMSCorrelationID(value)
53
+ when 'reply_to' then @jms_message.setJMSReplyTo(value)
54
+ when 'type' then @jms_message.setJMSType(value)
55
+ end
56
+ end
57
+ end
58
+
59
+ def populate_message_properties(properties)
60
+ return if properties.nil?
61
+ properties.each do |key, value|
62
+ case value
63
+ when Integer
64
+ @jms_message.set_long_property(key.to_s, value)
65
+ when Float
66
+ @jms_message.set_double_property(key.to_s, value)
67
+ when TrueClass, FalseClass
68
+ @jms_message.set_boolean_property(key.to_s, value)
69
+ else
70
+ @jms_message.set_string_property(key.to_s, value.to_s)
71
+ end
72
+ end
73
+ end
74
+
75
+ def method_missing(*args)
76
+ @jms_message.send(*args)
77
+ end
78
+
79
+ class << self
80
+ alias :__new__ :new
81
+
82
+ def inherited(subclass)
83
+ class << subclass
84
+ alias :new :__new__
85
+ end
86
+ end
87
+
88
+ def new(jms_message_or_session, payload = nil, encoding = nil)
89
+ if jms_message_or_session.is_a?( javax.jms::Session )
90
+ encoding ||= ENV['DEFAULT_MESSAGE_ENCODING'] || DEFAULT_ENCODE_ENCODING
91
+ klass = class_for_encoding( encoding.to_sym )
92
+ klass.new( jms_message_or_session, payload )
93
+ else
94
+ encoding = extract_encoding_from_message( jms_message_or_session ) || DEFAULT_DECODE_ENCODING
95
+ klass = class_for_encoding( encoding )
96
+ msg = klass.allocate
97
+ msg.initialize_from_message( jms_message_or_session )
98
+ msg
99
+ end
100
+ end
101
+
102
+ def encoding_map
103
+ @encoding_map ||= { }
104
+ end
105
+
106
+ def register_encoding(klass)
107
+ encoding_map[klass::ENCODING] = klass
108
+ end
109
+
110
+ def class_for_encoding(encoding)
111
+ klass = encoding_map[encoding.to_sym]
112
+ raise ArgumentError.new( "No message class found for encoding '#{encoding}'" ) unless klass
113
+ klass
114
+ end
115
+
116
+ def extract_encoding_from_message(jms_message)
117
+ jms_message.get_string_property( ENCODING_PROPERTY )
118
+ end
119
+
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,47 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ module TorqueBox
19
+ module Messaging
20
+ class MessageProcessor
21
+
22
+ attr_accessor :message
23
+
24
+ def initialize
25
+ @message = nil
26
+ end
27
+
28
+ def on_message(body)
29
+ throw "Your subclass must implement on_message(body)"
30
+ end
31
+
32
+ def on_error(error)
33
+ raise error
34
+ end
35
+
36
+ def process!(message)
37
+ @message = message
38
+ begin
39
+ on_message( message.decode )
40
+ rescue Exception => e
41
+ on_error( e )
42
+ end
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ require 'torquebox/transactions'
19
+
20
+ module TorqueBox
21
+ module Messaging
22
+ class ProcessorWrapper
23
+
24
+ def initialize(target, session, message)
25
+ @target = target
26
+ @session = session
27
+ @message = message
28
+ end
29
+
30
+ def process!
31
+ TorqueBox.transaction( @session ) do
32
+ @target.process!( @message )
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ require 'torquebox/messaging/destination'
19
+ require 'torquebox/service_registry'
20
+
21
+ module TorqueBox
22
+ module Messaging
23
+ class Queue < Destination
24
+
25
+ def self.start( name, options={} )
26
+ selector = options.fetch( :selector, "" )
27
+ durable = options.fetch( :durable, true )
28
+ jndi = options.fetch( :jndi, [].to_java(:string) )
29
+ TorqueBox::ServiceRegistry.lookup("jboss.messaging.default.jms.manager") do |server|
30
+ server.createQueue( false, name, selector, durable, jndi )
31
+ end
32
+ new( name )
33
+ end
34
+
35
+ def stop
36
+ TorqueBox::ServiceRegistry.lookup("jboss.messaging.default.jms.manager") do |server|
37
+ server.destroyQueue( name )
38
+ end
39
+ end
40
+
41
+ def publish_and_receive(message, options={})
42
+ result = nil
43
+ with_session do |session|
44
+ result = session.publish_and_receive(self, message,
45
+ normalize_options(options))
46
+ end
47
+ result
48
+ end
49
+
50
+ def receive_and_publish(options={}, &block)
51
+ with_session do |session|
52
+ session.receive_and_publish(self, normalize_options(options), &block)
53
+ end
54
+ end
55
+
56
+ def to_s
57
+ "[Queue: #{super}]"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,168 @@
1
+ # Copyright 2008-2011 Red Hat, Inc, and individual contributors.
2
+ #
3
+ # This is free software; you can redistribute it and/or modify it
4
+ # under the terms of the GNU Lesser General Public License as
5
+ # published by the Free Software Foundation; either version 2.1 of
6
+ # the License, or (at your option) any later version.
7
+ #
8
+ # This software is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this software; if not, write to the Free
15
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
+
18
+ module TorqueBox
19
+ module Messaging
20
+
21
+ class Session
22
+
23
+ AUTO_ACK = javax.jms::Session::AUTO_ACKNOWLEDGE
24
+ CLIENT_ACK = javax.jms::Session::CLIENT_ACKNOWLEDGE
25
+ DUPS_OK_ACK = javax.jms::Session::DUPS_OK_ACKNOWLEDGE
26
+
27
+ attr_accessor :jms_session
28
+
29
+ def initialize(jms_session)
30
+ @jms_session = jms_session
31
+ end
32
+
33
+ def close
34
+ @jms_session.close
35
+ end
36
+
37
+ def queue_for(name)
38
+ Queue.new( @jms_session.create_queue( name ) )
39
+ end
40
+
41
+ def publish(destination, payload, options={})
42
+ producer = @jms_session.create_producer( java_destination( destination ) )
43
+ message = Message.new( @jms_session, payload, options[:encoding] )
44
+
45
+ message.populate_message_headers(options)
46
+ message.populate_message_properties(options[:properties])
47
+
48
+ producer.send( message.jms_message,
49
+ options.fetch(:delivery_mode, producer.delivery_mode),
50
+ options.fetch(:priority, producer.priority),
51
+ options.fetch(:ttl, producer.time_to_live) )
52
+ message
53
+ end
54
+
55
+ # Returns decoded message, by default. Pass :decode=>false to
56
+ # return the original JMS TextMessage. Pass :timeout to give up
57
+ # after a number of milliseconds
58
+ def receive(destination, options={})
59
+ decode = options.fetch(:decode, true)
60
+ timeout = options.fetch(:timeout, 0)
61
+ selector = options[:selector]
62
+
63
+ java_destination = java_destination( destination )
64
+ if options[:durable] && java_destination.class.name =~ /Topic/
65
+ consumer = @jms_session.createDurableSubscriber( java_destination,
66
+ options.fetch(:subscriber_name, Topic::DEFAULT_SUBSCRIBER_NAME),
67
+ selector,
68
+ false )
69
+ else
70
+ consumer = @jms_session.createConsumer( java_destination, selector )
71
+ end
72
+ begin
73
+ jms_message = consumer.receive( timeout )
74
+ if jms_message
75
+ decode ? Message.new( jms_message ).decode : jms_message
76
+ end
77
+ ensure
78
+ consumer.close unless consumer.nil?
79
+ end
80
+ end
81
+
82
+ # Implement the request-response pattern. Sends a message to the
83
+ # request destination and waits for a reply on the response
84
+ # destination.
85
+ #
86
+ # Options:
87
+ #
88
+ # :timeout - specifies the time in miliseconds to wait for answer,
89
+ # default: 10000 (10s)
90
+ # :decode - pass false to return the original JMS TextMessage,
91
+ # default: true
92
+ #
93
+ def publish_and_receive(destination, message, options = {})
94
+ options[:timeout] ||= 10000 # 10s
95
+ decode = options.fetch(:decode, false)
96
+ options[:properties] ||= {}
97
+ options[:properties]["synchronous"] = "true"
98
+ wrapped_message = { :timeout => options[:timeout], :message => message }
99
+ message = publish(destination, wrapped_message, options)
100
+
101
+ options[:selector] = "JMSCorrelationID='#{message.jms_message.jms_message_id}'"
102
+ response = receive(destination, options)
103
+
104
+ if response
105
+ decode ? Message.new( response ).decode : response
106
+ end
107
+ end
108
+
109
+ # Receiving end of the request-response pattern. The return value of
110
+ # the block passed to this method is the response sent back to the
111
+ # client. If no block is given then request is returned as the
112
+ # response.
113
+ def receive_and_publish(destination, options = {})
114
+ selector = "synchronous = 'true'"
115
+ selector = "#{selector} and (#{options[:selector]})" if options[:selector]
116
+ receive_options = options.merge(:decode => false,
117
+ :selector => selector)
118
+
119
+ request = receive(destination, receive_options)
120
+ unless request.nil?
121
+ decoded_request = Message.new( request ).decode
122
+ request_message = decoded_request[:message]
123
+ # Base the response ttl off the original request timeout
124
+ request_timeout = decoded_request[:timeout]
125
+ options[:ttl] ||= request_timeout
126
+
127
+ response = block_given? ? yield(request_message) : request_message
128
+
129
+ options[:correlation_id] = request.jms_message_id
130
+ publish(destination, response, options)
131
+ end
132
+ end
133
+
134
+ def unsubscribe(subscriber_name = Topic::DEFAULT_SUBSCRIBER_NAME)
135
+ @jms_session.unsubscribe( subscriber_name )
136
+ end
137
+
138
+ def create_browser(*args)
139
+ jms_session.create_browser( *args )
140
+ end
141
+
142
+ def java_destination(destination)
143
+ java_destination = destination.name
144
+
145
+ unless java_destination.is_a?( javax.jms.Destination )
146
+ meth = destination.is_a?( Queue ) ? :create_queue : :create_topic
147
+ java_destination = @jms_session.send( meth, java_destination )
148
+ end
149
+
150
+ java_destination
151
+ end
152
+
153
+ def self.canonical_ack_mode(ack_mode)
154
+ case ( ack_mode )
155
+ when Fixnum
156
+ return ack_mode
157
+ when :auto
158
+ return AUTO_ACK
159
+ when :client
160
+ return CLIENT_ACK
161
+ when :dups_ok
162
+ return DUPS_OK_ACK
163
+ end
164
+ end
165
+ end
166
+
167
+ end
168
+ end
@@ -15,24 +15,24 @@
15
15
  # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16
16
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
17
17
 
18
- require 'torquebox/messaging/destination'
18
+ require 'torquebox/messaging/queue'
19
19
  require 'torquebox/messaging/future_responder'
20
20
  require 'torquebox/messaging/future'
21
21
  require 'torquebox/messaging/future_status'
22
22
 
23
23
  module TorqueBox
24
24
  module Messaging
25
-
25
+
26
26
  class Task
27
27
  include FutureStatus
28
28
 
29
- def self.queue_name
30
- suffix = org.torquebox.common.util.StringUtils.underscore(name[0...-4])
29
+ def self.queue_name( name = self.name[0...-4] )
30
+ suffix = org.torquebox.core.util.StringUtils.underscore(name)
31
31
  "/queues/torquebox/#{ENV['TORQUEBOX_APP_NAME']}/tasks/#{suffix}"
32
32
  end
33
33
 
34
34
  def self.async(method, payload = {}, options = {})
35
- queue = Queue.new(queue_name)
35
+ queue = Queue.new( queue_name )
36
36
  future = Future.new( queue )
37
37
  message = {
38
38
  :method => method,
@@ -40,8 +40,9 @@ module TorqueBox
40
40
  :future_id => future.correlation_id,
41
41
  :future_queue => queue_name
42
42
  }
43
+ options[:encoding] = :marshal
43
44
  queue.publish( message, options )
44
-
45
+
45
46
  future
46
47
  rescue javax.naming.NameNotFoundException => ex
47
48
  raise RuntimeError.new("The queue for #{self.name} is not available. Did you disable it by setting its concurrency to 0?")