jruby-jms 1.1.0-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 (51) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +8 -0
  3. data/Gemfile.lock +36 -0
  4. data/HISTORY.md +52 -0
  5. data/LICENSE.txt +201 -0
  6. data/README.md +205 -0
  7. data/Rakefile +30 -0
  8. data/examples/advanced/session_pool.rb +37 -0
  9. data/examples/client-server/replier.rb +29 -0
  10. data/examples/client-server/requestor.rb +40 -0
  11. data/examples/file-to-q/files_to_q.rb +51 -0
  12. data/examples/file-to-q/q_to_files.rb +44 -0
  13. data/examples/invm/invm.rb +44 -0
  14. data/examples/invm/log4j.properties +58 -0
  15. data/examples/jms.yml +149 -0
  16. data/examples/performance/consumer.rb +25 -0
  17. data/examples/performance/producer.rb +31 -0
  18. data/examples/producer-consumer/browser.rb +24 -0
  19. data/examples/producer-consumer/consumer.rb +24 -0
  20. data/examples/producer-consumer/consumer_async.rb +41 -0
  21. data/examples/producer-consumer/producer.rb +25 -0
  22. data/examples/publish-subscribe/publish.rb +24 -0
  23. data/examples/publish-subscribe/subscribe.rb +31 -0
  24. data/lib/jms.rb +20 -0
  25. data/lib/jms/bytes_message.rb +52 -0
  26. data/lib/jms/connection.rb +529 -0
  27. data/lib/jms/imports.rb +21 -0
  28. data/lib/jms/logging.rb +50 -0
  29. data/lib/jms/map_message.rb +91 -0
  30. data/lib/jms/message.rb +285 -0
  31. data/lib/jms/message_consumer.rb +117 -0
  32. data/lib/jms/message_listener_impl.rb +79 -0
  33. data/lib/jms/message_producer.rb +59 -0
  34. data/lib/jms/mq_workaround.rb +70 -0
  35. data/lib/jms/object_message.rb +26 -0
  36. data/lib/jms/oracle_a_q_connection_factory.rb +48 -0
  37. data/lib/jms/queue_browser.rb +28 -0
  38. data/lib/jms/session.rb +473 -0
  39. data/lib/jms/session_pool.rb +168 -0
  40. data/lib/jms/text_message.rb +31 -0
  41. data/lib/jms/version.rb +3 -0
  42. data/nbproject/private/private.properties +3 -0
  43. data/nbproject/private/rake-d.txt +5 -0
  44. data/parallel_minion.gemspec +21 -0
  45. data/test/connection_test.rb +160 -0
  46. data/test/jms.yml +111 -0
  47. data/test/log4j.properties +32 -0
  48. data/test/message_test.rb +130 -0
  49. data/test/session_pool_test.rb +86 -0
  50. data/test/session_test.rb +140 -0
  51. metadata +113 -0
