jruby-hornetq 0.2.3.alpha → 0.2.5.alpha

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.
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env jruby
2
+ #
3
+ # HornetQ Producer:
4
+ # Write messages to the queue
5
+ #
6
+
7
+ require 'rubygems'
8
+ require 'yaml'
9
+ require 'hornetq'
10
+ require 'logger'
11
+ require 'test_object'
12
+
13
+ config = YAML.load_file(File.dirname(__FILE__) + '/hornetq.yml')
14
+ client = config['client']
15
+
16
+ # Create a HornetQ session
17
+ logger = Logger.new($stdout)
18
+ factory = HornetQ::Client::Factory.new(client[:connector])
19
+ session_pool = factory.create_session_pool(client[:session_pool])
20
+ producer_manager = HornetQ::Client::ProducerManager.new(session_pool, client[:addresses], true)
21
+
22
+ ['HUP', 'INT', 'TERM'].each do |signal_name|
23
+ Signal.trap(signal_name) do
24
+ puts "caught #{signal_name}"
25
+ $stopped = true
26
+ end
27
+ end
28
+
29
+ $stopped = false
30
+ threads = []
31
+ (1..5).each do |i|
32
+ threads << Thread.new(i) do |thread_count|
33
+ msg_count = 0
34
+ while !$stopped
35
+ msg_count += 1
36
+ obj = TestObject.new("Message ##{thread_count}-#{msg_count}")
37
+ producer_manager.send('address1', obj)
38
+ sleep 1
39
+ end
40
+ end
41
+ end
42
+ (6..10).each do |i|
43
+ threads << Thread.new(i) do |thread_count|
44
+ msg_count = 0
45
+ while !$stopped
46
+ msg_count += 1
47
+ obj = {:thread => thread_count, :message => msg_count}
48
+ producer_manager.send('address2', obj)
49
+ sleep 2
50
+ end
51
+ end
52
+ end
53
+
54
+ threads.each { |thread| thread.join }
@@ -0,0 +1,11 @@
1
+ class TestObject
2
+ attr_reader :message
3
+
4
+ def initialize(message)
5
+ @message = message
6
+ end
7
+
8
+ def to_s
9
+ @message
10
+ end
11
+ end
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env jruby
2
+ #
3
+ # HornetQ Consumer:
4
+ # Write messages to the queue
5
+ #
6
+
7
+ require 'rubygems'
8
+ require 'yaml'
9
+ require 'hornetq'
10
+ require 'test_object'
11
+
12
+ $config = YAML.load_file(File.dirname(__FILE__) + '/hornetq.yml')
13
+ $client = $config['client']
14
+ factory = HornetQ::Client::Factory.new($client[:connector])
15
+ $consumer_manager = HornetQ::Client::ConsumerManager.new(factory, $client[:session], $client[:addresses])
16
+
17
+ ['HUP', 'INT', 'TERM'].each do |signal_name|
18
+ Signal.trap(signal_name) do
19
+ puts "caught #{signal_name}"
20
+ consumer_manager.close
21
+ end
22
+ end
23
+
24
+ $threads = []
25
+ def create_workers(address, queue, count, sleep_time)
26
+ address_config = $client[:addresses][address]
27
+ queue_config = address_config[:queues][queue]
28
+ (1..count).each do |i|
29
+ $threads << Thread.new(i) do |thread_count|
30
+ prefix = "#{address}-#{queue}-#{thread_count}"
31
+ begin
32
+ $consumer_manager.each(address,queue) do |obj|
33
+ puts "#{prefix} read #{obj.inspect}"
34
+ sleep sleep_time
35
+ end
36
+ puts "#{prefix} end of thread"
37
+ rescue Exception => e
38
+ puts "#{prefix} Exception: #{e.message}\n#{e.backtrace.join("\n")}"
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ create_workers('address1', 'queue1_1', 5, 1)
45
+ create_workers('address1', 'queue1_2', 5, 2)
46
+ create_workers('address2', 'queue2_1', 5, 2)
47
+ create_workers('address2', 'queue2_2', 5, 1)
48
+
49
+ $threads.each { |thread| thread.join }
data/lib/hornetq.rb CHANGED
@@ -1,7 +1,4 @@
1
1
  include Java
2
- require 'hornetq/server'
3
- require 'hornetq/client'
4
- require 'hornetq/uri'
5
2
 
6
3
  module HornetQ
7
4
 
@@ -27,4 +24,10 @@ module HornetQ
27
24
  port ||= DEFAULT_NETTY_PORT
