jruby-jms 0.10.2 → 0.11.0

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 (70) hide show
  1. data/HISTORY.md +15 -0
  2. data/README.md +27 -28
  3. data/Rakefile +7 -1
  4. data/doc/classes/JMS.html +265 -0
  5. data/doc/classes/JMS/BytesMessage.html +215 -0
  6. data/doc/classes/JMS/Connection.html +1145 -0
  7. data/doc/classes/JMS/MapMessage.html +333 -0
  8. data/doc/classes/JMS/Message.html +1085 -0
  9. data/doc/classes/JMS/MessageConsumer.html +316 -0
  10. data/doc/classes/JMS/MessageListenerImpl.html +262 -0
  11. data/doc/classes/JMS/ObjectMessage.html +170 -0
  12. data/doc/classes/JMS/OracleAQConnectionFactory.html +184 -0
  13. data/doc/classes/JMS/QueueBrowser.html +155 -0
  14. data/doc/classes/JMS/Session.html +947 -0
  15. data/doc/classes/JMS/SessionPool.html +411 -0
  16. data/doc/classes/JMS/TextMessage.html +194 -0
  17. data/doc/created.rid +1 -0
  18. data/doc/files/README_md.html +440 -0
  19. data/doc/files/lib/jms/bytes_message_rb.html +122 -0
  20. data/doc/files/lib/jms/connection_rb.html +140 -0
  21. data/doc/files/lib/jms/imports_rb.html +108 -0
  22. data/doc/files/lib/jms/logging_rb.html +129 -0
  23. data/doc/files/lib/jms/map_message_rb.html +122 -0
  24. data/doc/files/lib/jms/message_consumer_rb.html +122 -0
  25. data/doc/files/lib/jms/message_listener_impl_rb.html +122 -0
  26. data/doc/files/lib/jms/message_rb.html +122 -0
  27. data/doc/files/lib/jms/object_message_rb.html +122 -0
  28. data/doc/files/lib/jms/oracle_a_q_connection_factory_rb.html +122 -0
  29. data/doc/files/lib/jms/queue_browser_rb.html +122 -0
  30. data/doc/files/lib/jms/session_pool_rb.html +108 -0
  31. data/doc/files/lib/jms/session_rb.html +164 -0
  32. data/doc/files/lib/jms/text_message_rb.html +122 -0
  33. data/doc/files/lib/jms_rb.html +131 -0
  34. data/doc/fr_class_index.html +39 -0
  35. data/doc/fr_file_index.html +42 -0
  36. data/doc/fr_method_index.html +120 -0
  37. data/doc/index.html +24 -0
  38. data/doc/rdoc-style.css +208 -0
  39. data/examples/advanced/session_pool.rb +37 -0
  40. data/examples/client-server/replier.rb +29 -0
  41. data/examples/client-server/requestor.rb +40 -0
  42. data/examples/jms.yml +85 -9
  43. data/examples/performance/consumer.rb +6 -8
  44. data/examples/performance/producer.rb +10 -10
  45. data/examples/producer-consumer/browser.rb +24 -0
  46. data/examples/{consumer.rb → producer-consumer/consumer.rb} +5 -4
  47. data/examples/producer-consumer/consumer_async.rb +30 -0
  48. data/examples/{producer.rb → producer-consumer/producer.rb} +5 -3
  49. data/examples/publish-subscribe/publish.rb +24 -0
  50. data/examples/publish-subscribe/subscribe.rb +31 -0
  51. data/lib/jms/bytes_message.rb +52 -0
  52. data/lib/jms/connection.rb +170 -162
  53. data/lib/jms/imports.rb +21 -0
  54. data/lib/jms/logging.rb +17 -1
  55. data/lib/jms/{javax_jms_map_message.rb → map_message.rb} +2 -2
  56. data/lib/jms/message.rb +285 -0
  57. data/lib/jms/{javax_jms_message_consumer.rb → message_consumer.rb} +6 -3
  58. data/lib/jms/{message_listener.rb → message_listener_impl.rb} +3 -3
  59. data/lib/jms/{javax_jms_object_message.rb → object_message.rb} +1 -1
  60. data/lib/jms/oracle_a_q_connection_factory.rb +35 -0
  61. data/lib/jms/{javax_jms_queue_browser.rb → queue_browser.rb} +5 -4
  62. data/lib/jms/{javax_jms_session.rb → session.rb} +23 -25
  63. data/lib/jms/session_pool.rb +148 -0
  64. data/lib/jms/{javax_jms_text_message.rb → text_message.rb} +1 -1
  65. data/test/connection_test.rb +31 -29
  66. data/test/jms.yml +8 -9
  67. data/test/message_test.rb +29 -29
  68. data/test/session_test.rb +39 -39
  69. metadata +62 -22
  70. data/lib/jms/javax_jms_message.rb +0 -264