@@ -0,0 +1,168 @@
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_timeout Number of seconds to wait before raising a TimeoutError
23
+ # if no sessions are available in the poo
24
+ # Default: 60
25
+ # :pool_warn_timeout Number of seconds to wait before logging a warning when a
26
+ # session in the pool is not available
27
+ # Default: 5
28
+ # :pool_logger Supply a logger that responds to #debug, #info, #warn and #debug?
29
+ # For example: Rails.logger
30
+ # Default: JMS.logger
31
+ # Example:
32
+ # session_pool = connection.create_session_pool(config)
33
+ # session_pool.session do |session|
34
+ # ....
35
+ # end
36
+ class SessionPool
37
+ def initialize(connection, params={})
38
+ # Save Session params since it will be used every time a new session is
39
+ # created in the pool
40
+ session_params = params.nil? ? {} : params.dup
41
+ logger = session_params[:pool_logger] || JMS.logger
42
+ # Define how GenePool can create new sessions
43
+ @pool = GenePool.new(
44
+ :name => session_params[:pool_name] || self.class.name,
45
+ :pool_size => session_params[:pool_size] || 10,
46
+ :warn_timeout => session_params[:pool_warn_timeout] || 5,
47
+ :timeout => session_params[:pool_timeout] || 60,
48
+ :close_proc => nil,
49
+ :logger => logger) do
50
+ connection.create_session(session_params)
51
+ end
52
+
53
+ # Handle connection failures
54
+ connection.on_exception do |jms_exception|
55
+ logger.error "JMS Connection Exception has occurred: #{jms_exception}" if logger
56
+ #TODO: Close all sessions in the pool and release from the pool?
57
+ end
58
+ end
59
+
60
+ # Obtain a session from the pool and pass it to the supplied block
61
+ # The session is automatically returned to the pool once the block completes
62
+ #
63
+ # In the event a JMS Exception is thrown the session will be closed and removed
64
+ # from the pool to prevent re-using sessions that are no longer valid
65
+ def session(&block)
66
+ s = nil
67
+ begin
68
+ s = @pool.checkout
69
+ block.call(s)
70
+ rescue javax.jms.JMSException => e
71
+ s.close rescue nil
72
+ @pool.remove(s)
73
+ s = nil # Do not check back in since we have removed it
74
+ raise e
75
+ ensure
76
+ @pool.checkin(s) if s
77
+ end
78
+ end
79
+
80
+ # Obtain a session from the pool and create a MessageConsumer.
81
+ # Pass both into the supplied block.
82
+ # Once the block is complete the consumer is closed and the session is
83
+ # returned to the pool.
84
+ #
85
+ # Parameters:
86
+ # :queue_name => String: Name of the Queue to return
87
+ # Symbol: :temporary => Create temporary queue
88
+ # Mandatory unless :topic_name is supplied
89
+ # Or,
90
+ # :topic_name => String: Name of the Topic to write to or subscribe to
91
+ # Symbol: :temporary => Create temporary topic
92
+ # Mandatory unless :queue_name is supplied
93
+ # Or,
94
+ # :destination=> Explicit javaxJms::Destination to use
95
+ #
96
+ # :selector => Filter which messages should be returned from the queue
97
+ # Default: All messages
98
+ # :no_local => Determine whether messages published by its own connection
99
+ # should be delivered to it
100
+ # Default: false
101
+ #
102
+ # Example
103
+ # session_pool.consumer(:queue_name => 'MyQueue') do |session, consumer|
104
+ # message = consumer.receive(timeout)
105
+ # puts message.data if message
106
+ # end
107
+ def consumer(params, &block)
108
+ session do |s|
109
+ consumer = nil
110
+ begin
111
+ consumer = s.consumer(params)
112
+ block.call(s, consumer)
113
+ ensure
114
+ consumer.close if consumer
115
+ end
116
+ end
117
+ end
118
+
119
+ # Obtain a session from the pool and create a MessageProducer.
120
+ # Pass both into the supplied block.
121
+ # Once the block is complete the producer is closed and the session is
122
+ # returned to the pool.
123
+ #
124
+ # Parameters:
125
+ # :queue_name => String: Name of the Queue to send messages to
126
+ # Symbol: :temporary => Create temporary queue
127
+ # Mandatory unless :topic_name is supplied
128
+ # Or,
129
+ # :topic_name => String: Name of the Topic to send message to
130
+ # Symbol: :temporary => Create temporary topic
131
+ # Mandatory unless :queue_name is supplied
132
+ # Or,
133
+ # :destination=> Explicit JMS::Destination to use
134
+ #
135
+ # Example
136
+ # session_pool.producer(:queue_name => 'ExampleQueue') do |session, producer|
137
+ # producer.send(session.message("Hello World"))
138
+ # end
139
+ def producer(params, &block)
140
+ session do |s|
141
+ producer = nil
142
+ begin
143
+ producer = s.producer(params)
144
+ block.call(s, producer)
145
+ ensure
146
+ producer.close if producer
147
+ end
148
+ end
149
+ end
150
+
151
+ # Immediately Close all sessions in the pool and release from the pool
152
+ #
153
+ # Note: This is an immediate close, active sessions will be aborted
154
+ #
155
+ # Note: Once closed a session pool cannot be re-used. A new instance must
156
+ # be created
157
+ #
158
+ # TODO: Allow an option to wait for active sessions to be returned before
159
+ # closing
160
+ def close
161
+ @pool.each do |s|
162
+ s.close
163
+ end
164
+ end
165
+
166
+ end
167
+
168
+ end
@@ -0,0 +1,31 @@
1
+ ################################################################################
2
+ # Copyright 2008, 2009, 2010, 2011 J. Reid Morrison
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ ################################################################################
16
+
17
+ #Interface javax.jms.TextMessage
18
+ module JMS::TextMessage
19
+ def data
20
+ getText
21
+ end
22
+
23
+ def data=(val)
24
+ setText(val.to_s)
25
+ end
26
+
27
+ def to_s
28
+ data
29
+ end
30
+
31
+ end
@@ -0,0 +1,3 @@
1
+ module JMS #:nodoc
2
+ VERSION = "1.1.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ file.reference.jruby-jms-examples=/Users/rmorrison/Sandbox/jruby-jms/examples
2
+ file.reference.jruby-jms-lib=/Users/rmorrison/Sandbox/jruby-jms/lib
3
+ file.reference.jruby-jms-test=/Users/rmorrison/Sandbox/jruby-jms/test
@@ -0,0 +1,5 @@
1
+ clean=Remove any temporary products.
2
+ clobber=Remove any generated file.
3
+ doc=Generate RDOC documentation
4
+ gem=Build gem
5
+ test=Run Test Suite
@@ -0,0 +1,21 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ # Maintain gem's version:
4
+ require 'jms/version'
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'jruby-jms'
9
+ spec.version = JMS::VERSION
10
+ spec.platform = 'java'
11
+ spec.authors = ['Reid Morrison']
12
+ spec.email = ['reidmo@gmail.com']
13
+ spec.homepage = 'https://github.com/reidmorrison/jruby-jms'
14
+ spec.summary = 'JRuby interface into JMS'
15
+ spec.description = 'JRuby-JMS is a Java and Ruby library that exposes the Java JMS API in a ruby friendly way. For JRuby only.'
16
+ spec.files = FileList["./**/*"].exclude('*.gem', './nbproject/*').map{|f| f.sub(/^\.\//, '')}
17
+ spec.test_files = Dir["test/**/*"]
18
+ spec.license = "Apache License V2.0"
19
+ spec.has_rdoc = true
20
+ spec.add_dependency 'gene_pool'
21
+ end
@@ -0,0 +1,160 @@
1
+ # Allow examples to be run in-place without requiring a gem install
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'shoulda'
7
+ require 'jms'
8
+ require 'yaml'
9
+
10
+ # Set Log4J properties file so that it does not need to be in the CLASSPATH
11
+ java.lang.System.properties['log4j.configuration'] = "test/log4j.properties"
12
+
13
+ class JMSTest < Test::Unit::TestCase
14
+ context 'JMS Connection' do
15
+ # Load configuration from jms.yml
16
+ setup do
17
+ # To change the JMS provider, edit jms.yml and change :default
18
+
19
+ # Load Connection parameters from configuration file
20
+ cfg = YAML.load_file(File.join(File.dirname(__FILE__), 'jms.yml'))
21
+ jms_provider = cfg['default']
22
+ @config = cfg[jms_provider]
23
+ raise "JMS Provider option:#{jms_provider} not found in jms.yml file" unless @config
24
+ @queue_name = @config.delete(:queue_name) || raise("Mandatory :queue_name missing from jms.yml")
25
+ @topic_name = @config.delete(:topic_name) || raise("Mandatory :topic_name missing from jms.yml")
26
+ end
27
+
28
+ should 'Create Connection to the Broker/Server' do
29
+ connection = JMS::Connection.new(@config)
30
+ JMS::logger.info connection.to_s
31
+ assert_not_nil connection
32
+ connection.close
33
+ end
34
+
35
+ should 'Create and start Connection to the Broker/Server with block' do
36
+ JMS::Connection.start(@config) do |connection|
37
+ assert_not_nil connection
38
+ end
39
+ end
40
+
41
+ should 'Create and start Connection to the Broker/Server with block and start one session' do
42
+ JMS::Connection.session(@config) do |session|
43
+ assert_not_nil session
44
+ end
45
+ end
46
+
47
+ should 'Start and stop connection' do
48
+ connection = JMS::Connection.new(@config)
49
+ assert_not_nil connection
50
+ assert_nil connection.start
51
+
52
+ assert_nil connection.stop
53
+ assert_nil connection.close
54
+ end
55
+
56
+ should 'Create a session from the connection' do
57
+ connection = JMS::Connection.new(@config)
58
+
59
+ session_parms = {
60
+ :transacted => true,
61
+ :options => JMS::Session::AUTO_ACKNOWLEDGE
62
+ }
63
+
64
+ session = connection.create_session
65
+ assert_not_nil session
66
+ assert_equal session.transacted?, false
67
+ assert_nil session.close
68
+
69
+ assert_nil connection.stop
70
+ assert_nil connection.close
71
+ end
72
+
73
+ should 'Create a session with a block' do
74
+ connection = JMS::Connection.new(@config)
75
+
76
+ connection.session do |session|
77
+ assert_not_nil session
78
+ assert_equal session.transacted?, false
79
+ end
80
+
81
+ assert_nil connection.stop
82
+ assert_nil connection.close
83
+ end
84
+
85
+ should 'create a session without a block and throw exception' do
86
+ connection = JMS::Connection.new(@config)
87
+
88
+ assert_raise(RuntimeError) { connection.session }
89
+
90
+ assert_nil connection.stop
91
+ assert_nil connection.close
92
+ end
93
+
94
+ should 'Create a session from the connection with params' do
95
+ connection = JMS::Connection.new(@config)
96
+
97
+ session_parms = {
98
+ :transacted => true,
99
+ :options => JMS::Session::AUTO_ACKNOWLEDGE
100
+ }
101
+
102
+ session = connection.create_session(session_parms)
103
+ assert_not_nil session
104
+ assert_equal session.transacted?, true
105
+ # When session is transacted, options are ignore, so ack mode must be transacted
106
+ assert_equal session.acknowledge_mode, JMS::Session::SESSION_TRANSACTED
107
+ assert_nil session.close
108
+
109
+ assert_nil connection.stop
110
+ assert_nil connection.close
111
+ end
112
+
113
+ should 'Create a session from the connection with block and params' do
114
+ JMS::Connection.start(@config) do |connection|
115
+
116
+ session_parms = {
117
+ :transacted => true,
118
+ :options => JMS::Session::CLIENT_ACKNOWLEDGE
119
+ }
120
+
121
+ connection.session(session_parms) do |session|
122
+ assert_not_nil session
123
+ assert_equal session.transacted?, true
124
+ # When session is transacted, options are ignore, so ack mode must be transacted
125
+ assert_equal session.acknowledge_mode, JMS::Session::SESSION_TRANSACTED
126
+ end
127
+ end
128
+ end
129
+
130
+ should 'Create a session from the connection with block and params opposite test' do
131
+ JMS::Connection.start(@config) do |connection|
132
+
133
+ session_parms = {
134
+ :transacted => false,
135
+ :options => JMS::Session::AUTO_ACKNOWLEDGE
136
+ }
137
+
138
+ connection.session(session_parms) do |session|
139
+ assert_not_nil session
140
+ assert_equal session.transacted?, false
141
+ assert_equal session.acknowledge_mode, JMS::Session::AUTO_ACKNOWLEDGE
142
+ end
143
+ end
144
+ end
145
+
146
+ context 'JMS Connection additional capabilities' do
147
+
148
+ should 'start an on_message handler' do
149
+ JMS::Connection.start(@config) do |connection|
150
+ value = nil
151
+ connection.on_message(:transacted => true, :queue_name => :temporary) do |message|
152
+ value = "received"
153
+ end
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ end
160
+ end
@@ -0,0 +1,111 @@
1
+ # This YAML file contains the configuration options for several different
2
+ # JMS Providers
3
+ #
4
+ # The Examples that ship with jruby-jms will use the entry 'default' unless
5
+ # overriden at the command line. For example:
6
+ # jruby producer.rb activemq
7
+ #
8
+ ---
9
+ # Which JMS Provider to use by default
10
+
11
+ #default: hornetq222
12
+ #default: hornetq225
13
+ #default: activemq543
14
+ #default: activemq551
15
+ default: activemq590
16
+ #default: webspheremq6
17
+ #default: webspheremq7
18
+
19
+ activemq543:
20
+ :factory: org.apache.activemq.ActiveMQConnectionFactory
21
+ :broker_url: tcp://localhost:61616
22
+ :require_jars:
23
+ - ~/jms/apache-activemq-5.4.3/activemq-all-5.4.3.jar
24
+ :queue_name: TestQueue
25
+ :topic_name: TestTopic
26
+
27
+ activemq551:
28
+ :factory: org.apache.activemq.ActiveMQConnectionFactory
29
+ :broker_url: tcp://localhost:61616
30
+ :require_jars:
31
+ - ~/jms/apache-activemq-5.5.1/activemq-all-5.5.1.jar
32
+ - ~/jms/apache-activemq-5.5.1/lib/optional/slf4j-log4j12-1.5.11.jar
33
+ - ~/jms/apache-activemq-5.5.1/lib/optional/log4j-1.2.14.jar
34
+ :queue_name: TestQueue
35
+ :topic_name: TestTopic
36
+
37
+ activemq590:
38
+ :factory: org.apache.activemq.ActiveMQConnectionFactory
39
+ :broker_url: tcp://localhost:61616
40
+ :require_jars:
41
+ - /usr/local/Cellar/activemq/5.9.0/libexec/activemq-all-5.9.0.jar
42
+ - /usr/local/Cellar/activemq/5.9.0/libexec/lib/optional/log4j-1.2.17.jar
43
+ :queue_name: TestQueue
44
+ :topic_name: TestTopic
45
+
46
+ hornetq225:
47
+ # Connect to a local HornetQ Broker using JNDI
48
+ :jndi_name: /ConnectionFactory
49
+ :jndi_context:
50
+ java.naming.factory.initial: org.jnp.interfaces.NamingContextFactory
51
+ java.naming.provider.url: jnp://localhost:1099
52
+ java.naming.factory.url.pkgs: org.jboss.naming:org.jnp.interfaces
53
+ java.naming.security.principal: guest
54
+ java.naming.security.credentials: guest
55
+ :require_jars:
56
+ - ~/jms/hornetq-2.2.5.Final/lib/hornetq-core-client.jar
57
+ - ~/jms/hornetq-2.2.5.Final/lib/netty.jar
58
+ - ~/jms/hornetq-2.2.5.Final/lib/hornetq-jms-client.jar
59
+ - ~/jms/hornetq-2.2.5.Final/lib/jboss-jms-api.jar
60
+ - ~/jms/hornetq-2.2.5.Final/lib/jnp-client.jar
61
+ :queue_name: TestQueue
62
+ :topic_name: TestTopic
63
+
64
+ hornetq222:
65
+ # Connect to a local HornetQ Broker using JNDI
66
+ :jndi_name: /ConnectionFactory
67
+ :jndi_context:
68
+ java.naming.factory.initial: org.jnp.interfaces.NamingContextFactory
69
+ java.naming.provider.url: jnp://localhost:1099
70
+ java.naming.factory.url.pkgs: org.jboss.naming:org.jnp.interfaces
71
+ java.naming.security.principal: guest
72
+ java.naming.security.credentials: guest
73
+ :require_jars:
74
+ - ~/jms/hornetq-2.2.2.Final/lib/hornetq-core-client.jar
75
+ - ~/jms/hornetq-2.2.2.Final/lib/netty.jar
76
+ - ~/jms/hornetq-2.2.2.Final/lib/hornetq-jms-client.jar
77
+ - ~/jms/hornetq-2.2.2.Final/lib/jboss-jms-api.jar
78
+ - ~/jms/hornetq-2.2.2.Final/lib/jnp-client.jar
79
+ :queue_name: TestQueue
80
+ :topic_name: TestTopic
81
+
82
+ webspheremq7:
83
+ :factory: com.ibm.mq.jms.MQConnectionFactory
84
+ :queue_manager: MYQM
85
+ :host_name: 127.0.0.1
86
+ :channel: SRVCONCHA
87
+ :port: 61414
88
+ # Transport Type: com.ibm.mq.jms.JMSC::MQJMS_TP_CLIENT_MQ_TCPIP
89
+ :transport_type: 1
90
+ :username: mqm
91
+ :require_jars:
92
+ - ~/jms/libs-ibmqm7/com.ibm.mqjms.jar
93
+ - ~/jms/libs-ibmqm7/jms.jar
94
+ - ~/jms/libs-ibmqm7/com.ibm.mq.jmqi.jar
95
+ - ~/jms/libs-ibmqm7/dhbcore.jar
96
+ :queue_name: TestQueue
97
+ :topic_name: TestTopic
98
+
99
+ webspheremq6:
100
+ :factory: com.ibm.mq.jms.MQConnectionFactory
101
+ :queue_manager: MYQM
102
+ :host_name: 127.0.0.1
103
+ :channel: SRVCONCHA
104
+ :port: 61414
105
+ # Transport Type: com.ibm.mq.jms.JMSC::MQJMS_TP_CLIENT_MQ_TCPIP
106
+ :transport_type: 1
107
+ :username: mqm
108
+ :require_jars:
109
+ - ~/jms/libs-ibmqm6/com.ibm.mqjms.jar
110
+ :queue_name: TestQueue
111
+ :topic_name: TestTopic