28
25
  return java.lang.Integer.new(port)
29
26
  end
27
+
30
28
  end
29
+
30
+ require 'hornetq/server'
31
+ require 'hornetq/client'
32
+ require 'hornetq/uri'
33
+ require 'hornetq/common/logging'
@@ -1,19 +1,22 @@
1
+ HornetQ.require_jar 'hornetq-core-client'
2
+ HornetQ.require_jar 'netty'
3
+
1
4
  module HornetQ
2
5
  module Client
3
- # Only load as needed
4
- def self.load_requirements
5
- HornetQ.require_jar 'hornetq-core-client'
6
- HornetQ.require_jar 'netty'
7
- require 'hornetq/client/org_hornetq_api_core_client_client_session'
8
- require 'hornetq/client/org_hornetq_core_client_impl_client_message_impl'
9
- require 'hornetq/client/org_hornetq_utils_typed_properties'
10
-
11
- # Import Message Constants
12
- import Java::org.hornetq.api.core::Message
13
- end
6
+ # Import Message Constants
7
+ java_import Java::org.hornetq.api.core::Message
14
8
  end
15
9
  end
16
10
 
17
11
  require 'hornetq/client/factory'
18
- require 'hornetq/client/requestor'
19
- require 'hornetq/client/server'
12
+ require 'hornetq/common/org_hornetq_core_logging_logger'
13
+ require 'hornetq/client/org_hornetq_api_core_client_client_session'
14
+ require 'hornetq/client/org_hornetq_core_client_impl_client_message_impl'
15
+ require 'hornetq/client/org_hornetq_core_client_impl_client_consumer_impl'
16
+ require 'hornetq/client/org_hornetq_core_client_impl_client_producer_impl'
17
+ require 'hornetq/client/org_hornetq_utils_typed_properties'
18
+ require 'hornetq/common/logging'
19
+ require 'hornetq/common/log_delegate'
20
+ require 'hornetq/client/message_handler'
21
+ require 'hornetq/client/requestor_pattern'
22
+ require 'hornetq/client/server_pattern'
@@ -1,378 +1,443 @@
1
- require 'uri'
1
+ module HornetQ
2
+ module Client
2
3
 
