jruby-jms 0.10.2 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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