@@ -17,13 +17,13 @@
17
17
  # For each thread that will be processing messages concurrently a separate
18
18
  # session is required. All sessions can share a single connection to the same
19
19
  # JMS Provider.
20
- #
20
+ #
21
21
  # Interface javax.jms.Session
22
- #
22
+ #
23
23
  # See: http://download.oracle.com/javaee/6/api/javax/jms/Session.html
24
- #
24
+ #
25
25
  # Other methods still directly accessible through this class:
26
- #
26
+ #
27
27
  # create_browser(queue, message_selector)
28
28
  # Creates a QueueBrowser object to peek at the messages on the specified queue using a message selector.
29
29
  #
@@ -32,9 +32,9 @@
32
32
  #
33
33
  # create_consumer(destination)
34
34
  # Creates a MessageConsumer for the specified destination
35
- # See: Connection::consumer
36
- #
37
- # Example:
35
+ # See: Connection::consumer
36
+ #
37
+ # Example:
38
38
  # destination = session.create_destination(:queue_name => "MyQueue")
39
39
  # session.create_consumer(destination)
40
40
  #
@@ -49,7 +49,7 @@
49
49
  #
50
50
  # create_durable_subscriber(Topic topic, java.lang.String name, java.lang.String messageSelector, boolean noLocal)
51
51
  # Creates a durable subscriber to the specified topic, using a message selector and specifying whether messages published by its own connection should be delivered to it.
52
- #
52
+ #
53
53
  # create_map_Message()
54
54
  # Creates a MapMessage object
55
55
  #
@@ -107,7 +107,8 @@
107
107
  # unsubscribe(name)
108
108
  # Unsubscribes a durable subscription that has been created by a client
109
109
  #
110
- module javax.jms::Session
110
+ # Interface javax.jms.Session
111
+ module JMS::Session
111
112
  # Create a new message instance based on the type of the data being supplied
112
113
  # String (:to_str) => TextMessage
113
114
  # Hash (:each_pair) => MapMessage
@@ -129,13 +130,13 @@ module javax.jms::Session
129
130
  end
130
131
 
131
132
  # Create the destination based on the parameter supplied
132
- #
133
+ #
133
134
  # The idea behind this method is to allow the decision as to whether
134
135
  # one is sending to a topic or destination to be transparent to the code.
135
136
  # The supplied parameters can be externalized into say a YAML file
136
137
  # so that today it writes to a queue, later it can be changed to write
137
138
  # to a topic so that multiple parties can receive the same messages.
138
- #
139
+ #
139
140
  # Note: For Temporary Queues and Topics, remember to delete them when done
140
141
  # or just use ::destination instead with a block and it will take care
141
142
  # of deleting them for you
@@ -167,11 +168,11 @@ module javax.jms::Session
167
168
  #
168
169
  # Returns the result of the supplied block
169
170
  def create_destination(params)
170
- # Allow a Java JMS destination object to be passed in
171
- return params[:destination] if params[:destination] && params[:destination].java_kind_of?(javax.jms::Destination)
172
-
173
- # :queue_name is deprecated
174
- queue_name = params[:queue_name] || params[:queue_name]
171
+ # Allow a Java JMS destination object to be passed in
172
+ return params[:destination] if params[:destination] && params[:destination].java_kind_of?(JMS::Destination)
173
+
174
+ # :q_name is deprecated
175
+ queue_name = params[:queue_name] || params[:q_name]
175
176
  topic_name = params[:topic_name]
176
177
  raise "Missing mandatory parameter :queue_name or :topic_name to Session::producer, Session::consumer, or Session::browser" unless queue_name || topic_name
177
178
 
@@ -181,9 +182,9 @@ module javax.jms::Session
181
182
  topic_name == :temporary ? create_temporary_topic : create_topic(topic_name)
182
183
  end
183
184
  end
184
-
185
+
185
186
  # Create a queue or topic to send or receive messages from
186
- #
187
+ #
187
188
  # A block must be supplied so that if it is a temporary topic or queue
188
189
  # it will be deleted after the proc is complete
189
190
  #
@@ -223,7 +224,7 @@ module javax.jms::Session
223
224
  # Delete Temporary Queue / Topic