3
- module HornetQ::Client
4
-
5
- class Factory
6
- # Create a new Factory from which sessions can be created
7
- #
8
- # Parameters:
9
- # * a Hash consisting of one or more of the named parameters
10
- # * Summary of parameters and their default values
11
- # HornetQ::Client::Factory.new(
12
- # :uri => 'hornetq://localhost',
13
- # :ack_batch_size => ,
14
- # :auto_group => ,
15
- # :block_on_acknowledge => ,
16
- # :block_on_durable_send => ,
17
- # :block_on_non_durable_send => ,
18
- # :cache_large_messages_client => ,
19
- # :call_timeout => ,
20
- # :client_failure_check_period => ,
21
- # :confirmation_window_size => ,
22
- # :connection_load_balancing_policy_class_name => ,
23
- # :connection_ttl => ,
24
- # :consumer_max_rate => ,
25
- # :consumer_window_size => ,
26
- # :discovery_address => ,
27
- # :discovery_initial_wait_timeout => ,
28
- # :discovery_port => ,
29
- # :discovery_refresh_timeout => ,
30
- # :failover_on_initial_connection => true,
31
- # :failover_on_server_shutdown => true,
32
- # :group_id => ,
33
- # :initial_message_packet_size => ,
34
- # :java_object => ,
35
- # :local_bind_address => ,
36
- # :max_retry_interval => ,
37
- # :min_large_message_size => ,
38
- # :pre_acknowledge => ,
39
- # :producer_max_rate => ,
40
- # :producer_window_size => ,
41
- # :reconnect_attempts => 1,
42
- # :retry_interval => ,
43
- # :retry_interval_multiplier => ,
44
- # :scheduled_thread_pool_max_size => ,
45
- # :static_connectors => ,
46
- # :thread_pool_max_size => ,
47
- # :use_global_pools =>
48
- # )
49
- #
50
- # Mandatory Parameters
51
- # * :uri
52
- # * The hornetq uri as to which server to connect with and which
53
- # transport protocol to use. Format:
54
- # hornetq://server:port,backupserver:port/?protocol=[netty|discover]
55
- # * To use the default netty transport
56
- # hornetq://server:port
57
- # * To use the default netty transport and specify a backup server
58
- # hornetq://server:port,backupserver:port
59
- # * To use auto-discovery
60
- # hornetq://server:port/?protocol=discovery
61
- # * To use HornetQ within the current JVM
62
- # hornetq://invm
63
- #
64
- # Optional Parameters
65
- # * :ack_batch_size
66
- # * :auto_group
67
- # * :block_on_acknowledge
68
- # * :block_on_durable_send
69
- # * :block_on_non_durable_send
70
- # * :cache_large_messages_client
71
- # * :call_timeout
72
- # * :client_failure_check_period
73
- # * :confirmation_window_size
74
- # * :connection_load_balancing_policy_class_name
75
- # * :connection_ttl
76
- # * :consumer_max_rate
77
- # * :consumer_window_size
78
- # * :discovery_address
79
- # * :discovery_initial_wait_timeout
80
- # * :discovery_port
81
- # * :discovery_refresh_timeout
82
- # * :failover_on_initial_connection
83
- # * :failover_on_server_shutdown
84
- # * :group_id
85
- # * :initial_message_packet_size
86
- # * :java_object
87
- # * :local_bind_address
88
- # * :max_retry_interval
89
- # * :min_large_message_size
90
- # * :pre_acknowledge
91
- # * :producer_max_rate
92
- # * :producer_window_size
93
- # * :reconnect_attempts
94
- # * :retry_interval
95
- # * :retry_interval_multiplier
96
- # * :scheduled_thread_pool_max_size
97
- # * :static_connectors
98
- # * :thread_pool_max_size
99
- # * :use_global_pools
4
+ class Factory
5
+ # Create a new Factory and Session
6
+ #
7
+ # Creates a new factory and session, then passes the session to the supplied
8
+ # block. Upon completion the session and factory are both closed
9
+ # See Factory::initialize and Factory::create_session for the list
10
+ # of parameters
11
+ def self.session(params={},&proc)
12
+ raise "Missing mandatory code block" unless proc
13
+ factory = nil
14
+ session = nil
15
+ begin
16
+ if params.kind_of?(String)
17
+ # TODO: Support passing username and password from URI to Session
18
+ factory = self.new(params)
19
+ session = factory.session({}, &proc)
20
+ else
21
+ factory = self.new(params[:connector] || {})
22
+ session = factory.session(params[:session] || {}, &proc)
23
+ end
24
+ ensure
25
+ session.close if session
26
+ factory.close if factory
27
+ end
28
+ end
100
29
 
101
- def initialize(params={})
102
- HornetQ::Client.load_requirements
103
- uri = nil
104
- # TODO: Support :uri as an array for cluster configurations
105
- if params.kind_of?(String)
106
- uri = HornetQ::URI.new(params)
107
- params = uri.params
108
- else
109
- raise "Missing :uri param in HornetQ::Server.create_server" unless params[:uri]
110
- uri = HornetQ::URI.new(params.delete(:uri))
111
- # params override uri params
112
- params = uri.params.merge(params)
30
+ # Create a new Factory along with a Session, and then start the session
31
+ #
32
+ # Creates a new factory and session, then passes the session to the supplied
33
+ # block. Upon completion the session and factory are both closed
34
+ # See Factory::initialize and Factory::create_session for the list
35
+ # of parameters
36
+ def self.start(params={},&proc)
37
+ session(params) do |session|
38
+ session.start
39
+ proc.call(session)
40
+ end
113
41
  end
114
-
115
- @factory = nil
116
- # In-VM Transport has no fail-over or additional parameters
117
- if uri.host == 'invm'
118
- transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::INVM_CONNECTOR_CLASS_NAME)
119
- @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport)
120
- elsif params[:protocol]
121
- # Auto-Discovery just has a host name and port
122
- if params[:protocol] == 'discovery'
123
- @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(uri.host, uri.port)
124
- elsif params[:protocol] != 'netty'
125
- raise "Unknown HornetQ protocol:#{params[:protocol]}"
42
+
43
+ # Call the supplied code block after creating a factory instance
44
+ # See initialize for the parameter list
45
+ # The factory is closed before returning
46
+ #
47
+ # Returns the result of the code block
48
+ def self.create_factory(params={}, &proc)
49
+ raise "Missing mandatory code block" unless proc
50
+ factory = nil
51
+ result = nil
52
+ begin
53
+ factory=self.new(params)
54
+ result = proc.call(factory)
55
+ ensure
56
+ factory.close
126
57
  end
58
+ result
127
59
  end
128
60
 
