jruby-hornetq 0.2.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.md +5 -0
- data/LICENSE.txt +201 -0
- data/README.md +249 -0
- data/Rakefile +23 -0
- data/bin/hornetq_server +70 -0
- data/examples/backup_server.yml +4 -0
- data/examples/batch_client.rb +124 -0
- data/examples/client.rb +49 -0
- data/examples/consumer.rb +35 -0
- data/examples/hornetq.yml +36 -0
- data/examples/live_server.yml +5 -0
- data/examples/multi_client.rb +63 -0
- data/examples/multi_consumer.rb +54 -0
- data/examples/producer.rb +36 -0
- data/examples/run_broker.rb +59 -0
- data/examples/server.rb +42 -0
- data/examples/standalone_server.yml +3 -0
- data/lib/hornetq/client_requestor.rb +30 -0
- data/lib/hornetq/client_server.rb +47 -0
- data/lib/hornetq/hornet_q_client.rb +388 -0
- data/lib/hornetq/lib/hornetq-core-client.jar +0 -0
- data/lib/hornetq/lib/hornetq-core.jar +0 -0
- data/lib/hornetq/lib/netty.jar +0 -0
- data/lib/hornetq/org_hornetq_api_core_client_client_session.rb +16 -0
- data/lib/hornetq/org_hornetq_core_client_impl_client_message_impl.rb +166 -0
- data/lib/hornetq/org_hornetq_core_client_impl_client_producer_impl.rb +5 -0
- data/lib/hornetq/org_hornetq_utils_typed_properties.rb +60 -0
- data/lib/hornetq/session_pool.rb +175 -0
- data/lib/hornetq.rb +9 -0
- metadata +106 -0
@@ -0,0 +1,388 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module HornetQClient
|
4
|
+
|
5
|
+
# Import Message Constants
|
6
|
+
import Java::org.hornetq.api.core.Message
|
7
|
+
|
8
|
+
# Netty Class name
|
9
|
+
NETTY_CLASS_NAME ='org.hornetq.core.remoting.impl.netty.NettyConnectorFactory'
|
10
|
+
INVM_CLASS_NAME = 'org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory'
|
11
|
+
DEFAULT_NETTY_PORT = 5445
|
12
|
+
|
13
|
+
class Factory
|
14
|
+
# Create a new Factory from which sessions can be created
|
15
|
+
#
|
16
|
+
# Parameters:
|
17
|
+
# * a Hash consisting of one or more of the named parameters
|
18
|
+
# * Summary of parameters and their default values
|
19
|
+
# HornetQClient::Factory.new(
|
20
|
+
# :uri => 'hornetq://localhost',
|
21
|
+
# :ack_batch_size => ,
|
22
|
+
# :auto_group => ,
|
23
|
+
# :block_on_acknowledge => ,
|
24
|
+
# :block_on_durable_send => ,
|
25
|
+
# :block_on_non_durable_send => ,
|
26
|
+
# :cache_large_messages_client => ,
|
27
|
+
# :call_timeout => ,
|
28
|
+
# :client_failure_check_period => ,
|
29
|
+
# :confirmation_window_size => ,
|
30
|
+
# :connection_load_balancing_policy_class_name => ,
|
31
|
+
# :connection_ttl => ,
|
32
|
+
# :consumer_max_rate => ,
|
33
|
+
# :consumer_window_size => ,
|
34
|
+
# :discovery_address => ,
|
35
|
+
# :discovery_initial_wait_timeout => ,
|
36
|
+
# :discovery_port => ,
|
37
|
+
# :discovery_refresh_timeout => ,
|
38
|
+
# :failover_on_initial_connection => true,
|
39
|
+
# :failover_on_server_shutdown => true,
|
40
|
+
# :group_id => ,
|
41
|
+
# :initial_message_packet_size => ,
|
42
|
+
# :java_object => ,
|
43
|
+
# :local_bind_address => ,
|
44
|
+
# :max_retry_interval => ,
|
45
|
+
# :min_large_message_size => ,
|
46
|
+
# :pre_acknowledge => ,
|
47
|
+
# :producer_max_rate => ,
|
48
|
+
# :producer_window_size => ,
|
49
|
+
# :reconnect_attempts => 1,
|
50
|
+
# :retry_interval => ,
|
51
|
+
# :retry_interval_multiplier => ,
|
52
|
+
# :scheduled_thread_pool_max_size => ,
|
53
|
+
# :static_connectors => ,
|
54
|
+
# :thread_pool_max_size => ,
|
55
|
+
# :use_global_pools =>
|
56
|
+
# )
|
57
|
+
#
|
58
|
+
# Mandatory Parameters
|
59
|
+
# * :uri
|
60
|
+
# * The hornetq uri as to which server to connect with and which
|
61
|
+
# transport protocol to use. Format:
|
62
|
+
# hornetq://server:port,backupserver:port/?protocol=[netty|discover]
|
63
|
+
# * To use the default netty transport
|
64
|
+
# hornetq://server:port
|
65
|
+
# * To use the default netty transport and specify a backup server
|
66
|
+
# hornetq://server:port,backupserver:port
|
67
|
+
# * To use auto-discovery
|
68
|
+
# hornetq://server:port/?protocol=discovery
|
69
|
+
# * To use HornetQ within the current JVM
|
70
|
+
# hornetq://invm
|
71
|
+
#
|
72
|
+
# Optional Parameters
|
73
|
+
# * :ack_batch_size
|
74
|
+
# * :auto_group
|
75
|
+
# * :block_on_acknowledge
|
76
|
+
# * :block_on_durable_send
|
77
|
+
# * :block_on_non_durable_send
|
78
|
+
# * :cache_large_messages_client
|
79
|
+
# * :call_timeout
|
80
|
+
# * :client_failure_check_period
|
81
|
+
# * :confirmation_window_size
|
82
|
+
# * :connection_load_balancing_policy_class_name
|
83
|
+
# * :connection_ttl
|
84
|
+
# * :consumer_max_rate
|
85
|
+
# * :consumer_window_size
|
86
|
+
# * :discovery_address
|
87
|
+
# * :discovery_initial_wait_timeout
|
88
|
+
# * :discovery_port
|
89
|
+
# * :discovery_refresh_timeout
|
90
|
+
# * :failover_on_initial_connection
|
91
|
+
# * :failover_on_server_shutdown
|
92
|
+
# * :group_id
|
93
|
+
# * :initial_message_packet_size
|
94
|
+
# * :java_object
|
95
|
+
# * :local_bind_address
|
96
|
+
# * :max_retry_interval
|
97
|
+
# * :min_large_message_size
|
98
|
+
# * :pre_acknowledge
|
99
|
+
# * :producer_max_rate
|
100
|
+
# * :producer_window_size
|
101
|
+
# * :reconnect_attempts
|
102
|
+
# * :retry_interval
|
103
|
+
# * :retry_interval_multiplier
|
104
|
+
# * :scheduled_thread_pool_max_size
|
105
|
+
# * :static_connectors
|
106
|
+
# * :thread_pool_max_size
|
107
|
+
# * :use_global_pools
|
108
|
+
|
109
|
+
def initialize(parms={})
|
110
|
+
raise "Missing :uri under :connector in config" unless uri = parms[:uri]
|
111
|
+
# TODO: Support :uri as an array for cluster configurations
|
112
|
+
|
113
|
+
scheme, userinfo, host, port, registry, path, opaque, query, fragment = URI.split(uri)
|
114
|
+
raise InvalidURIError,"bad URI(only scheme hornetq:// is supported): #{uri}" unless scheme == 'hornetq'
|
115
|
+
backup_host = backup_port = nil
|
116
|
+
|
117
|
+
# Check for multiple server names
|
118
|
+
if registry
|
119
|
+
host, backup_host = registry.split(',')
|
120
|
+
host, port = host.split(':')
|
121
|
+
backup_host, backup_port = backup_host.split(':')
|
122
|
+
end
|
123
|
+
|
124
|
+
# Extract settings passed in query
|
125
|
+
settings = {}
|
126
|
+
if query
|
127
|
+
query.split(';').each do |i|
|
128
|
+
key, value = i.split('=')
|
129
|
+
settings[key] = value
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Determine transport protocol
|
134
|
+
factory = nil
|
135
|
+
# In-VM Transport has no fail-over or additional parameters
|
136
|
+
if host == 'invm'
|
137
|
+
transport = Java::org.hornetq.api.core.TransportConfiguration.new(INVM_CLASS_NAME)
|
138
|
+
factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport)
|
139
|
+
elsif settings[:protocol]
|
140
|
+
# Auto-Discovery just has a host name and port
|
141
|
+
if settings[:protocol] == 'discovery'
|
142
|
+
factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(host, port)
|
143
|
+
elsif settings[:protocol] != 'netty'
|
144
|
+
raise "Unknown HornetQ protocol:#{settings[:protocol]}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Unless already created, then the factory will use the netty protocol
|
149
|
+
unless factory
|
150
|
+
# Primary Transport
|
151
|
+
raise "Mandatory hostname missing in :uri" unless host
|
152
|
+
port ||= DEFAULT_NETTY_PORT
|
153
|
+
transport = Java::org.hornetq.api.core.TransportConfiguration.new(NETTY_CLASS_NAME, {'host' => host, 'port' => Java::java.lang.Integer.new(port)})
|
154
|
+
|
155
|
+
# Check for backup server connection information
|
156
|
+
if backup_host
|
157
|
+
backup_port ||= DEFAULT_NETTY_PORT
|
158
|
+
backup_transport = Java::org.hornetq.api.core.TransportConfiguration.new(NETTY_CLASS_NAME, {'host' => backup_host, 'port' => Java::java.lang.Integer.new(backup_port)})
|
159
|
+
factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport, backup_transport)
|
160
|
+
else
|
161
|
+
factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# If any other options were supplied, apply them to the created Factory instance
|
166
|
+
parms.each_pair do |key, val|
|
167
|
+
next if key == :uri
|
168
|
+
method = key.to_s+'='
|
169
|
+
if factory.respond_to? method
|
170
|
+
factory.send method, val
|
171
|
+
#puts "Debug: #{key} = #{factory.send key}" if factory.respond_to? key.to_sym
|
172
|
+
else
|
173
|
+
puts "Warning: Option:#{key}, with value:#{val} is invalid and being ignored"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
@factory = factory
|
178
|
+
end
|
179
|
+
|
180
|
+
# Create a new HornetQ session
|
181
|
+
#
|
182
|
+
# If a block is passed in the block will be passed the session as a parameter
|
183
|
+
# and this method will return the result of the block. The session is
|
184
|
+
# always closed once the proc completes
|
185
|
+
#
|
186
|
+
# If no block is passed, a new session is returned and it is the responsibility
|
187
|
+
# of the caller to close the session
|
188
|
+
#
|
189
|
+
# Note:
|
190
|
+
# * The returned session MUST be closed once complete
|
191
|
+
# factory = HornetQClient::Factory.new(:uri => 'hornetq://localhost/')
|
192
|
+
# session = factory.create_session
|
193
|
+
# ...
|
194
|
+
# session.close
|
195
|
+
# factory.close
|
196
|
+
# * It is recommended to rather call HornetQClient::Factory.create_session
|
197
|
+
# so that all resouces are closed automatically
|
198
|
+
# HornetQClient::Factory.create_session(:uri => 'hornetq://localhost/') do |session|
|
199
|
+
# ...
|
200
|
+
# end
|
201
|
+
#
|
202
|
+
# Returns:
|
203
|
+
# * A new HornetQ ClientSession
|
204
|
+
# * See org.hornetq.api.core.client.ClientSession for documentation on returned object
|
205
|
+
#
|
206
|
+
# Throws:
|
207
|
+
# * NativeException
|
208
|
+
# * ...
|
209
|
+
#
|
210
|
+
# Example:
|
211
|
+
# require 'hornetq'
|
212
|
+
#
|
213
|
+
# factory = nil
|
214
|
+
# begin
|
215
|
+
# factory = HornetQClient::Factory.new(:uri => 'hornetq://localhost/')
|
216
|
+
# factory.create_session do |session|
|
217
|
+
#
|
218
|
+
# # Create a new queue
|
219
|
+
# session.create_queue('Example', 'Example', true)
|
220
|
+
#
|
221
|
+
# # Create a producer to send messages
|
222
|
+
# producer = session.create_producer('Example')
|
223
|
+
#
|
224
|
+
# # Create a Text Message
|
225
|
+
# message = session.create_message(HornetQClient::Message::TEXT_TYPE,true)
|
226
|
+
# message << 'Hello World'
|
227
|
+
#
|
228
|
+
# # Send the message
|
229
|
+
# producer.send(message)
|
230
|
+
# end
|
231
|
+
# ensure
|
232
|
+
# factory.close if factory
|
233
|
+
# end
|
234
|
+
#
|
235
|
+
# Example:
|
236
|
+
# require 'hornetq'
|
237
|
+
#
|
238
|
+
# factory = nil
|
239
|
+
# session = nil
|
240
|
+
# begin
|
241
|
+
# factory = HornetQClient::Factory.new(:uri => 'hornetq://localhost/')
|
242
|
+
# session = factory.create_session
|
243
|
+
#
|
244
|
+
# # Create a new queue
|
245
|
+
# session.create_queue('Example', 'Example', true)
|
246
|
+
#
|
247
|
+
# # Create a producer to send messages
|
248
|
+
# producer = session.create_producer('Example')
|
249
|
+
#
|
250
|
+
# # Create a Text Message
|
251
|
+
# message = session.create_message(HornetQClient::Message::TEXT_TYPE,true)
|
252
|
+
# message.body_buffer.write_string('Hello World')
|
253
|
+
#
|
254
|
+
# # Send the message
|
255
|
+
# producer.send(message)
|
256
|
+
# ensure
|
257
|
+
# session.close if session
|
258
|
+
# factory.close if factory
|
259
|
+
# end
|
260
|
+
#
|
261
|
+
# Parameters:
|
262
|
+
# * a Hash consisting of one or more of the named parameters
|
263
|
+
# * Summary of parameters and their default values
|
264
|
+
# factory.create_session(
|
265
|
+
# :username => 'my_username', # Default is no authentication
|
266
|
+
# :password => 'password', # Default is no authentication
|
267
|
+
# :xa => false,
|
268
|
+
# :auto_commit_sends => true,
|
269
|
+
# :auto_commit_acks => true,
|
270
|
+
# :pre_acknowledge => false,
|
271
|
+
# :ack_batch_size => 1
|
272
|
+
# )
|
273
|
+
#
|
274
|
+
# Mandatory Parameters
|
275
|
+
# * None
|
276
|
+
#
|
277
|
+
# Optional Parameters
|
278
|
+
# * :username
|
279
|
+
# * The user name. To create an authenticated session
|
280
|
+
#
|
281
|
+
# * :password
|
282
|
+
# * The user password. To create an authenticated session
|
283
|
+
#
|
284
|
+
# * :xa
|
285
|
+
# * Whether the session supports XA transaction semantics or not
|
286
|
+
#
|
287
|
+
# * :auto_commit_sends
|
288
|
+
# * true: automatically commit message sends
|
289
|
+
# * false: commit manually
|
290
|
+
#
|
291
|
+
# * :auto_commit_acks
|
292
|
+
# * true: automatically commit message acknowledgement
|
293
|
+
# * false: commit manually
|
294
|
+
#
|
295
|
+
# * :pre_acknowledge
|
296
|
+
# * true: to pre-acknowledge messages on the server
|
297
|
+
# * false: to let the client acknowledge the messages
|
298
|
+
# * Note: It is possible to pre-acknowledge messages on the server so that the
|
299
|
+
# client can avoid additional network trip to the server to acknowledge
|
300
|
+
# messages. While this increases performance, this does not guarantee
|
301
|
+
# delivery (as messages can be lost after being pre-acknowledged on the
|
302
|
+
# server). Use with caution if your application design permits it.
|
303
|
+
#
|
304
|
+
# * :ack_batch_size
|
305
|
+
# * the batch size of the acknowledgements
|
306
|
+
#
|
307
|
+
def create_session(parms={}, &proc)
|
308
|
+
raise "HornetQClient Factory Already Closed" unless @factory
|
309
|
+
if proc
|
310
|
+
session = nil
|
311
|
+
result = nil
|
312
|
+
begin
|
313
|
+
#session = @factory.create_session(true, true)
|
314
|
+
session = @factory.create_session(
|
315
|
+
parms[:username],
|
316
|
+
parms[:password],
|
317
|
+
parms[:xa] || false,
|
318
|
+
parms[:auto_commit_sends].nil? ? true : parms[:auto_commit_sends],
|
319
|
+
parms[:auto_commit_acks].nil? ? true : parms[:auto_commit_acks],
|
320
|
+
parms[:pre_acknowledge] || false,
|
321
|
+
parms[:ack_batch_size] || 1)
|
322
|
+
result = proc.call(session)
|
323
|
+
ensure
|
324
|
+
session.close if session
|
325
|
+
end
|
326
|
+
result
|
327
|
+
else
|
328
|
+
@factory.create_session(
|
329
|
+
parms[:username],
|
330
|
+
parms[:password],
|
331
|
+
parms[:xa] || false,
|
332
|
+
parms[:auto_commit_sends].nil? ? true : parms[:auto_commit_sends],
|
333
|
+
parms[:auto_commit_acks].nil? ? true : parms[:auto_commit_acks],
|
334
|
+
parms[:pre_acknowledge] || false,
|
335
|
+
parms[:ack_batch_size] || 1)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
# Create a Session pool
|
340
|
+
def create_session_pool(parms={})
|
341
|
+
SessionPool.new(self, parms)
|
342
|
+
end
|
343
|
+
|
344
|
+
# Close Factory connections
|
345
|
+
def close
|
346
|
+
@factory.close if @factory
|
347
|
+
@factory = nil
|
348
|
+
end
|
349
|
+
|
350
|
+
# Create a new Factory and Session
|
351
|
+
#
|
352
|
+
# Creates a new factory and session, then passes the session to the supplied
|
353
|
+
# block. Upon completion the session and factory are both closed
|
354
|
+
# See Factory::initialize and Factory::create_session for the list
|
355
|
+
# of parameters
|
356
|
+
def self.create_session(parms={},&proc)
|
357
|
+
raise "Missing mandatory code block" unless proc
|
358
|
+
factory = nil
|
359
|
+
session = nil
|
360
|
+
begin
|
361
|
+
factory = self.new(parms[:connector] || {})
|
362
|
+
session = factory.create_session(parms[:session] || {}, &proc)
|
363
|
+
ensure
|
364
|
+
factory.close if factory
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
# Call the supplied code block after creating a factory instance
|
369
|
+
# See initialize for the parameter list
|
370
|
+
# The factory is closed before returning
|
371
|
+
#
|
372
|
+
# Returns the result of the code block
|
373
|
+
def self.create_factory(parms={}, &proc)
|
374
|
+
raise "Missing mandatory code block" unless proc
|
375
|
+
factory = nil
|
376
|
+
result = nil
|
377
|
+
begin
|
378
|
+
factory=self.new(parms)
|
379
|
+
result = proc.call(factory)
|
380
|
+
ensure
|
381
|
+
factory.close
|
382
|
+
end
|
383
|
+
result
|
384
|
+
end
|
385
|
+
|
386
|
+
end
|
387
|
+
|
388
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Add methods to Session Interface
|
2
|
+
module Java::org.hornetq.api.core.client::ClientSession
|
3
|
+
|
4
|
+
# To be consistent create Requestor from Session
|
5
|
+
def create_requestor(request_address)
|
6
|
+
#Java::org.hornetq.api.core.client::ClientRequestor.new(self, request_address);
|
7
|
+
HornetQClient::ClientRequestor.new(self, request_address)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Create a server handler for receiving requests and responding with
|
11
|
+
# replies to the supplied address
|
12
|
+
def create_server(input_queue, timeout=0)
|
13
|
+
HornetQClient::ClientServer.new(self, input_queue, timeout)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,166 @@
|
|
1
|
+
|
2
|
+
# Cannot add to the interface Java::org.hornetq.api.core::Message because these
|
3
|
+
# methods access instance variables in the Java object
|
4
|
+
class Java::OrgHornetqCoreClientImpl::ClientMessageImpl
|
5
|
+
# Attributes
|
6
|
+
# attr_accessor :address, :type, :durable, :expiration, :priority, :timestamp, :user_id
|
7
|
+
|
8
|
+
# Is this a request message for which a reply is expected?
|
9
|
+
def request?
|
10
|
+
contains_property(Java::OrgHornetqCoreClientImpl::ClientMessageImpl::REPLYTO_HEADER_NAME)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return the Reply To Queue Name as a string
|
14
|
+
def reply_to_queue_name
|
15
|
+
get_string_property(Java::OrgHornetqCoreClientImpl::ClientMessageImpl::REPLYTO_HEADER_NAME)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Set the Reply To Queue Name
|
19
|
+
# When supplied, the consumer of the message is expected to send a response to the
|
20
|
+
# specified queue. However, this is by convention, so no response is guaranteed
|
21
|
+
# Note: Rather than set this directly, consider creating a ClientRequestor:
|
22
|
+
# requestor = session.create_requestor('Request Queue')
|
23
|
+
#
|
24
|
+
def reply_to_queue_name=(name)
|
25
|
+
val = nil
|
26
|
+
if name.is_a? Java::org.hornetq.api.core::SimpleString
|
27
|
+
val = name
|
28
|
+
else
|
29
|
+
val = Java::org.hornetq.api.core::SimpleString.new(name.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
put_string_property(Java::OrgHornetqCoreClientImpl::ClientMessageImpl::REPLYTO_HEADER_NAME, val)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return the size of the encoded message
|
36
|
+
# attr_reader :encode_size
|
37
|
+
|
38
|
+
# Return the body for this message
|
39
|
+
# TODO: Do remaining message Types
|
40
|
+
#
|
41
|
+
# WARNING: This method can only be called ONCE!
|
42
|
+
# WARNING: Do not call after setting the body otherwise the send will have
|
43
|
+
# an empty body
|
44
|
+
def body
|
45
|
+
case type
|
46
|
+
when Java::org.hornetq.api.core.Message::BYTES_TYPE #4
|
47
|
+
when Java::org.hornetq.api.core.Message::DEFAULT_TYPE #0
|
48
|
+
when Java::org.hornetq.api.core.Message::MAP_TYPE #5
|
49
|
+
Java::org.hornetq.utils::TypedProperties.new.decode(body_buffer)
|
50
|
+
when Java::org.hornetq.api.core.Message::OBJECT_TYPE #2
|
51
|
+
when Java::org.hornetq.api.core.Message::STREAM_TYPE #6
|
52
|
+
when Java::org.hornetq.api.core.Message::TEXT_TYPE #3
|
53
|
+
body_buffer.read_nullable_simple_string.to_string
|
54
|
+
else
|
55
|
+
raise "Unknown Message Type, use Message#body_buffer instead"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Write data into the message body
|
60
|
+
#
|
61
|
+
# Data is automatically converted based on the message type
|
62
|
+
#
|
63
|
+
# TODO Support non-string Types
|
64
|
+
def <<(data)
|
65
|
+
case type
|
66
|
+
when Java::org.hornetq.api.core.Message::BYTES_TYPE #4
|
67
|
+
when Java::org.hornetq.api.core.Message::DEFAULT_TYPE #0
|
68
|
+
raise "Cannot use Message#<< when the Message#type has not been set"
|
69
|
+
when Java::org.hornetq.api.core.Message::MAP_TYPE #5
|
70
|
+
if data.class == Java::org.hornetq.utils::TypedProperties
|
71
|
+
body_buffer.reset_writer_index
|
72
|
+
data.encode(body_buffer)
|
73
|
+
elsif data.responds_to? :each_pair
|
74
|
+
properties = Java::org.hornetq.utils::TypedProperties.new
|
75
|
+
properties.from_hash(data)
|
76
|
+
body_buffer.reset_writer_index
|
77
|
+
properties.encode(body_buffer)
|
78
|
+
end
|
79
|
+
when Java::org.hornetq.api.core.Message::OBJECT_TYPE #2
|
80
|
+
when Java::org.hornetq.api.core.Message::STREAM_TYPE #6
|
81
|
+
when Java::org.hornetq.api.core.Message::TEXT_TYPE #3
|
82
|
+
if data.class == Java::org.hornetq.api.core::SimpleString
|
83
|
+
body_buffer.writeNullableSimpleString(data)
|
84
|
+
else
|
85
|
+
body_buffer.writeNullableSimpleString(Java::org.hornetq.api.core::SimpleString.new(data.to_s))
|
86
|
+
end
|
87
|
+
else
|
88
|
+
raise "Unknown Message Type, use Message#body_buffer instead"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Get a property
|
93
|
+
def [](key)
|
94
|
+
getObjectProperty(key.to_s)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set a property
|
98
|
+
# TODO: Does it need proper translation, otherwise it will be a Ruby object
|
99
|
+
def []=(key,value)
|
100
|
+
putObjectProperty(key, value)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Does this message include the supplied property?
|
104
|
+
def include?(key)
|
105
|
+
# Ensure a Ruby true is returned
|
106
|
+
property_exists(key.to_s) == true
|
107
|
+
end
|
108
|
+
|
109
|
+
# call-seq:
|
110
|
+
# body_buffer
|
111
|
+
#
|
112
|
+
# Return the message body as a HornetQBuffer
|
113
|
+
#
|
114
|
+
|
115
|
+
# call-seq:
|
116
|
+
# to_map
|
117
|
+
#
|
118
|
+
# Return the Message as a Map
|
119
|
+
#
|
120
|
+
|
121
|
+
# call-seq:
|
122
|
+
# remove_property(key)
|
123
|
+
#
|
124
|
+
# Remove a property
|
125
|
+
|
126
|
+
# call-seq:
|
127
|
+
# contains_property(key)
|
128
|
+
#
|
129
|
+
# Returns true if this message contains a property with the given key
|
130
|
+
# TODO: Symbols?
|
131
|
+
|
132
|
+
# Return TypedProperties
|
133
|
+
def getProperties
|
134
|
+
properties
|
135
|
+
end
|
136
|
+
|
137
|
+
# Iterate over all the properties
|
138
|
+
#
|
139
|
+
def properties_each_pair(&proc)
|
140
|
+
enum = getPropertyNames
|
141
|
+
while enum.has_more_elements
|
142
|
+
key = enum.next_element
|
143
|
+
proc.call key, getObjectProperty(key)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Return all message Attributes as a hash
|
148
|
+
def attributes
|
149
|
+
{
|
150
|
+
:address => address.nil? ? '' : address.to_string,
|
151
|
+
:type => type,
|
152
|
+
:durable => durable,
|
153
|
+
:expiration => expiration,
|
154
|
+
:priority => priority,
|
155
|
+
:timestamp => timestamp,
|
156
|
+
:user_id => user_id,
|
157
|
+
:encode_size => encode_size
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
# Does not include the body since it can only read once
|
162
|
+
def inspect
|
163
|
+
"#{self.class.name}:\nAttributes: #{attributes.inspect}\nProperties: #{properties.inspect}"
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Used by HornetQ to move around HashMap messages
|
2
|
+
# Ruby methods added to make it behave like a Ruby Hash
|
3
|
+
class Java::org.hornetq.utils::TypedProperties
|
4
|
+
# Get a property
|
5
|
+
def [](key)
|
6
|
+
value = getProperty(key)
|
7
|
+
(value.class == Java::org.hornetq.api.core::SimpleString) ? value.to_s : value
|
8
|
+
end
|
9
|
+
|
10
|
+
# Set a property
|
11
|
+
# Currently supports Long, Double, Boolean
|
12
|
+
# TODO: Not supported Byte, Bytes, Short, Int, FLoat, Char
|
13
|
+
def []=(key,val)
|
14
|
+
case
|
15
|
+
when val.class == Fixnum # 1
|
16
|
+
putLongProperty(key,val)
|
17
|
+
when val.class == Float #1.1
|
18
|
+
putDoubleProperty(key,val)
|
19
|
+
when val.class == Bignum # 11111111111111111
|
20
|
+
putLongProperty(key,val)
|
21
|
+
when (val.class == TrueClass) || (val.class == FalseClass)
|
22
|
+
putBooleanProperty(key,val)
|
23
|
+
when val.class == NilClass
|
24
|
+
setSimpleStringProperty(key,null)
|
25
|
+
when val.class == Java::org.hornetq.api.core::SimpleString
|
26
|
+
setSimpleStringProperty(key,val)
|
27
|
+
else
|
28
|
+
putSimpleStringProperty(key,val.to_s)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Iterate through each key,value pair
|
33
|
+
def each_pair(&proc)
|
34
|
+
it = property_names.iterator
|
35
|
+
while it.has_next
|
36
|
+
key = it.next
|
37
|
+
proc.call(key.to_string, self[key])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Convert Properties to a Ruby Hash
|
42
|
+
def to_h
|
43
|
+
h = {}
|
44
|
+
each_pair do |key, value|
|
45
|
+
h[key] = value
|
46
|
+
end
|
47
|
+
h
|
48
|
+
end
|
49
|
+
|
50
|
+
# Write Hash values into this TyedProperties instance
|
51
|
+
def from_h(hash)
|
52
|
+
hash.each_pair do |key,value|
|
53
|
+
self[key] = value
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def inspect
|
58
|
+
"#{self.class.name}: #{to_h.inspect}"
|
59
|
+
end
|
60
|
+
end
|