224
225
  dest.delete if dest && dest.respond_to?(:delete)
225
226
  end
226
- end
227
+ end
227
228
 
228
229
  # Return the queue matching the queue name supplied
229
230
  # Call the Proc if supplied
@@ -291,12 +292,9 @@ module javax.jms::Session
291
292
  # Symbol: :temporary => Create temporary topic
292
293
  # Mandatory unless :queue_name is supplied
293
294
  # Or,
294
- # :destination=> Explicit javax.jms::Destination to use
295
+ # :destination=> Explicit JMS::Destination to use
295
296
  def producer(params, &proc)
296
- destination = create_destination(params)
297
- # Call original java method with this destination
298
- #p = java_send :create_producer, [javax.jms::Destination], destination
299
- p = create_producer(destination)
297
+ p = self.create_producer(self.create_destination(params))
300
298
  if proc
301
299
  begin
302
300
  proc.call(p)
@@ -314,7 +312,7 @@ module javax.jms::Session
314
312
  # Call the Proc if supplied, then automatically close the consumer
315
313
  #
316
314
  # Parameters:
317
- # :queue_name => String: Name of the Queue to return
315
+ # :queue_name => String: Name of the Queue to return
318
316
  # Symbol: :temporary => Create temporary queue
319
317
  # Mandatory unless :topic_name is supplied
320
318
  # Or,
@@ -0,0 +1,148 @@
1
+ require 'gene_pool'
2
+
3
+ module JMS
4
+ # Since a Session can only be used by one thread at a time, we could create
5
+ # a Session for every thread. That could result in excessive unused Sessions.
6
+ # An alternative is to create a pool of sessions that can be shared by
7
+ # multiple threads.
8
+ #
9
+ # Each thread can request a session and then return it once it is no longer
10
+ # needed by that thread. The only way to get a session is pass a block so that
11
+ # the Session is automatically returned to the pool upon completion of the block.
12
+ #
13
+ # Parameters:
14
+ # see regular session parameters from: JMS::Connection#initialize
15
+ #
16
+ # Additional parameters for controlling the session pool itself
17
+ # :pool_name Name of the pool as it shows up in the logger.
18
+ # Default: 'JMS::SessionPool'
19
+ # :pool_size Maximum Pool Size. Default: 10
20
+ # The pool only grows as needed and will never exceed
21
+ # :pool_size
22
+ # :pool_warn_timeout Number of seconds to wait before logging a warning when a
23
+ # session in the pool is not available. Measured in seconds
24
+ # Default: 5.0
25
+ # :pool_logger Supply a logger that responds to #debug, #info, #warn and #debug?
26
+ # For example: Rails.logger
27
+ # Default: None
28
+ # Example:
29
+ # session_pool = connection.create_session_pool(config)
30
+ # session_pool.session do |session|
31
+ # ....
32
+ # end
33
+ class SessionPool
34
+ def initialize(connection, params={})
35
+ # Save Session params since it will be used every time a new session is
36
+ # created in the pool
37
+ session_params = params.nil? ? {} : params.dup
38
+ logger = session_params[:pool_logger]
39
+ # Define how GenePool can create new sessions
40
+ @pool = GenePool.new(
41
+ :name => session_params[:pool_name] || self.class.name,
42
+ :pool_size => session_params[:pool_size] || 10,
43
+ :warn_timeout => session_params[:pool_warn_timeout] || 5,
44
+ :logger => logger) do
45
+ connection.create_session(session_params)
46
+ end
47
+
48
+ # Handle connection failures
49
+ connection.on_exception do |jms_exception|
50
+ logger.error "JMS Connection Exception has occurred: #{jms_exception}" if logger
51
+ #TODO: Close all sessions in the pool and release from the pool?
52
+ end
53
+ end
54
+
55
+ # Obtain a session from the pool and pass it to the supplied block
56
+ # The session is automatically returned to the pool once the block completes
57
+ def session(&block)
58
+ #TODO Check if session is open?
59
+ @pool.with_connection &block
60
+ #TODO Catch connection failures and release from pool?
61
+ end
62
+
63
+ # Obtain a session from the pool and create a MessageConsumer.
64
+ # Pass both into the supplied block.
65
+ # Once the block is complete the consumer is closed and the session is
66
+ # returned to the pool.
67
+ #
68
+ # Parameters:
69
+ # :queue_name => String: Name of the Queue to return
70
+ # Symbol: :temporary => Create temporary queue
71
+ # Mandatory unless :topic_name is supplied
72
+ # Or,
73
+ # :topic_name => String: Name of the Topic to write to or subscribe to
74
+ # Symbol: :temporary => Create temporary topic
75
+ # Mandatory unless :queue_name is supplied
76
+ # Or,
77
+ # :destination=> Explicit javaxJms::Destination to use
78
+ #
79
+ # :selector => Filter which messages should be returned from the queue
80
+ # Default: All messages
81
+ # :no_local => Determine whether messages published by its own connection
82
+ # should be delivered to it
83
+ # Default: false
84
+ #
85
+ # Example
86
+ # session_pool.consumer(:queue_name => 'MyQueue') do |session, consumer|
87
+ # message = consumer.receive(timeout)
88
+ # puts message.data if message
89
+ # end
90
+ def consumer(params, &block)
91
+ session do |s|
92
+ consumer = nil
93
+ begin
94
+ consumer = s.consumer(params)
95
+ block.call(s, consumer)
96
+ ensure
97
+ consumer.close if consumer
98
+ end
99
+ end
100
+ end
101
+
102
+ # Obtain a session from the pool and create a MessageProducer.
103
+ # Pass both into the supplied block.
104
+ # Once the block is complete the producer is closed and the session is
105
+ # returned to the pool.
106
+ #
107
+ # Parameters:
108
+ # :queue_name => String: Name of the Queue to send messages to
109
+ # Symbol: :temporary => Create temporary queue
110
+ # Mandatory unless :topic_name is supplied
111
+ # Or,
112
+ # :topic_name => String: Name of the Topic to send message to
113
+ # Symbol: :temporary => Create temporary topic
114
+ # Mandatory unless :queue_name is supplied
115
+ # Or,
116
+ # :destination=> Explicit JMS::Destination to use
117
+ #
118
+ # Example
119
+ # session_pool.producer(:queue_name => 'ExampleQueue') do |session, producer|
120
+ # producer.send(session.message("Hello World"))
121
+ # end
122
+ def producer(params, &block)
123
+ session do |s|
124
+ producer = nil
125
+ begin
126
+ producer = s.producer(params)
127
+ block.call(s, producer)
128
+ ensure
129
+ producer.close if producer
130
+ end
131
+ end
132
+ end
133
+
134
+ # Immediately Close all sessions in the pool and release from the pool
135
+ #
136
+ # TODO: Allow an option to wait for active sessions to be returned before
137
+ # closing
138
+ def close
139
+ @pool.each do |s|
140
+ #@pool.remove(s)
141
+ s.close
142
+ #@pool.remove(s)
143
+ end
144
+ end
145
+
146
+ end
147
+
148
+ end
@@ -15,7 +15,7 @@
15
15
  ################################################################################