129
- # Unless already created, then the factory will use the netty protocol
130
- unless @factory
131
- # Primary Transport
132
- transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::NETTY_CONNECTOR_CLASS_NAME, {'host' => uri.host, 'port' => uri.port })
61
+ # Create a new Factory from which sessions can be created
62
+ #
63
+ # Parameters:
64
+ # * a Hash consisting of one or more of the named parameters
65
+ # * Summary of parameters and their default values
66
+ # HornetQ::Client::Factory.new(
67
+ # :uri => 'hornetq://localhost',
68
+ # :ack_batch_size => ,
69
+ # :auto_group => ,
70
+ # :block_on_acknowledge => ,
71
+ # :block_on_durable_send => ,
72
+ # :block_on_non_durable_send => ,
73
+ # :cache_large_messages_client => ,
74
+ # :call_timeout => ,
75
+ # :client_failure_check_period => ,
76
+ # :confirmation_window_size => ,
77
+ # :connection_load_balancing_policy_class_name => ,
78
+ # :connection_ttl => ,
79
+ # :consumer_max_rate => ,
80
+ # :consumer_window_size => ,
81
+ # :discovery_address => ,
82
+ # :discovery_initial_wait_timeout => ,
83
+ # :discovery_port => ,
84
+ # :discovery_refresh_timeout => ,
85
+ # :failover_on_initial_connection => true,
86
+ # :failover_on_server_shutdown => true,
87
+ # :group_id => ,
88
+ # :initial_message_packet_size => ,
89
+ # :java_object => ,
90
+ # :local_bind_address => ,
91
+ # :max_retry_interval => ,
92
+ # :min_large_message_size => ,
93
+ # :pre_acknowledge => ,
94
+ # :producer_max_rate => ,
95
+ # :producer_window_size => ,
96
+ # :reconnect_attempts => 1,
97
+ # :retry_interval => ,
98
+ # :retry_interval_multiplier => ,
99
+ # :scheduled_thread_pool_max_size => ,
100
+ # :static_connectors => ,
101
+ # :thread_pool_max_size => ,
102
+ # :use_global_pools =>
103
+ # )
104
+ #
105
+ # Mandatory Parameters
106
+ # * :uri
107
+ # * The hornetq uri as to which server to connect with and which
108
+ # transport protocol to use. Format:
109
+ # hornetq://server:port,backupserver:port/?protocol=[netty|discover]
110
+ # * To use the default netty transport
111
+ # hornetq://server:port
112
+ # * To use the default netty transport and specify a backup server
113
+ # hornetq://server:port,backupserver:port
114
+ # * To use auto-discovery
115
+ # hornetq://server:port/?protocol=discovery
116
+ # * To use HornetQ within the current JVM
117
+ # hornetq://invm
118
+ #
119
+ # Optional Parameters
120
+ # * :ack_batch_size
121
+ # * :auto_group
122
+ # * :block_on_acknowledge
123
+ # * :block_on_durable_send
124
+ # * :block_on_non_durable_send
125
+ # * :cache_large_messages_client
126
+ # * :call_timeout
127
+ # * :client_failure_check_period
128
+ # * :confirmation_window_size
129
+ # * :connection_load_balancing_policy_class_name
130
+ # * :connection_ttl
131
+ # * :consumer_max_rate
132
+ # * :consumer_window_size
133
+ # * :discovery_address
134
+ # * :discovery_initial_wait_timeout
135
+ # * :discovery_port
136
+ # * :discovery_refresh_timeout
137
+ # * :failover_on_initial_connection
138
+ # * :failover_on_server_shutdown
139
+ # * :group_id
140
+ # * :initial_message_packet_size
141
+ # * :java_object
142
+ # * :local_bind_address
143
+ # * :max_retry_interval
144
+ # * :min_large_message_size
145
+ # * :pre_acknowledge
146
+ # * :producer_max_rate
147
+ # * :producer_window_size
148
+ # * :reconnect_attempts
149
+ # * :retry_interval
150
+ # * :retry_interval_multiplier
151
+ # * :scheduled_thread_pool_max_size
152
+ # * :static_connectors
153
+ # * :thread_pool_max_size
154
+ # * :use_global_pools
133
155
 
134
- # Check for backup server connection information
135
- if uri.backup_host
136
- backup_transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::NETTY_CONNECTOR_CLASS_NAME, {'host' => uri.backup_host, 'port' => uri.backup_port })
137
- @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport, backup_transport)
156
+ def initialize(params={})
157
+ uri = nil
158
+ # TODO: Support :uri as an array for cluster configurations
159
+ if params.kind_of?(String)
160
+ uri = HornetQ::URI.new(params)
161
+ params = uri.params
138
162
  else
