stomp 1.1.8 → 1.1.9
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/CHANGELOG.rdoc +13 -2
- data/README.rdoc +3 -0
- data/Rakefile +1 -1
- data/examples/logexamp.rb +50 -0
- data/examples/slogger.rb +100 -0
- data/lib/stomp/client.rb +34 -4
- data/lib/stomp/connection.rb +58 -7
- data/lib/stomp/version.rb +1 -1
- data/spec/client_shared_examples.rb +14 -0
- data/spec/connection_spec.rb +15 -0
- data/stomp.gemspec +9 -21
- data/test/test_client.rb +89 -2
- data/test/test_connection.rb +16 -5
- data/test/test_message.rb +1 -1
- metadata +34 -61
data/CHANGELOG.rdoc
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
== 1.1.
|
1
|
+
== 1.1.9 2011-15-06
|
2
|
+
|
3
|
+
* Support wildcard destinations
|
4
|
+
* Handle subscribe with string or symbol ID
|
5
|
+
* Check for duplicate subscriptions in spec tests
|
6
|
+
* Support AMQ and Apollo servers in uinit tests
|
7
|
+
* Correct UTF-8 (Unicode) content-length calcualtion in Ruby 1.9
|
8
|
+
* Send of a nil body causes exception
|
9
|
+
* Add optional callback logging. See the examples install directory, files logexamp.rb and slogger.rb
|
10
|
+
* Correct date stamps in this file
|
11
|
+
|
12
|
+
== 1.1.8 2011-16-03
|
2
13
|
|
3
14
|
* Set KEEPALIVE on connection socket options
|
4
15
|
* Attempt to support JRuby more robustly (poll remains broken)
|
@@ -9,7 +20,7 @@
|
|
9
20
|
* Allow connection to hosts with a - (dash) in the host name
|
10
21
|
* Add limit parameter to thread joins
|
11
22
|
|
12
|
-
== 1.1.7
|
23
|
+
== 1.1.7 2011-09-01
|
13
24
|
|
14
25
|
* Binary parse of raw STOMP frame
|
15
26
|
* Fix broken tests on Ruby 1.9.2
|
data/README.rdoc
CHANGED
@@ -51,6 +51,7 @@ An implementation of the Stomp protocol for Ruby. See:
|
|
51
51
|
:timeout => -1,
|
52
52
|
:connect_headers => {},
|
53
53
|
:parse_timeout => 5,
|
54
|
+
:logger => nil,
|
54
55
|
}
|
55
56
|
|
56
57
|
# for client
|
@@ -101,4 +102,6 @@ The following people have contributed to Stomp:
|
|
101
102
|
* Stefan Saasen
|
102
103
|
* Neil Wilson
|
103
104
|
* Dinesh Majrekar
|
105
|
+
* Kiall Mac Innes
|
106
|
+
* Rob Skaggs
|
104
107
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'stomp'
|
3
|
+
require 'logger' # for the 'local' logger
|
4
|
+
#
|
5
|
+
$:.unshift(File.dirname(__FILE__))
|
6
|
+
#
|
7
|
+
require 'slogger'
|
8
|
+
#
|
9
|
+
# A STOMP client program which uses the callback logging facility.
|
10
|
+
#
|
11
|
+
llog = Logger::new(STDOUT)
|
12
|
+
llog.level = Logger::DEBUG
|
13
|
+
llog.debug "LE Starting"
|
14
|
+
|
15
|
+
# //////////////////////////////////////////////////////////////////////////////
|
16
|
+
mylog = Slogger::new # The client provided STOMP callback logger
|
17
|
+
|
18
|
+
# //////////////////////////////////////////////////////////////////////////////
|
19
|
+
user = ENV['STOMP_USER'] ? ENV['STOMP_USER'] : 'guest'
|
20
|
+
password = ENV['STOMP_PASSWORD'] ? ENV['STOMP_PASSWORD'] : 'guestpw'
|
21
|
+
host = ENV['STOMP_HOST'] ? ENV['STOMP_HOST'] : 'localhost'
|
22
|
+
port = ENV['STOMP_PORT'] ? ENV['STOMP_PORT'].to_i : 61613
|
23
|
+
# //////////////////////////////////////////////////////////////////////////////
|
24
|
+
# A hash type connect *MUST* be used to enable callback logging.
|
25
|
+
# //////////////////////////////////////////////////////////////////////////////
|
26
|
+
hash = { :hosts => [
|
27
|
+
{:login => user, :passcode => password, :host => 'noonehome', :port => 2525},
|
28
|
+
{:login => user, :passcode => password, :host => host, :port => port},
|
29
|
+
],
|
30
|
+
:logger => mylog, # This enables callback logging!
|
31
|
+
:max_reconnect_attempts => 5,
|
32
|
+
}
|
33
|
+
|
34
|
+
# //////////////////////////////////////////////////////////////////////////////
|
35
|
+
# For a Connection:
|
36
|
+
conn = Stomp::Connection.new(hash)
|
37
|
+
conn.disconnect
|
38
|
+
# //////////////////////////////////////////////////////////////////////////////
|
39
|
+
llog.debug "LE Connection processing complete"
|
40
|
+
|
41
|
+
# //////////////////////////////////////////////////////////////////////////////
|
42
|
+
# For a Client:
|
43
|
+
conn = Stomp::Client.new(hash)
|
44
|
+
conn.close
|
45
|
+
# //////////////////////////////////////////////////////////////////////////////
|
46
|
+
# llog.debug "LE Client processing complete"
|
47
|
+
|
48
|
+
# //////////////////////////////////////////////////////////////////////////////
|
49
|
+
llog.debug "LE Ending"
|
50
|
+
|
data/examples/slogger.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Example STOMP call back logger class.
|
4
|
+
|
5
|
+
Optional callback methods:
|
6
|
+
|
7
|
+
on_connecting: connection starting
|
8
|
+
on_connected: successful connect
|
9
|
+
on_connectfail: unsuccessful connect (will usually be retried)
|
10
|
+
on_disconnect: successful disconnect
|
11
|
+
|
12
|
+
on_miscerr: on miscellaneous xmit/recv errors
|
13
|
+
|
14
|
+
All methods are optional, at the user's requirements.
|
15
|
+
|
16
|
+
If a method is not provided, it is not called (of course.)
|
17
|
+
|
18
|
+
IMPORTANT NOTE: call back logging methods *MUST* not raise exceptions,
|
19
|
+
otherwise the underlying STOMP connection will fail in mysterious ways.
|
20
|
+
|
21
|
+
Callback parameters: are a copy of the @parameters instance variable for
|
22
|
+
the Stomp::Connection.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
require 'logger' # use the standard Ruby logger .....
|
27
|
+
|
28
|
+
class Slogger
|
29
|
+
#
|
30
|
+
def initialize(init_parms = nil)
|
31
|
+
@log = Logger::new(STDOUT) # User preference
|
32
|
+
@log.level = Logger::DEBUG # User preference
|
33
|
+
@log.info("Logger initialization complete.")
|
34
|
+
end
|
35
|
+
|
36
|
+
# Log connecting events
|
37
|
+
def on_connecting(parms)
|
38
|
+
begin
|
39
|
+
@log.debug "Connecting: #{info(parms)}"
|
40
|
+
rescue
|
41
|
+
@log.debug "Connecting oops"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Log connected events
|
46
|
+
def on_connected(parms)
|
47
|
+
begin
|
48
|
+
@log.debug "Connected: #{info(parms)}"
|
49
|
+
rescue
|
50
|
+
@log.debug "Connected oops"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Log connectfail events
|
55
|
+
def on_connectfail(parms)
|
56
|
+
begin
|
57
|
+
@log.debug "Connect Fail #{info(parms)}"
|
58
|
+
rescue
|
59
|
+
@log.debug "Connect Fail oops"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Log disconnect events
|
64
|
+
def on_disconnect(parms)
|
65
|
+
begin
|
66
|
+
@log.debug "Disconnected #{info(parms)}"
|
67
|
+
rescue
|
68
|
+
@log.debug "Disconnected oops"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# Log miscellaneous errors
|
74
|
+
def on_miscerr(parms, errstr)
|
75
|
+
begin
|
76
|
+
@log.debug "Miscellaneous Error #{info(parms)}"
|
77
|
+
@log.debug "Miscellaneous Error String #{errstr}"
|
78
|
+
rescue
|
79
|
+
@log.debug "Miscellaneous Error oops"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def info(parms)
|
86
|
+
#
|
87
|
+
# Available in the Hash:
|
88
|
+
# parms[:cur_host]
|
89
|
+
# parms[:cur_port]
|
90
|
+
# parms[:cur_login]
|
91
|
+
# parms[:cur_passcode]
|
92
|
+
# parms[:cur_ssl]
|
93
|
+
# parms[:cur_recondelay]
|
94
|
+
# parms[:cur_parseto]
|
95
|
+
# parms[:cur_conattempts]
|
96
|
+
#
|
97
|
+
"Host: #{parms[:cur_host]}, Port: #{parms[:cur_port]}, Login: Port: #{parms[:cur_login]}, Passcode: #{parms[:cur_passcode]}"
|
98
|
+
end
|
99
|
+
end # of class
|
100
|
+
|
data/lib/stomp/client.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'thread'
|
2
|
+
require 'digest/sha1'
|
2
3
|
|
3
4
|
module Stomp
|
4
5
|
|
@@ -121,7 +122,7 @@ module Stomp
|
|
121
122
|
replay_list = @replay_messages_by_txn[name]
|
122
123
|
if replay_list
|
123
124
|
replay_list.each do |message|
|
124
|
-
if listener =
|
125
|
+
if listener = find_listener(message)
|
125
126
|
listener.call(message)
|
126
127
|
end
|
127
128
|
end
|
@@ -141,14 +142,22 @@ module Stomp
|
|
141
142
|
# Accepts a transaction header ( :transaction => 'some_transaction_id' )
|
142
143
|
def subscribe(destination, headers = {})
|
143
144
|
raise "No listener given" unless block_given?
|
144
|
-
|
145
|
+
# use subscription id to correlate messages to subscription. As described in
|
146
|
+
# the SUBSCRIPTION section of the protocol: http://stomp.codehaus.org/Protocol.
|
147
|
+
# If no subscription id is provided, generate one.
|
148
|
+
set_subscription_id_if_missing(destination, headers)
|
149
|
+
if @listeners[headers[:id]]
|
150
|
+
raise "attempting to subscribe to a queue with a previous subscription"
|
151
|
+
end
|
152
|
+
@listeners[headers[:id]] = lambda {|msg| yield msg}
|
145
153
|
@connection.subscribe(destination, headers)
|
146
154
|
end
|
147
155
|
|
148
156
|
# Unsubecribe from a channel
|
149
157
|
def unsubscribe(name, headers = {})
|
158
|
+
set_subscription_id_if_missing(name, headers)
|
150
159
|
@connection.unsubscribe(name, headers)
|
151
|
-
@listeners[
|
160
|
+
@listeners[headers[:id]] = nil
|
152
161
|
end
|
153
162
|
|
154
163
|
# Acknowledge a message, used when a subscription has specified
|
@@ -230,6 +239,16 @@ module Stomp
|
|
230
239
|
end
|
231
240
|
|
232
241
|
private
|
242
|
+
# Set a subscription id in the headers hash if one does not already exist.
|
243
|
+
# For simplicities sake, all subscriptions have a subscription ID.
|
244
|
+
# setting an id in the SUBSCRIPTION header is described in the stomp protocol docs:
|
245
|
+
# http://stomp.codehaus.org/Protocol
|
246
|
+
def set_subscription_id_if_missing(destination, headers)
|
247
|
+
headers[:id] = headers[:id] ? headers[:id] : headers['id']
|
248
|
+
if headers[:id] == nil
|
249
|
+
headers[:id] = Digest::SHA1.hexdigest(destination)
|
250
|
+
end
|
251
|
+
end
|
233
252
|
|
234
253
|
def register_receipt_listener(listener)
|
235
254
|
id = -1
|
@@ -284,6 +303,17 @@ module Stomp
|
|
284
303
|
new_options
|
285
304
|
end
|
286
305
|
|
306
|
+
def find_listener(message)
|
307
|
+
subscription_id = message.headers['subscription']
|
308
|
+
if subscription_id == nil
|
309
|
+
# For backward compatibility, some messages may already exist with no
|
310
|
+
# subscription id, in which case we can attempt to synthesize one.
|
311
|
+
set_subscription_id_if_missing(message.headers['destination'], message.headers)
|
312
|
+
subscription_id = message.headers['id']
|
313
|
+
end
|
314
|
+
@listeners[subscription_id]
|
315
|
+
end
|
316
|
+
|
287
317
|
def start_listeners
|
288
318
|
@listeners = {}
|
289
319
|
@receipt_listeners = {}
|
@@ -293,7 +323,7 @@ module Stomp
|
|
293
323
|
while true
|
294
324
|
message = @connection.receive
|
295
325
|
if message.command == 'MESSAGE'
|
296
|
-
if listener =
|
326
|
+
if listener = find_listener(message)
|
297
327
|
listener.call(message)
|
298
328
|
end
|
299
329
|
elsif message.command == 'RECEIPT'
|
data/lib/stomp/connection.rb
CHANGED
@@ -43,6 +43,7 @@ module Stomp
|
|
43
43
|
# :timeout => -1,
|
44
44
|
# :connect_headers => {},
|
45
45
|
# :parse_timeout => 5,
|
46
|
+
# :logger => nil,
|
46
47
|
# }
|
47
48
|
#
|
48
49
|
# e.g. c = Connection.new(hash)
|
@@ -72,6 +73,7 @@ module Stomp
|
|
72
73
|
@ssl = false
|
73
74
|
@parameters = nil
|
74
75
|
@parse_timeout = 5 # To override, use hashed parameters
|
76
|
+
@logger = nil # To override, use hashed parameters
|
75
77
|
end
|
76
78
|
|
77
79
|
# Use Mutexes: only one lock per each thread
|
@@ -94,8 +96,12 @@ module Stomp
|
|
94
96
|
@reconnect_delay = @parameters[:initial_reconnect_delay]
|
95
97
|
@connect_headers = @parameters[:connect_headers]
|
96
98
|
@parse_timeout = @parameters[:parse_timeout]
|
99
|
+
@logger = @parameters[:logger]
|
97
100
|
#sets the first host to connect
|
98
101
|
change_host
|
102
|
+
if @logger && @logger.respond_to?(:on_connecting)
|
103
|
+
@logger.on_connecting(log_params)
|
104
|
+
end
|
99
105
|
end
|
100
106
|
|
101
107
|
# Syntactic sugar for 'Connection.new' See 'initialize' for usage.
|
@@ -115,14 +121,19 @@ module Stomp
|
|
115
121
|
# Open complete
|
116
122
|
|
117
123
|
connect(used_socket)
|
118
|
-
|
124
|
+
if @logger && @logger.respond_to?(:on_connected)
|
125
|
+
@logger.on_connected(log_params)
|
126
|
+
end
|
119
127
|
@connection_attempts = 0
|
120
128
|
rescue
|
121
129
|
@failure = $!
|
122
130
|
used_socket = nil
|
123
131
|
raise unless @reliable
|
124
|
-
|
125
|
-
|
132
|
+
if @logger && @logger.respond_to?(:on_connectfail)
|
133
|
+
@logger.on_connectfail(log_params)
|
134
|
+
else
|
135
|
+
$stderr.print "connect to #{@host} failed: #{$!} will retry(##{@connection_attempts}) in #{@reconnect_delay}\n"
|
136
|
+
end
|
126
137
|
raise Stomp::Error::MaxReconnectAttempts if max_reconnect_attempts?
|
127
138
|
|
128
139
|
sleep(@reconnect_delay)
|
@@ -310,6 +321,9 @@ module Stomp
|
|
310
321
|
transmit("DISCONNECT", headers)
|
311
322
|
headers = headers.symbolize_keys
|
312
323
|
@disconnect_receipt = receive if headers[:receipt]
|
324
|
+
if @logger && @logger.respond_to?(:on_disconnect)
|
325
|
+
@logger.on_disconnect(log_params)
|
326
|
+
end
|
313
327
|
close_socket
|
314
328
|
end
|
315
329
|
|
@@ -332,7 +346,12 @@ module Stomp
|
|
332
346
|
rescue
|
333
347
|
@failure = $!
|
334
348
|
raise unless @reliable
|
335
|
-
|
349
|
+
errstr = "receive failed: #{$!}"
|
350
|
+
if @logger && @logger.respond_to?(:on_miscerr)
|
351
|
+
@logger.on_miscerr(log_params, errstr)
|
352
|
+
else
|
353
|
+
$stderr.print errstr
|
354
|
+
end
|
336
355
|
end
|
337
356
|
end
|
338
357
|
end
|
@@ -340,7 +359,12 @@ module Stomp
|
|
340
359
|
def receive
|
341
360
|
super_result = __old_receive
|
342
361
|
if super_result.nil? && @reliable
|
343
|
-
|
362
|
+
errstr = "connection.receive returning EOF as nil - resetting connection.\n"
|
363
|
+
if @logger && @logger.respond_to?(:on_miscerr)
|
364
|
+
@logger.on_miscerr(log_params, errstr)
|
365
|
+
else
|
366
|
+
$stderr.print errstr
|
367
|
+
end
|
344
368
|
@socket = nil
|
345
369
|
super_result = __old_receive
|
346
370
|
end
|
@@ -412,23 +436,37 @@ module Stomp
|
|
412
436
|
used_socket = socket
|
413
437
|
_transmit(used_socket, command, headers, body)
|
414
438
|
return
|
439
|
+
rescue Stomp::Error::MaxReconnectAttempts => e
|
440
|
+
raise
|
415
441
|
rescue
|
416
442
|
@failure = $!
|
417
443
|
raise unless @reliable
|
418
|
-
|
444
|
+
errstr = "transmit to #{@host} failed: #{$!}\n"
|
445
|
+
if @logger && @logger.respond_to?(:on_miscerr)
|
446
|
+
@logger.on_miscerr(log_params, errstr)
|
447
|
+
else
|
448
|
+
$stderr.print errstr
|
449
|
+
end
|
419
450
|
end
|
420
451
|
end
|
421
452
|
end
|
422
453
|
|
423
454
|
def _transmit(used_socket, command, headers = {}, body = '')
|
424
455
|
@transmit_semaphore.synchronize do
|
456
|
+
# Handle nil body
|
457
|
+
body = '' if body.nil?
|
458
|
+
# The content-length should be expressed in bytes.
|
459
|
+
# Ruby 1.8: String#length => # of bytes; Ruby 1.9: String#length => # of characters
|
460
|
+
# With Unicode strings, # of bytes != # of characters. So, use String#bytesize when available.
|
461
|
+
body_length_bytes = body.respond_to?(:bytesize) ? body.bytesize : body.length
|
462
|
+
|
425
463
|
# ActiveMQ interprets every message as a BinaryMessage
|
426
464
|
# if content_length header is included.
|
427
465
|
# Using :suppress_content_length => true will suppress this behaviour
|
428
466
|
# and ActiveMQ will interpret the message as a TextMessage.
|
429
467
|
# For more information refer to http://juretta.com/log/2009/05/24/activemq-jms-stomp/
|
430
468
|
# Lets send this header in the message, so it can maintain state when using unreceive
|
431
|
-
headers['content-length'] = "#{
|
469
|
+
headers['content-length'] = "#{body_length_bytes}" unless headers[:suppress_content_length]
|
432
470
|
|
433
471
|
used_socket.puts command
|
434
472
|
headers.each {|k,v| used_socket.puts "#{k}:#{v}" }
|
@@ -502,6 +540,19 @@ module Stomp
|
|
502
540
|
@subscriptions.each { |k,v| _transmit(used_socket, "SUBSCRIBE", v) }
|
503
541
|
end
|
504
542
|
|
543
|
+
def log_params
|
544
|
+
lparms = @parameters.clone
|
545
|
+
lparms[:cur_host] = @host
|
546
|
+
lparms[:cur_port] = @port
|
547
|
+
lparms[:cur_login] = @login
|
548
|
+
lparms[:cur_passcode] = @passcode
|
549
|
+
lparms[:cur_ssl] = @ssl
|
550
|
+
lparms[:cur_recondelay] = @reconnect_delay
|
551
|
+
lparms[:cur_parseto] = @parse_timeout
|
552
|
+
lparms[:cur_conattempts] = @connection_attempts
|
553
|
+
#
|
554
|
+
lparms
|
555
|
+
end
|
505
556
|
end
|
506
557
|
|
507
558
|
end
|
data/lib/stomp/version.rb
CHANGED
@@ -49,6 +49,20 @@ shared_examples_for "standard Client" do
|
|
49
49
|
}.should_not raise_error
|
50
50
|
end
|
51
51
|
|
52
|
+
it "should raise RuntimeError on duplicate subscriptions" do
|
53
|
+
lambda {
|
54
|
+
@client.subscribe(@destination)
|
55
|
+
@client.subscribe(@destination)
|
56
|
+
}.should raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should raise RuntimeError with duplicate id headers" do
|
60
|
+
lambda {
|
61
|
+
@client.subscribe(@destination, {'id' => 'abcdef'})
|
62
|
+
@client.subscribe(@destination, {'id' => 'abcdef'})
|
63
|
+
}.should raise_error
|
64
|
+
end
|
65
|
+
|
52
66
|
end
|
53
67
|
|
54
68
|
end
|
data/spec/connection_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe Stomp::Connection do
|
@@ -89,6 +90,11 @@ describe Stomp::Connection do
|
|
89
90
|
@tcp_socket.should_not_receive(:puts).with("content-length:7")
|
90
91
|
@connection.publish "/queue", "message", :suppress_content_length => true
|
91
92
|
end
|
93
|
+
|
94
|
+
it "should get the correct byte length when dealing with Unicode characters" do
|
95
|
+
@tcp_socket.should_receive(:puts).with("content-length:18")
|
96
|
+
@connection.publish "/queue", "сообщение" # 'сообщение' is 'message' in Russian
|
97
|
+
end
|
92
98
|
end
|
93
99
|
|
94
100
|
describe "when unacknowledging a message" do
|
@@ -180,6 +186,15 @@ describe Stomp::Connection do
|
|
180
186
|
|
181
187
|
end
|
182
188
|
|
189
|
+
describe "when sending a nil message body" do
|
190
|
+
it "should should not raise an error" do
|
191
|
+
@connection = Stomp::Connection.new("niluser", "nilpass", "localhost", 61613)
|
192
|
+
lambda {
|
193
|
+
@connection.publish("/queue/nilq", nil)
|
194
|
+
}.should_not raise_error
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
183
198
|
describe "when using ssl" do
|
184
199
|
|
185
200
|
# Mocking ruby's openssl extension, so we can test without requiring openssl
|
data/stomp.gemspec
CHANGED
@@ -5,14 +5,14 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{stomp}
|
8
|
-
s.version = "1.1.
|
8
|
+
s.version = "1.1.9"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date = %q{2011-
|
11
|
+
s.authors = [%q{Brian McCallister}, %q{Marius Mathiesen}, %q{Thiago Morello}, %q{Guy M. Allard}]
|
12
|
+
s.date = %q{2011-06-16}
|
13
13
|
s.description = %q{Ruby client for the Stomp messaging protocol}
|
14
|
-
s.email = [
|
15
|
-
s.executables = [
|
14
|
+
s.email = [%q{brianm@apache.org}, %q{marius@stones.com}, %q{morellon@gmail.com}, %q{allard.guy.m@gmail.com}]
|
15
|
+
s.executables = [%q{catstomp}, %q{stompcat}]
|
16
16
|
s.extra_rdoc_files = [
|
17
17
|
"LICENSE",
|
18
18
|
"README.rdoc"
|
@@ -25,7 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
"bin/catstomp",
|
26
26
|
"bin/stompcat",
|
27
27
|
"examples/consumer.rb",
|
28
|
+
"examples/logexamp.rb",
|
28
29
|
"examples/publisher.rb",
|
30
|
+
"examples/slogger.rb",
|
29
31
|
"lib/stomp.rb",
|
30
32
|
"lib/stomp/client.rb",
|
31
33
|
"lib/stomp/connection.rb",
|
@@ -45,25 +47,11 @@ Gem::Specification.new do |s|
|
|
45
47
|
"test/test_message.rb"
|
46
48
|
]
|
47
49
|
s.homepage = %q{https://rubygems.org/gems/stomp}
|
48
|
-
s.require_paths = [
|
49
|
-
s.rubygems_version = %q{1.
|
50
|
+
s.require_paths = [%q{lib}]
|
51
|
+
s.rubygems_version = %q{1.8.5}
|
50
52
|
s.summary = %q{Ruby client for the Stomp messaging protocol}
|
51
|
-
s.test_files = [
|
52
|
-
"examples/consumer.rb",
|
53
|
-
"examples/publisher.rb",
|
54
|
-
"spec/client_shared_examples.rb",
|
55
|
-
"spec/client_spec.rb",
|
56
|
-
"spec/connection_spec.rb",
|
57
|
-
"spec/message_spec.rb",
|
58
|
-
"spec/spec_helper.rb",
|
59
|
-
"test/test_client.rb",
|
60
|
-
"test/test_connection.rb",
|
61
|
-
"test/test_helper.rb",
|
62
|
-
"test/test_message.rb"
|
63
|
-
]
|
64
53
|
|
65
54
|
if s.respond_to? :specification_version then
|
66
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
67
55
|
s.specification_version = 3
|
68
56
|
|
69
57
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
data/test/test_client.rb
CHANGED
@@ -151,6 +151,93 @@ class TestClient < Test::Unit::TestCase
|
|
151
151
|
@client.commit 'tx2'
|
152
152
|
end
|
153
153
|
|
154
|
+
def test_raise_on_multiple_subscriptions_to_same_destination
|
155
|
+
subscribe_dest = destination
|
156
|
+
@client.subscribe(subscribe_dest) {|m| nil }
|
157
|
+
assert_raise(RuntimeError) do
|
158
|
+
@client.subscribe(subscribe_dest) {|m| nil }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_raise_on_multiple_subscriptions_to_same_id
|
163
|
+
subscribe_dest = destination
|
164
|
+
@client.subscribe(subscribe_dest, {'id' => 'myid'}) {|m| nil }
|
165
|
+
assert_raise(RuntimeError) do
|
166
|
+
@client.subscribe(subscribe_dest, {'id' => 'myid'}) {|m| nil }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_raise_on_multiple_subscriptions_to_same_id_mixed
|
171
|
+
subscribe_dest = destination
|
172
|
+
@client.subscribe(subscribe_dest, {'id' => 'myid'}) {|m| nil }
|
173
|
+
assert_raise(RuntimeError) do
|
174
|
+
@client.subscribe(subscribe_dest, {:id => 'myid'}) {|m| nil }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_asterisk_wildcard_subscribe
|
179
|
+
queue_base_name = destination
|
180
|
+
queue1 = queue_base_name + ".a"
|
181
|
+
queue2 = queue_base_name + ".b"
|
182
|
+
send_message = message_text
|
183
|
+
@client.publish queue1, send_message
|
184
|
+
@client.publish queue2, send_message
|
185
|
+
messages = []
|
186
|
+
@client.subscribe(queue_base_name + ".*", :ack => 'client') do |m|
|
187
|
+
messages << m
|
188
|
+
@client.acknowledge(m)
|
189
|
+
end
|
190
|
+
Timeout::timeout(4) do
|
191
|
+
sleep 0.1 while messages.size < 2
|
192
|
+
end
|
193
|
+
|
194
|
+
messages.each do |message|
|
195
|
+
assert_not_nil message
|
196
|
+
assert_equal send_message, message.body
|
197
|
+
end
|
198
|
+
results = [queue1, queue2].collect do |queue|
|
199
|
+
messages.any? do |message|
|
200
|
+
message_source = message.headers['destination']
|
201
|
+
message_source == queue
|
202
|
+
end
|
203
|
+
end
|
204
|
+
assert results.all?{|a| a == true }
|
205
|
+
|
206
|
+
end unless ENV['STOMP_NOWILD']
|
207
|
+
|
208
|
+
def test_greater_than_wildcard_subscribe
|
209
|
+
queue_base_name = destination + "."
|
210
|
+
queue1 = queue_base_name + "foo.a"
|
211
|
+
queue2 = queue_base_name + "bar.a"
|
212
|
+
queue3 = queue_base_name + "foo.b"
|
213
|
+
send_message = message_text
|
214
|
+
@client.publish queue1, send_message
|
215
|
+
@client.publish queue2, send_message
|
216
|
+
@client.publish queue3, send_message
|
217
|
+
messages = []
|
218
|
+
# should subscribe to all three queues
|
219
|
+
@client.subscribe(queue_base_name + ">", :ack => 'client') do |m|
|
220
|
+
messages << m
|
221
|
+
@client.acknowledge(m)
|
222
|
+
end
|
223
|
+
Timeout::timeout(4) do
|
224
|
+
sleep 0.1 while messages.size < 3
|
225
|
+
end
|
226
|
+
|
227
|
+
messages.each do |message|
|
228
|
+
assert_not_nil message
|
229
|
+
assert_equal send_message, message.body
|
230
|
+
end
|
231
|
+
# make sure that the messages received came from the expected queues
|
232
|
+
results = [queue1, queue2, queue3].collect do |queue|
|
233
|
+
messages.any? do |message|
|
234
|
+
message_source = message.headers['destination']
|
235
|
+
message_source == queue
|
236
|
+
end
|
237
|
+
end
|
238
|
+
assert results.all?{|a| a == true }
|
239
|
+
end unless ENV['STOMP_NOWILD'] || ENV['STOMP_APOLLO']
|
240
|
+
|
154
241
|
def test_transaction_with_client_side_redelivery
|
155
242
|
@client.publish destination, message_text
|
156
243
|
|
@@ -252,7 +339,7 @@ class TestClient < Test::Unit::TestCase
|
|
252
339
|
@client.publish(dest, message_text)
|
253
340
|
end
|
254
341
|
#
|
255
|
-
max_sleep=5
|
342
|
+
max_sleep = (RUBY_VERSION =~ /1\.8\.6/) ? 30 : 5
|
256
343
|
sleep_incr = 0.10
|
257
344
|
total_slept = 0
|
258
345
|
while true
|
@@ -272,6 +359,6 @@ class TestClient < Test::Unit::TestCase
|
|
272
359
|
|
273
360
|
def destination
|
274
361
|
name = caller_method_name unless name
|
275
|
-
"/queue/test/ruby/
|
362
|
+
qname = ENV['STOMP_APOLLO'] ? "/queue/test.ruby.stomp." + name : "/queue/test/ruby/stomp/" + name
|
276
363
|
end
|
277
364
|
end
|
data/test/test_connection.rb
CHANGED
@@ -142,19 +142,20 @@ class TestStomp < Test::Unit::TestCase
|
|
142
142
|
|
143
143
|
def test_thread_poll_one
|
144
144
|
received = nil
|
145
|
+
max_sleep = (RUBY_VERSION =~ /1\.8\.6/) ? 5 : 1
|
145
146
|
Thread.new(@conn) do |amq|
|
146
147
|
while true
|
147
148
|
received = amq.poll
|
148
149
|
# One message is needed
|
149
150
|
Thread.exit if received
|
150
|
-
sleep
|
151
|
+
sleep max_sleep
|
151
152
|
end
|
152
153
|
end
|
153
154
|
#
|
154
155
|
@conn.subscribe( make_destination )
|
155
156
|
message = Time.now.to_s
|
156
157
|
@conn.publish(make_destination, message)
|
157
|
-
sleep 1
|
158
|
+
sleep max_sleep+1
|
158
159
|
assert_not_nil received
|
159
160
|
assert_equal message, received.body
|
160
161
|
end
|
@@ -183,7 +184,7 @@ class TestStomp < Test::Unit::TestCase
|
|
183
184
|
@conn.publish(dest, msg)
|
184
185
|
end
|
185
186
|
#
|
186
|
-
max_sleep=5
|
187
|
+
max_sleep = (RUBY_VERSION =~ /1\.8\.6/) ? 30 : 5
|
187
188
|
sleep_incr = 0.10
|
188
189
|
total_slept = 0
|
189
190
|
while true
|
@@ -225,7 +226,7 @@ class TestStomp < Test::Unit::TestCase
|
|
225
226
|
@conn.publish(dest, msg)
|
226
227
|
end
|
227
228
|
#
|
228
|
-
max_sleep=5
|
229
|
+
max_sleep = (RUBY_VERSION =~ /1\.8\.6/) ? 30 : 5
|
229
230
|
sleep_incr = 0.10
|
230
231
|
total_slept = 0
|
231
232
|
while true
|
@@ -237,10 +238,20 @@ class TestStomp < Test::Unit::TestCase
|
|
237
238
|
assert_equal @max_msgs, msg_ctr
|
238
239
|
end
|
239
240
|
|
241
|
+
def test_nil_body
|
242
|
+
dest = make_destination
|
243
|
+
assert_nothing_raised {
|
244
|
+
@conn.publish dest, nil
|
245
|
+
}
|
246
|
+
@conn.subscribe dest
|
247
|
+
msg = @conn.receive
|
248
|
+
assert_equal "", msg.body
|
249
|
+
end
|
250
|
+
|
240
251
|
private
|
241
252
|
def make_destination
|
242
253
|
name = caller_method_name unless name
|
243
|
-
"/queue/test/ruby/stomp/" + name
|
254
|
+
qname = ENV['STOMP_APOLLO'] ? "/queue/test.ruby.stomp." + name : "/queue/test/ruby/stomp/" + name
|
244
255
|
end
|
245
256
|
|
246
257
|
def _test_transaction
|
data/test/test_message.rb
CHANGED
@@ -112,7 +112,7 @@ class TestMessageKcode < Test::Unit::TestCase
|
|
112
112
|
private
|
113
113
|
def make_destination
|
114
114
|
name = caller_method_name unless name
|
115
|
-
"/queue/test/rubyk01/stomp/" + name
|
115
|
+
qname = ENV['STOMP_APOLLO'] ? "/queue/test.rubyk01.stomp." + name : "/queue/test/rubyk01/stomp/" + name
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
metadata
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: stomp
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 1
|
7
|
-
- 1
|
8
|
-
- 8
|
9
|
-
version: 1.1.8
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.9
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Brian McCallister
|
13
9
|
- Marius Mathiesen
|
14
10
|
- Thiago Morello
|
@@ -16,39 +12,33 @@ authors:
|
|
16
12
|
autorequire:
|
17
13
|
bindir: bin
|
18
14
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
dependencies:
|
23
|
-
- !ruby/object:Gem::Dependency
|
15
|
+
date: 2011-06-16 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
24
18
|
name: rspec
|
25
|
-
|
26
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
requirement: &18191140 !ruby/object:Gem::Requirement
|
27
20
|
none: false
|
28
|
-
requirements:
|
29
|
-
- -
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
|
32
|
-
- 2
|
33
|
-
- 3
|
34
|
-
version: "2.3"
|
21
|
+
requirements:
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '2.3'
|
35
25
|
type: :development
|
36
|
-
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: *18191140
|
37
28
|
description: Ruby client for the Stomp messaging protocol
|
38
|
-
email:
|
29
|
+
email:
|
39
30
|
- brianm@apache.org
|
40
31
|
- marius@stones.com
|
41
32
|
- morellon@gmail.com
|
42
33
|
- allard.guy.m@gmail.com
|
43
|
-
executables:
|
34
|
+
executables:
|
44
35
|
- catstomp
|
45
36
|
- stompcat
|
46
37
|
extensions: []
|
47
|
-
|
48
|
-
extra_rdoc_files:
|
38
|
+
extra_rdoc_files:
|
49
39
|
- LICENSE
|
50
40
|
- README.rdoc
|
51
|
-
files:
|
41
|
+
files:
|
52
42
|
- CHANGELOG.rdoc
|
53
43
|
- LICENSE
|
54
44
|
- README.rdoc
|
@@ -56,7 +46,9 @@ files:
|
|
56
46
|
- bin/catstomp
|
57
47
|
- bin/stompcat
|
58
48
|
- examples/consumer.rb
|
49
|
+
- examples/logexamp.rb
|
59
50
|
- examples/publisher.rb
|
51
|
+
- examples/slogger.rb
|
60
52
|
- lib/stomp.rb
|
61
53
|
- lib/stomp/client.rb
|
62
54
|
- lib/stomp/connection.rb
|
@@ -74,47 +66,28 @@ files:
|
|
74
66
|
- test/test_connection.rb
|
75
67
|
- test/test_helper.rb
|
76
68
|
- test/test_message.rb
|
77
|
-
has_rdoc: true
|
78
69
|
homepage: https://rubygems.org/gems/stomp
|
79
70
|
licenses: []
|
80
|
-
|
81
71
|
post_install_message:
|
82
72
|
rdoc_options: []
|
83
|
-
|
84
|
-
require_paths:
|
73
|
+
require_paths:
|
85
74
|
- lib
|
86
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
76
|
none: false
|
88
|
-
requirements:
|
89
|
-
- -
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
|
92
|
-
|
93
|
-
version: "0"
|
94
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
82
|
none: false
|
96
|
-
requirements:
|
97
|
-
- -
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
|
100
|
-
- 0
|
101
|
-
version: "0"
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
102
87
|
requirements: []
|
103
|
-
|
104
88
|
rubyforge_project:
|
105
|
-
rubygems_version: 1.
|
89
|
+
rubygems_version: 1.8.5
|
106
90
|
signing_key:
|
107
91
|
specification_version: 3
|
108
92
|
summary: Ruby client for the Stomp messaging protocol
|
109
|
-
test_files:
|
110
|
-
- examples/consumer.rb
|
111
|
-
- examples/publisher.rb
|
112
|
-
- spec/client_shared_examples.rb
|
113
|
-
- spec/client_spec.rb
|
114
|
-
- spec/connection_spec.rb
|
115
|
-
- spec/message_spec.rb
|
116
|
-
- spec/spec_helper.rb
|
117
|
-
- test/test_client.rb
|
118
|
-
- test/test_connection.rb
|
119
|
-
- test/test_helper.rb
|
120
|
-
- test/test_message.rb
|
93
|
+
test_files: []
|