16
16
 
17
17
  #Interface javax.jms.TextMessage
18
- module javax.jms::TextMessage
18
+ module JMS::TextMessage
19
19
  def data
20
20
  getText
21
21
  end
@@ -12,12 +12,14 @@ class JMSTest < Test::Unit::TestCase
12
12
  # Load configuration from jms.yml
13
13
  setup do
14
14
  # To change the JMS provider, edit jms.yml and change :default
15
-
15
+
16
16
  # Load Connection parameters from configuration file
17
17
  cfg = YAML.load_file(File.join(File.dirname(__FILE__), 'jms.yml'))
18
18
  jms_provider = cfg['default']
19
19
  @config = cfg[jms_provider]
20
20
  raise "JMS Provider option:#{jms_provider} not found in jms.yml file" unless @config
21
+ @queue_name = @config.delete(:queue_name) || raise("Mandatory :queue_name missing from jms.yml")
22
+ @topic_name = @config.delete(:topic_name) || raise("Mandatory :topic_name missing from jms.yml")
21
23
  end
22
24
 
23
25
  should 'Create Connection to the Broker/Server' do
@@ -32,114 +34,114 @@ class JMSTest < Test::Unit::TestCase
32
34
  assert_not_nil connection
33
35
  end
34
36
  end
35
-
37
+
36
38
  should 'Create and start Connection to the Broker/Server with block and start one session' do
37
39
  JMS::Connection.session(@config) do |session|
38
40
  assert_not_nil session
39
41
  end
40
42
  end
41
-
43
+
42
44
  should 'Start and stop connection' do
43
45
  connection = JMS::Connection.new(@config)
44
46
  assert_not_nil connection
45
47
  assert_nil connection.start
46
-
48
+
47
49
  assert_nil connection.stop
48
50
  assert_nil connection.close
49
51
  end
50
52
 
51
53
  should 'Create a session from the connection' do