163
+ raise "Missing :uri param in HornetQ::Server.create_server" unless params[:uri]
164
+ uri = HornetQ::URI.new(params.delete(:uri))
165
+ # params override uri params
166
+ params = uri.params.merge(params)
167
+ end
168
+
169
+ @factory = nil
170
+ # In-VM Transport has no fail-over or additional parameters
171
+ if uri.host == 'invm'
172
+ transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::INVM_CONNECTOR_CLASS_NAME)
139
173
  @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport)
174
+ elsif params[:protocol]
175
+ # Auto-Discovery just has a host name and port
176
+ if params[:protocol] == 'discovery'
177
+ @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(uri.host, uri.port)
178
+ elsif params[:protocol] != 'netty'
179
+ raise "Unknown HornetQ protocol:#{params[:protocol]}"
180
+ end
181
+ end
182
+
183
+ # Unless already created, then the factory will use the netty protocol
184
+ unless @factory
185
+ # Primary Transport
186
+ transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::NETTY_CONNECTOR_CLASS_NAME, {'host' => uri.host, 'port' => uri.port })
187
+
188
+ # Check for backup server connection information
189
+ if uri.backup_host
190
+ backup_transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::NETTY_CONNECTOR_CLASS_NAME, {'host' => uri.backup_host, 'port' => uri.backup_port })
191
+ @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport, backup_transport)
192
+ else
193
+ @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport)
194
+ end
195
+ end
196
+
197
+ # If any other options were supplied, apply them to the created Factory instance
198
+ params.each_pair do |key, val|
199
+ next if key == :uri
200
+ method = key.to_s+'='
201
+ if @factory.respond_to? method
202
+ @factory.send method, val
203
+ #puts "Debug: #{key} = #{@factory.send key}" if @factory.respond_to? key.to_sym
204
+ else
205
+ puts "Warning: Option:#{key}, with value:#{val} is invalid and being ignored"
206
+ end
140
207
  end
141
208
  end
142
209
 
