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.
- data/HISTORY.md +15 -0
- data/README.md +27 -28
- data/Rakefile +7 -1
- data/doc/classes/JMS.html +265 -0
- data/doc/classes/JMS/BytesMessage.html +215 -0
- data/doc/classes/JMS/Connection.html +1145 -0
- data/doc/classes/JMS/MapMessage.html +333 -0
- data/doc/classes/JMS/Message.html +1085 -0
- data/doc/classes/JMS/MessageConsumer.html +316 -0
- data/doc/classes/JMS/MessageListenerImpl.html +262 -0
- data/doc/classes/JMS/ObjectMessage.html +170 -0
- data/doc/classes/JMS/OracleAQConnectionFactory.html +184 -0
- data/doc/classes/JMS/QueueBrowser.html +155 -0
- data/doc/classes/JMS/Session.html +947 -0
- data/doc/classes/JMS/SessionPool.html +411 -0
- data/doc/classes/JMS/TextMessage.html +194 -0
- data/doc/created.rid +1 -0
- data/doc/files/README_md.html +440 -0
- data/doc/files/lib/jms/bytes_message_rb.html +122 -0
- data/doc/files/lib/jms/connection_rb.html +140 -0
- data/doc/files/lib/jms/imports_rb.html +108 -0
- data/doc/files/lib/jms/logging_rb.html +129 -0
- data/doc/files/lib/jms/map_message_rb.html +122 -0
- data/doc/files/lib/jms/message_consumer_rb.html +122 -0
- data/doc/files/lib/jms/message_listener_impl_rb.html +122 -0
- data/doc/files/lib/jms/message_rb.html +122 -0
- data/doc/files/lib/jms/object_message_rb.html +122 -0
- data/doc/files/lib/jms/oracle_a_q_connection_factory_rb.html +122 -0
- data/doc/files/lib/jms/queue_browser_rb.html +122 -0
- data/doc/files/lib/jms/session_pool_rb.html +108 -0
- data/doc/files/lib/jms/session_rb.html +164 -0
- data/doc/files/lib/jms/text_message_rb.html +122 -0
- data/doc/files/lib/jms_rb.html +131 -0
- data/doc/fr_class_index.html +39 -0
- data/doc/fr_file_index.html +42 -0
- data/doc/fr_method_index.html +120 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/examples/advanced/session_pool.rb +37 -0
- data/examples/client-server/replier.rb +29 -0
- data/examples/client-server/requestor.rb +40 -0
- data/examples/jms.yml +85 -9
- data/examples/performance/consumer.rb +6 -8
- data/examples/performance/producer.rb +10 -10
- data/examples/producer-consumer/browser.rb +24 -0
- data/examples/{consumer.rb → producer-consumer/consumer.rb} +5 -4
- data/examples/producer-consumer/consumer_async.rb +30 -0
- data/examples/{producer.rb → producer-consumer/producer.rb} +5 -3
- data/examples/publish-subscribe/publish.rb +24 -0
- data/examples/publish-subscribe/subscribe.rb +31 -0
- data/lib/jms/bytes_message.rb +52 -0
- data/lib/jms/connection.rb +170 -162
- data/lib/jms/imports.rb +21 -0
- data/lib/jms/logging.rb +17 -1
- data/lib/jms/{javax_jms_map_message.rb → map_message.rb} +2 -2
- data/lib/jms/message.rb +285 -0
- data/lib/jms/{javax_jms_message_consumer.rb → message_consumer.rb} +6 -3
- data/lib/jms/{message_listener.rb → message_listener_impl.rb} +3 -3
- data/lib/jms/{javax_jms_object_message.rb → object_message.rb} +1 -1
- data/lib/jms/oracle_a_q_connection_factory.rb +35 -0
- data/lib/jms/{javax_jms_queue_browser.rb → queue_browser.rb} +5 -4
- data/lib/jms/{javax_jms_session.rb → session.rb} +23 -25
- data/lib/jms/session_pool.rb +148 -0
- data/lib/jms/{javax_jms_text_message.rb → text_message.rb} +1 -1
- data/test/connection_test.rb +31 -29
- data/test/jms.yml +8 -9
- data/test/message_test.rb +29 -29
- data/test/session_test.rb +39 -39
- metadata +62 -22
- 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
|
-
|
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?(
|
172
|
-
|
173
|
-
# :
|
174
|
-
queue_name = params[:queue_name] || params[:
|
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
|
295
|
+
# :destination=> Explicit JMS::Destination to use
|
295
296
|
def producer(params, &proc)
|
296
|
-
|
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
|
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
|
data/test/connection_test.rb
CHANGED
@@ -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 =>
|
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 =>
|
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,
|
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 =>
|
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,
|
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 =>
|
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,
|
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
|