52
54
  connection = JMS::Connection.new(@config)
53
-
54
- session_parms = {
55
+
56
+ session_parms = {
55
57
  :transacted => true,
56
- :options => javax.jms.Session::AUTO_ACKNOWLEDGE
58
+ :options => JMS::Session::AUTO_ACKNOWLEDGE
57
59
  }
58
60
 
59
61
  session = connection.create_session
60
62
  assert_not_nil session
61
63
  assert_equal session.transacted?, false
62
64
  assert_nil session.close
63
-
65
+
64
66
  assert_nil connection.stop
65
67
  assert_nil connection.close
66
68
  end
67
69
 
68
70
  should 'Create a session with a block' do
69
71
  connection = JMS::Connection.new(@config)
70
-
72
+
71
73
  connection.session do |session|
72
74
  assert_not_nil session
73
75
  assert_equal session.transacted?, false
74
76
  end
75
-
77
+
76
78
  assert_nil connection.stop
77
79
  assert_nil connection.close
78
80
  end
79
81
 
80
82
  should 'create a session without a block and throw exception' do
81
83
  connection = JMS::Connection.new(@config)
82
-
84
+
83
85
  assert_raise(RuntimeError) { connection.session }
84
-
86
+
85
87
  assert_nil connection.stop
86
88
  assert_nil connection.close
87
89
  end
88
90
 
89
91
  should 'Create a session from the connection with params' do
90
92
  connection = JMS::Connection.new(@config)
91
-
92
- session_parms = {
93
+
94
+ session_parms = {
93
95
  :transacted => true,
94
- :options => javax.jms.Session::AUTO_ACKNOWLEDGE
96
+ :options => JMS::Session::AUTO_ACKNOWLEDGE
95
97
  }
96
98
 
97
99
  session = connection.create_session(session_parms)
98
100
  assert_not_nil session
99
101
  assert_equal session.transacted?, true
100
102
  # When session is transacted, options are ignore, so ack mode must be transacted
101
- assert_equal session.acknowledge_mode, javax.jms.Session::SESSION_TRANSACTED
103
+ assert_equal session.acknowledge_mode, JMS::Session::SESSION_TRANSACTED
102
104
  assert_nil session.close
103
-
105
+
104
106
  assert_nil connection.stop
105
107
  assert_nil connection.close
106
108
  end
107
109
 
108
110
  should 'Create a session from the connection with block and params' do
109
111
  JMS::Connection.start(@config) do |connection|
110
-
111
- session_parms = {
112
+
113
+ session_parms = {
112
114
  :transacted => true,
113
- :options => javax.jms.Session::CLIENT_ACKNOWLEDGE
115
+ :options => JMS::Session::CLIENT_ACKNOWLEDGE
114
116
  }
115
117
 
116
118
  connection.session(session_parms) do |session|
117
119
  assert_not_nil session
118
120
  assert_equal session.transacted?, true
119
121
  # When session is transacted, options are ignore, so ack mode must be transacted
120
- assert_equal session.acknowledge_mode, javax.jms.Session::SESSION_TRANSACTED
122
+ assert_equal session.acknowledge_mode, JMS::Session::SESSION_TRANSACTED
121
123
  end
122
124
  end
123
125
  end
124
126
 
125
127
  should 'Create a session from the connection with block and params opposite test' do
126
128
  JMS::Connection.start(@config) do |connection|
127
-
128
- session_parms = {
129
+
130
+ session_parms = {
129
131
  :transacted => false,
130
- :options => javax.jms.Session::AUTO_ACKNOWLEDGE
132
+ :options => JMS::Session::AUTO_ACKNOWLEDGE
131
133
  }
132
134
 
133
135
  connection.session(session_parms) do |session|
134
136
  assert_not_nil session
135
137
  assert_equal session.transacted?, false
136
- assert_equal session.acknowledge_mode, javax.jms.Session::AUTO_ACKNOWLEDGE
138
+ assert_equal session.acknowledge_mode, JMS::Session::AUTO_ACKNOWLEDGE
137
139
  end
138
140
  end
139
141
  end
140
-
142
+
141
143
  context 'JMS Connection additional capabilities' do
142
-
144
+
143
145
  should 'start an on_message handler' do
144
146
  JMS::Connection.start(@config) do |connection|
145
147
  value = nil
@@ -148,8 +150,8 @@ class JMSTest < Test::Unit::TestCase
148
150
  end
149
151
  end
150
152
  end
151
-
153
+
152
154
  end
153
-
155
+
154
156
  end
155
157
  end