143
- # If any other options were supplied, apply them to the created Factory instance
144
- params.each_pair do |key, val|
145
- next if key == :uri
146
- method = key.to_s+'='
147
- if @factory.respond_to? method
148
- @factory.send method, val
149
- #puts "Debug: #{key} = #{@factory.send key}" if @factory.respond_to? key.to_sym
150
- else
151
- puts "Warning: Option:#{key}, with value:#{val} is invalid and being ignored"
210
+ # Create a new HornetQ session
211
+ #
212
+ # Note: Remember to close the session once it is no longer used.
213
+ # Recommend using #session with a block over this method where possible
214
+ #
215
+ # Note:
216
+ # * The returned session MUST be closed once complete
217
+ # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
218
+ # session = factory.create_session
219
+ # ...
220
+ # session.close
221
+ # factory.close
222
+ #
223
+ # Returns:
224
+ # * A new HornetQ ClientSession
225
+ # * See org.hornetq.api.core.client.ClientSession for documentation on returned object
226
+ #
227
+ # Throws:
228
+ # * NativeException
229
+ # * ...
230
+ #
231
+ # Example:
232
+ # require 'hornetq'
233
+ #
234
+ # factory = nil
235
+ # session = nil
236
+ # begin
237
+ # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
238
+ # session = factory.create_session
239
+ #
240
+ # # Create a new queue
241
+ # session.create_queue('Example', 'Example', true)
242
+ #
243
+ # # Create a producer to send messages
244
+ # producer = session.create_producer('Example')
245
+ #
246
+ # # Create a Text Message
247
+ # message = session.create_message(HornetQ::Client::Message::TEXT_TYPE,true)
248
+ # message.body_buffer.write_string('Hello World')
249
+ #
250
+ # # Send the message
251
+ # producer.send(message)
252
+ # ensure
253
+ # session.close if session
254
+ # factory.close if factory
255
+ # end
256
+ #
257
+ # Parameters:
258
+ # * a Hash consisting of one or more of the named parameters
259
+ # * Summary of parameters and their default values
260
+ # factory.create_session(
261
+ # :username => 'my_username', # Default is no authentication
262
+ # :password => 'password', # Default is no authentication
263
+ # :xa => false,
264
+ # :auto_commit_sends => true,
265
+ # :auto_commit_acks => true,
266
+ # :pre_acknowledge => false,
267
+ # :ack_batch_size => 1
268
+ # )
269
+ #
270
+ # Mandatory Parameters
271
+ # * None
272
+ #
273
+ # Optional Parameters
274
+ # * :username
275
+ # * The user name. To create an authenticated session
276
+ #
277
+ # * :password
278
+ # * The user password. To create an authenticated session
279
+ #
280
+ # * :xa
281
+ # * Whether the session supports XA transaction semantics or not
282
+ #
283
+ # * :auto_commit_sends
284
+ # * true: automatically commit message sends
285
+ # * false: commit manually
286
+ #
287
+ # * :auto_commit_acks
288
+ # * true: automatically commit message acknowledgement
289
+ # * false: commit manually
290
+ #
291
+ # * :pre_acknowledge
292
+ # * true: to pre-acknowledge messages on the server
293
+ # * false: to let the client acknowledge the messages
294
+ # * Note: It is possible to pre-acknowledge messages on the server so that the
295
+ # client can avoid additional network trip to the server to acknowledge
296
+ # messages. While this increases performance, this does not guarantee
297
+ # delivery (as messages can be lost after being pre-acknowledged on the
298
+ # server). Use with caution if your application design permits it.
299
+ #
300
+ # * :ack_batch_size
301
+ # * the batch size of the acknowledgements
302
+ #
303
+ def create_session(params={})
304
+ raise "HornetQ::Client::Factory Already Closed" unless @factory
305
+ @factory.create_session(
306
+ params[:username],
307
+ params[:password],
308
+ params[:xa] || false,
309
+ params[:auto_commit_sends].nil? ? true : params[:auto_commit_sends],
310
+ params[:auto_commit_acks].nil? ? true : params[:auto_commit_acks],
311
+ params[:pre_acknowledge] || false,
312
+ params[:ack_batch_size] || 1)
313
+ end
314
+
315
+ # Create a session, call the supplied block and once it completes
316
+ # close the session.
317
+ # See session_create for the Parameters
318
+ #
319
+ # Returns the result of the block
320
+ #
321
+ # Example
322
+ # HornetQ::Client::Factory.create_session(:uri => 'hornetq://localhost/') do |session|
323
+ # session.create_queue("Address", "Queue")
324
+ # end
325
+ #
326
+ # Example:
327
+ # require 'hornetq'
328
+ #
329
+ # factory = nil
330
+ # begin
331
+ # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
332
+ # factory.create_session do |session|
333
+ #
334
+ # # Create a new queue
335
+ # session.create_queue('Example', 'Example', true)
336
+ #
337
+ # # Create a producer to send messages
338
+ # producer = session.create_producer('Example')
339
+ #
340
+ # # Create a Text Message
341
+ # message = session.create_message(HornetQ::Client::Message::TEXT_TYPE,true)
342
+ # message.body = 'Hello World'
343
+ #
344
+ # # Send the message
345
+ # producer.send(message)
346
+ # end
347
+ # ensure
348
+ # factory.close if factory
349
+ # end
350
+ def session(params={}, &proc)
351
+ raise "HornetQ::Client::session mandatory block missing" unless proc
352
+ session = nil
353
+ begin
354
+ session = create_session(params)
355
+ proc.call(session)
356
+ ensure
357
+ session.close if session
152
358
  end
153
359
  end
154
- end
155
360
 
