jruby-hornetq 0.2.0.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.
- 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
|