156
- # Create a new HornetQ session
157
- #
158
- # Note: Remember to close the session once it is no longer used.
159
- # Recommend using #session with a block over this method where possible
160
- #
161
- # Note:
162
- # * The returned session MUST be closed once complete
163
- # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
164
- # session = factory.create_session
165
- # ...
166
- # session.close
167
- # factory.close
168
- #
169
- # Returns:
170
- # * A new HornetQ ClientSession
171
- # * See org.hornetq.api.core.client.ClientSession for documentation on returned object
172
- #
173
- # Throws:
174
- # * NativeException
175
- # * ...
176
- #
177
- # Example:
178
- # require 'hornetq'
179
- #
180
- # factory = nil
181
- # session = nil
182
- # begin
183
- # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
184
- # session = factory.create_session
185
- #
186
- # # Create a new queue
187
- # session.create_queue('Example', 'Example', true)
188
- #
189
- # # Create a producer to send messages
190
- # producer = session.create_producer('Example')
191
- #
192
- # # Create a Text Message
193
- # message = session.create_message(HornetQ::Client::Message::TEXT_TYPE,true)
194
- # message.body_buffer.write_string('Hello World')
195
- #
196
- # # Send the message
197
- # producer.send(message)
198
- # ensure
199
- # session.close if session
200
- # factory.close if factory
201
- # end
202
- #
203
- # Parameters:
204
- # * a Hash consisting of one or more of the named parameters
205
- # * Summary of parameters and their default values
206
- # factory.create_session(
207
- # :username => 'my_username', # Default is no authentication
208
- # :password => 'password', # Default is no authentication
209
- # :xa => false,
210
- # :auto_commit_sends => true,
211
- # :auto_commit_acks => true,
212
- # :pre_acknowledge => false,
213
- # :ack_batch_size => 1
214
- # )
215
- #
216
- # Mandatory Parameters
217
- # * None
218
- #
219
- # Optional Parameters
220
- # * :username
221
- # * The user name. To create an authenticated session
222
- #
223
- # * :password
224
- # * The user password. To create an authenticated session
225
- #
226
- # * :xa
227
- # * Whether the session supports XA transaction semantics or not
228
- #
229
- # * :auto_commit_sends
230
- # * true: automatically commit message sends
231
- # * false: commit manually
232
- #
233
- # * :auto_commit_acks
234
- # * true: automatically commit message acknowledgement
235
- # * false: commit manually
236
- #
237
- # * :pre_acknowledge
238
- # * true: to pre-acknowledge messages on the server
239
- # * false: to let the client acknowledge the messages
240
- # * Note: It is possible to pre-acknowledge messages on the server so that the
241
- # client can avoid additional network trip to the server to acknowledge
242
- # messages. While this increases performance, this does not guarantee
243
- # delivery (as messages can be lost after being pre-acknowledged on the
244
- # server). Use with caution if your application design permits it.
245
- #
246
- # * :ack_batch_size
247
- # * the batch size of the acknowledgements
248
- #
249
- def create_session(params={})
250
- raise "HornetQ::Client::Factory Already Closed" unless @factory
251
- @factory.create_session(
252
- params[:username],
253
- params[:password],
254
- params[:xa] || false,
255
- params[:auto_commit_sends].nil? ? true : params[:auto_commit_sends],
256
- params[:auto_commit_acks].nil? ? true : params[:auto_commit_acks],
257
- params[:pre_acknowledge] || false,
258
- params[:ack_batch_size] || 1)
259
- end
361
+ # Create a Session pool
362
+ # TODO Raise an exception when gene_pool is not available
363
+ def create_session_pool(params={})
364
+ require 'hornetq/client/session_pool'
365
+ SessionPool.new(self, params)
366
+ end
260
367
 
261
- # Create a session, call the supplied block and once it completes
262
- # close the session.
263
- # See session_create for the Parameters
264
- #
265
- # Returns the result of the block
266
- #
267
- # Example
268
- # HornetQ::Client::Factory.create_session(:uri => 'hornetq://localhost/') do |session|
269
- # session.create_queue("Address", "Queue")
270
- # end
271
- #
272
- # Example:
273
- # require 'hornetq'
274
- #
275
- # factory = nil
276
- # begin
277
- # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
278
- # factory.create_session do |session|
279
- #
280
- # # Create a new queue
281
- # session.create_queue('Example', 'Example', true)
282
- #
283
- # # Create a producer to send messages
284
- # producer = session.create_producer('Example')
285
- #
286
- # # Create a Text Message
287
- # message = session.create_message(HornetQ::Client::Message::TEXT_TYPE,true)
288
- # message.body = 'Hello World'
289
- #
290
- # # Send the message
291
- # producer.send(message)
292
- # end
293
- # ensure
294
- # factory.close if factory
295
- # end
296
- def session(params={}, &proc)
297
- raise "HornetQ::Client::session mandatory block missing" unless proc
298
- session = nil
299
- begin
300
- session = create_session(params)
301
- proc.call(session)
302
- ensure
303
- session.close if session
368
+ # Close Factory connections
369
+ def close
370
+ @factory.close if @factory
371
+ @factory = nil
304
372
  end
305
- end
306
-
307
- # Create a Session pool
308
- # TODO Raise an exception when gene_pool is not available
309
- def create_session_pool(params={})
310
- require 'hornetq/client/session_pool'
311
- SessionPool.new(self, params)
312
- end
313
-
314
- # Close Factory connections
315
- def close
316
- @factory.close if @factory
317
- @factory = nil
318
- end
319
373
 
320
- # Create a new Factory and Session
321
- #
322
- # Creates a new factory and session, then passes the session to the supplied
323
- # block. Upon completion the session and factory are both closed
324
- # See Factory::initialize and Factory::create_session for the list
325
- # of parameters
326
- def self.session(params={},&proc)
327
- raise "Missing mandatory code block" unless proc
328
- factory = nil
329
- session = nil
330
- begin
331
- if params.kind_of?(String)
332
- # TODO: Support passing username and password from URI to Session
333
- factory = self.new(params)
334
- session = factory.session({}, &proc)
335
- else
336
- factory = self.new(params[:connector] || {})
337
- session = factory.session(params[:session] || {}, &proc)
374
+ # Receive messages in a separate thread when they arrive
375
+ # Allows messages to be received in a separate thread. I.e. Asynchronously
376
+ # This method will return to the caller before messages are processed.
377
+ # It is then the callers responsibility to keep the program active so that messages
378
+ # can then be processed.
379
+ #
380
+ # Note:
381
+ #
382
+ # Session Parameters:
383
+ # :options => any of the javax.jms.Session constants
384
+ # Default: javax.jms.Session::AUTO_ACKNOWLEDGE
385
+ #
386
+ # :session_count : Number of sessions to create, each with their own consumer which
387
+ # in turn will call the supplied block.
388
+ # Note: The supplied block must be thread safe since it will be called
389
+ # by several threads at the same time.
390
+ # I.e. Don't change instance variables etc. without the
391
+ # necessary semaphores etc.
392
+ # Default: 1
393
+ #
394
+ # Consumer Parameters:
395
+ # :queue_name => Name of the Queue to read messages from
396
+ #
397
+ # :selector => Filter which messages should be returned from the queue
398
+ # Default: All messages
399
+ # :no_local => Determine whether messages published by its own connection
400
+ # should be delivered to it
401
+ # Default: false
402
+ #
403
+ # :statistics Capture statistics on how many messages have been read
404
+ # true : This method will capture statistics on the number of messages received
405
+ # and the time it took to process them.
406
+ # The timer starts when each() is called and finishes when either the last message was received,
407
+ # or when Destination::statistics is called. In this case MessageConsumer::statistics
408
+ # can be called several times during processing without affecting the end time.
409
+ # Also, the start time and message count is not reset until MessageConsumer::each
410
+ # is called again with :statistics => true
411
+ #
412
+ # The statistics gathered are returned when :statistics => true and :async => false
413
+ #
414
+ # Usage: For transacted sessions (the default) the Proc supplied must return
415
+ # either true or false:
416
+ # true => The session is committed
417
+ # false => The session is rolled back
418
+ # Any Exception => The session is rolled back
419
+ #
420
+ # Notes:
421
+ # * Remember to call ::start on the factory otherwise the on_message will not
422
+ # start consuming any messages
423
+ # * Remember to call message.acknowledge before completing the block so that
424
+ # the message will be removed from the queue
425
+ # * If the block throws an exception, the
426
+ def on_message(parms, &proc)
427
+ consumer_count = parms[:session_count] || 1
428
+ consumer_count.times do
429
+ session = self.create_session(parms)
430
+ consumer = session.create_consumer_from_params(parms)
431
+ consumer.on_message(parms, &proc)
432
+ @consumers << consumer
433
+ @sessions << session
338
434
  end
339
- ensure
340
- session.close if session
341
- factory.close if factory
342
- end
343
- end
344
-
345
- # Create a new Factory along with a Session, and then start the session
346
- #
347
- # Creates a new factory and session, then passes the session to the supplied
348
- # block. Upon completion the session and factory are both closed
349
- # See Factory::initialize and Factory::create_session for the list
350
- # of parameters
351
- def self.start(params={},&proc)
352
- session(params) do |session|
353
- session.start
354
- proc.call(session)
355
435
  end
356
- end
357
-
358
- # Call the supplied code block after creating a factory instance
359
- # See initialize for the parameter list
360
- # The factory is closed before returning
361
- #
362
- # Returns the result of the code block
363
- def self.create_factory(params={}, &proc)
364
- raise "Missing mandatory code block" unless proc
365
- factory = nil
366
- result = nil
367
- begin
368
- factory=self.new(params)
369
- result = proc.call(factory)
370
- ensure
371
- factory.close
436
+
437
+ def on_message_statistics
438
+ @consumers.collect{|consumer| consumer.on_message_statistics}
372
439
  end
373
- result
374
- end
375
440
 
376
- end
377
-
441
+ end
442
+ end
378
443
  end