stomp 1.2.11 → 1.2.12

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 CHANGED
@@ -1,3 +1,15 @@
1
+ == 1.2.12 20130728
2
+
3
+ * Fix infinite loop when max reconn attempts is reached
4
+ * Enhance JRuby support in tests
5
+ * Issue #63, nil message on rapid AMQ restarts
6
+ * Issue #63, fast spurious failovers with JRuby and AMQ
7
+ * Issue #67, SSL SNI support (thanks Hiram)
8
+ * Proper cleanup when not reliable adn EOF from broker
9
+ * Remove extraneous privte declarations
10
+ * Issue #65, allow non-word characters in login and passcode using stomp://
11
+ * Issue #66, allow a single broker in a failover URL
12
+
1
13
  == 1.2.11 20130728
2
14
 
3
15
  * Issue #60, timeout/hang under JRuby
data/README.rdoc CHANGED
@@ -12,6 +12,7 @@ An implementation of the Stomp protocol for Ruby. See:
12
12
 
13
13
  See _CHANGELOG.rdoc_ for details.
14
14
 
15
+ * Gem version 1.2.12. Miscellaneous issue fixes and cleanup.
15
16
  * Gem version 1.2.11. JRuby and AMQ support fixes.
16
17
  * Gem version 1.2.10. Support failover from heartbeat threads.
17
18
  * Gem version 1.2.9. Miscellaneous fixes and changes.
@@ -54,6 +55,9 @@ See _CHANGELOG.rdoc_ for details.
54
55
  :usecrlf => false, # Use CRLF command and header line ends (1.2+)
55
56
  :max_hbread_fails => 0, # Max HB read fails before retry. 0 => never retry
56
57
  :max_hbrlck_fails => 0, # Max HB read lock obtain fails before retry. 0 => never retry
58
+ :fast_hbs_adjust => 0.0, # Fast heartbeat senders sleep adjustment, seconds, needed ...
59
+ # For fast heartbeat senders. 'fast' == YMMV. If not
60
+ # correct for your environment, expect unnecessary fail overs
57
61
  }
58
62
 
59
63
  # for client
data/examples/slogger.rb CHANGED
@@ -203,7 +203,7 @@ class Slogger
203
203
  end
204
204
 
205
205
  # Stomp 1.1+ - heart beat read (receive) failed.
206
- def on_hbread_fail(parms, ticker_data)
206
+ def on_hbread_fail(parms, ticker_data = {})
207
207
  begin
208
208
  @log.debug "Hbreadf Parms #{info(parms)}"
209
209
  @log.debug "Hbreadf Result #{ticker_data.inspect}"
@@ -213,7 +213,7 @@ class Slogger
213
213
  end
214
214
 
215
215
  # Stomp 1.1+ - heart beat send (transmit) failed.
216
- def on_hbwrite_fail(parms, ticker_data)
216
+ def on_hbwrite_fail(parms, ticker_data = {})
217
217
  begin
218
218
  @log.debug "Hbwritef Parms #{info(parms)}"
219
219
  @log.debug "Hbwritef Result #{ticker_data.inspect}"
@@ -256,7 +256,7 @@ class Slogger
256
256
  end
257
257
 
258
258
  # Log heart beat fires
259
- def on_hbfire(parms, srind, curt)
259
+ def on_hbfire(parms, srind, firedata = {})
260
260
  begin
261
261
  @log.debug "HeartBeat Fire Parms #{info(parms)}"
262
262
  @log.debug "HeartBeat Fire Send/Receive #{srind}"
data/lib/client/utils.rb CHANGED
@@ -21,43 +21,43 @@ module Stomp
21
21
  @reliable = true
22
22
  true
23
23
  end
24
- private :parse_hash_params
25
24
 
26
25
  def parse_stomp_url(login)
27
- regexp = /^stomp:\/\/#{url_regex}/ # e.g. stomp://login:passcode@host:port or stomp://host:port
26
+ regexp = /^stomp:\/\/#{URL_REPAT}/
28
27
  return false unless login =~ regexp
29
28
 
30
- @login = $2 || ""
31
- @passcode = $3 || ""
32
- @host = $4
33
- @port = $5.to_i
29
+ @login = $3 || ""
30
+ @passcode = $4 || ""
31
+ @host = $5
32
+ @port = $6.to_i
33
+
34
34
  @reliable = false
35
35
  true
36
36
  end
37
- private :parse_stomp_url
38
37
 
39
38
  # e.g. failover://(stomp://login1:passcode1@localhost:61616,stomp://login2:passcode2@remotehost:61617)?option1=param
40
39
  def parse_failover_url(login)
41
- regexp = /^failover:(\/\/)?\(stomp(\+ssl)?:\/\/#{url_regex}(,stomp(\+ssl)?:\/\/#{url_regex}\))+(\?(.*))?$/
42
- return false unless login =~ regexp
43
-
44
- first_host = {}
45
- first_host[:ssl] = !$2.nil?
46
- @login = first_host[:login] = $4 || ""
47
- @passcode = first_host[:passcode] = $5 || ""
48
- @host = first_host[:host] = $6
49
- @port = first_host[:port] = $7.to_i || Connection::default_port(first_host[:ssl])
50
- options = $16 || ""
51
- parts = options.split(/&|=/)
52
- options = Hash[*parts]
53
- hosts = [first_host] + parse_hosts(login)
54
- @parameters = {}
55
- @parameters[:hosts] = hosts
56
- @parameters.merge! filter_options(options)
57
- @reliable = true
58
- true
40
+ rval = nil
41
+ if md = FAILOVER_REGEX.match(login)
42
+ finhosts = parse_hosts(login)
43
+ #
44
+ @login = finhosts[0][:login] || ""
45
+ @passcode = finhosts[0][:passcode] || ""
46
+ @host = finhosts[0][:host] || ""
47
+ @port = finhosts[0][:port] || ""
48
+ #
49
+ options = {}
50
+ if md_last = md[md.size-1]
51
+ parts = md_last.split(/&|=/)
52
+ raise Stomp::Error::MalformedFailoverOptionsError unless (parts.size % 2 ) == 0
53
+ options = Hash[*parts]
54
+ end
55
+ @parameters = {:hosts => finhosts}.merge! filter_options(options)
56
+ @reliable = true
57
+ rval = true
58
+ end
59
+ rval
59
60
  end
60
- private :parse_failover_url
61
61
 
62
62
  def parse_positional_params(login, passcode, host, port, reliable)
63
63
  @login = login
@@ -67,7 +67,6 @@ module Stomp
67
67
  @reliable = reliable
68
68
  true
69
69
  end
70
- private :parse_positional_params
71
70
 
72
71
  # Set a subscription id in the headers hash if one does not already exist.
73
72
  # For simplicities sake, all subscriptions have a subscription ID.
@@ -91,29 +90,21 @@ module Stomp
91
90
  id
92
91
  end
93
92
 
94
- # url_regex defines a regex for e.g. login:passcode@host:port or host:port
95
- def url_regex
96
- '(([\w\.\-]*):(\w*)@)?([\w\.\-]+):(\d+)'
97
- end
98
-
99
- # Parse a stomp URL.
100
- def parse_hosts(url)
101
- hosts = []
102
-
103
- host_match = /stomp(\+ssl)?:\/\/(([\w\.]*):(\w*)@)?([\w\.]+):(\d+)\)/
104
- url.scan(host_match).each do |match|
105
- host = {}
106
- host[:ssl] = !match[0].nil?
107
- host[:login] = match[2] || ""
108
- host[:passcode] = match[3] || ""
109
- host[:host] = match[4]
110
- host[:port] = match[5].to_i
111
-
112
- hosts << host
113
- end
114
-
115
- hosts
116
- end
93
+ # Parse a stomp URL.
94
+ def parse_hosts(url)
95
+ hosts = []
96
+ host_match = /stomp(\+ssl)?:\/\/#{URL_REPAT}/
97
+ url.scan(host_match).each do |match|
98
+ host = {}
99
+ host[:ssl] = match[0] == "+ssl" ? true : false
100
+ host[:login] = match[3] || ""
101
+ host[:passcode] = match[4] || ""
102
+ host[:host] = match[5]
103
+ host[:port] = match[6].to_i
104
+ hosts << host
105
+ end
106
+ hosts
107
+ end
117
108
 
118
109
  # A very basic check of required arguments.
119
110
  def check_arguments!()
@@ -161,14 +152,16 @@ module Stomp
161
152
  if message.nil? && (!@reliable)
162
153
  raise Stomp::Error::NilMessageError
163
154
  end
155
+ if message # message can be nil on rapid AMQ stop / start sequences
164
156
  # OK, we have some real data
165
- if message.command == Stomp::CMD_MESSAGE
166
- if listener = find_listener(message)
167
- listener.call(message)
168
- end
169
- elsif message.command == Stomp::CMD_RECEIPT
170
- if listener = @receipt_listeners[message.headers['receipt-id']]
171
- listener.call(message)
157
+ if message.command == Stomp::CMD_MESSAGE
158
+ if listener = find_listener(message)
159
+ listener.call(message)
160
+ end
161
+ elsif message.command == Stomp::CMD_RECEIPT
162
+ if listener = @receipt_listeners[message.headers['receipt-id']]
163
+ listener.call(message)
164
+ end
172
165
  end
173
166
  end
174
167
  end # while true
@@ -91,18 +91,28 @@ module Stomp
91
91
  def _start_send_ticker()
92
92
  sleeptime = @hbsend_interval / 1000000.0 # Sleep time secs
93
93
  reconn = false
94
+ adjust = 0.0
94
95
  @st = Thread.new {
96
+ first_time = true
95
97
  while true do
96
- sleep sleeptime
98
+ #
99
+ slt = sleeptime - adjust - @fast_hbs_adjust
100
+ sleep(slt)
97
101
  next unless @socket # nil under some circumstances ??
98
102
  curt = Time.now.to_f
99
103
  if @logger && @logger.respond_to?(:on_hbfire)
100
- @logger.on_hbfire(log_params, "send_fire", curt)
104
+ @logger.on_hbfire(log_params, "send_fire", :curt => curt, :last_sleep => slt)
101
105
  end
102
106
  delta = curt - @ls
103
- if delta > sleeptime
107
+ # Be tolerant (minus), and always do this the first time through.
108
+ # Reintroduce logic removed in d922fa.
109
+ compval = (@hbsend_interval - (@hbsend_interval/5.0)) / 1000000.0
110
+ if delta > compval || first_time
111
+ first_time = false
104
112
  if @logger && @logger.respond_to?(:on_hbfire)
105
- @logger.on_hbfire(log_params, "send_heartbeat", curt)
113
+ @logger.on_hbfire(log_params, "send_heartbeat", :last_sleep => slt,
114
+ :curt => curt, :last_send => @ls, :delta => delta,
115
+ :compval => compval)
106
116
  end
107
117
  # Send a heartbeat
108
118
  @transmit_semaphore.synchronize do
@@ -135,6 +145,7 @@ module Stomp
135
145
  Thread.exit # This sender thread is done
136
146
  end
137
147
  end
148
+ adjust = Time.now.to_f - curt
138
149
  Thread.pass
139
150
  end
140
151
  }
@@ -155,17 +166,15 @@ module Stomp
155
166
  rdrdy = _is_ready?(@socket)
156
167
  curt = Time.now.to_f
157
168
  if @logger && @logger.respond_to?(:on_hbfire)
158
- @logger.on_hbfire(log_params, "receive_fire", curt)
169
+ @logger.on_hbfire(log_params, "receive_fire", :curt => curt)
159
170
  end
160
-
161
171
  #
162
172
  begin
163
173
  delta = curt - @lr
164
174
  if delta > sleeptime
165
175
  if @logger && @logger.respond_to?(:on_hbfire)
166
- @logger.on_hbfire(log_params, "receive_heartbeat", curt)
176
+ @logger.on_hbfire(log_params, "receive_heartbeat", {})
167
177
  end
168
-
169
178
  # Client code could be off doing something else (that is, no reading of
170
179
  # the socket has been requested by the caller). Try to handle that case.
171
180
  lock = @read_semaphore.try_lock
@@ -223,7 +232,6 @@ module Stomp
223
232
  end
224
233
  fail_hard = true
225
234
  end
226
-
227
235
  # Do we want to attempt a retry?
228
236
  if @reliable
229
237
  # Retry on hard fail or max read fails
@@ -245,7 +253,6 @@ module Stomp
245
253
  Thread.exit # This receiver thread is done
246
254
  end
247
255
  end
248
-
249
256
  Thread.pass # Prior to next receive loop
250
257
  #
251
258
  end # of the "while true"
@@ -279,7 +279,6 @@ module Stomp
279
279
  if @ssl.ciphers # User ciphers list?
280
280
  ctx.ciphers = @ssl.ciphers # Accept user supplied ciphers
281
281
  else
282
- ctx.ciphers = Stomp::DEFAULT_CIPHERS # Just use Stomp defaults
283
282
  end
284
283
  end
285
284
  end
@@ -292,6 +291,7 @@ module Stomp
292
291
 
293
292
  Timeout::timeout(@connect_timeout, Stomp::Error::SocketOpenTimeout) do
294
293
  ssl = OpenSSL::SSL::SSLSocket.new(open_tcp_socket, ctx)
294
+ ssl.hostname = @host if ssl.respond_to? :hostname=
295
295
  ssl.sync_close = true # Sync ssl close with underlying TCP socket
296
296
  ssl.connect
297
297
  end
@@ -181,6 +181,7 @@ module Stomp
181
181
  :stompconn => false,
182
182
  :max_hbread_fails => 0,
183
183
  :max_hbrlck_fails => 0,
184
+ :fast_hbs_adjust => 0.0,
184
185
  }
185
186
 
186
187
  res_params = default_params.merge(params)
@@ -229,6 +230,8 @@ module Stomp
229
230
  begin
230
231
  used_socket = socket()
231
232
  return _receive(used_socket)
233
+ rescue Stomp::Error::MaxReconnectAttempts
234
+ raise
232
235
  rescue
233
236
  @failure = $!
234
237
  raise unless @reliable
data/lib/stomp/client.rb CHANGED
@@ -57,6 +57,7 @@ module Stomp
57
57
  # :usecrlf => false,
58
58
  # :max_hbread_fails => 0,
59
59
  # :max_hbrlck_fails => 0,
60
+ # :fast_hbs_adjust => 0.0,
60
61
  # }
61
62
  #
62
63
  # e.g. c = Stomp::Client.new(hash)
@@ -70,6 +70,7 @@ module Stomp
70
70
  # :usecrlf => false,
71
71
  # :max_hbread_fails => 0,
72
72
  # :max_hbrlck_fails => 0,
73
+ # :fast_hbs_adjust => 0.0,
73
74
  # }
74
75
  #
75
76
  # e.g. c = Stomp::Connection.new(hash)
@@ -116,6 +117,7 @@ module Stomp
116
117
  @usecrlf = false # If true, use \r\n as line ends (1.2 only)
117
118
  @max_hbread_fails = 0 # 0 means never retry for HB read failures
118
119
  @max_hbrlck_fails = 0 # 0 means never retry for HB read lock failures
120
+ @fast_hbs_adjust = 0.0 # Fast heartbeat senders sleep adjustment
119
121
  warn "login looks like a URL, do you have the correct parameters?" if @login =~ /:\/\//
120
122
  end
121
123
 
@@ -150,6 +152,7 @@ module Stomp
150
152
  @usecrlf = @parameters[:usecrlf]
151
153
  @max_hbread_fails = @parameters[:max_hbread_fails]
152
154
  @max_hbrlck_fails = @parameters[:max_hbrlck_fails]
155
+ @fast_hbs_adjust = @parameters[:fast_hbs_adjust]
153
156
  #sets the first host to connect
154
157
  change_host
155
158
  end
@@ -397,7 +400,10 @@ module Stomp
397
400
  receive()
398
401
  end
399
402
 
400
- # receive returns the next Message off of the wire.
403
+ # receive returns the next Message off of the wire. this can return nil
404
+ # in cases where:
405
+ # * the broker has closed the connection
406
+ # * the connection is not reliable
401
407
  def receive()
402
408
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
403
409
  super_result = __old_receive()
@@ -417,6 +423,13 @@ module Stomp
417
423
  super_result = __old_receive()
418
424
  end
419
425
  #
426
+ if super_result.nil? && !@reliable
427
+ @st.kill if @st # Kill ticker thread if any
428
+ @rt.kill if @rt # Kill ticker thread if any
429
+ close_socket()
430
+ @closed = true
431
+ warn 'warning: broker sent EOF, and connection not reliable' unless defined?(Test)
432
+ end
420
433
  if @logger && @logger.respond_to?(:on_receive)
421
434
  @logger.on_receive(log_params, super_result)
422
435
  end
@@ -111,4 +111,11 @@ module Stomp
111
111
  ["EXP-RC4-MD5", "TLSv1/SSLv3", 40, 128],
112
112
  ]
113
113
 
114
+ # stomp URL regex pattern, for e.g. login:passcode@host:port or host:port
115
+ URL_REPAT = '((([\w~!@#$%^&*()\-+=.?:<>,.]*\w):([\w~!@#$%^&*()\-+=.?:<>,.]*))?@)?([\w\.\-]+):(\d+)'
116
+
117
+ # Failover URL regex, for e.g.
118
+ #failover:(stomp+ssl://login1:passcode1@remotehost1:61612,stomp://login2:passcode2@remotehost2:61613)
119
+ FAILOVER_REGEX = /^failover:(\/\/)?\(stomp(\+ssl)?:\/\/#{URL_REPAT}(,stomp(\+ssl)?:\/\/#{URL_REPAT})*\)(\?(.*))?$/
120
+
114
121
  end # Module Stomp
data/lib/stomp/errors.rb CHANGED
@@ -205,6 +205,14 @@ module Stomp
205
205
  end
206
206
  end
207
207
 
208
+ # MalformedFailoverOptionsError is raised if failover URL
209
+ # options can not be parsed
210
+ class MalformedFailoverOptionsError < RuntimeError
211
+ def message
212
+ "failover options are malformed"
213
+ end
214
+ end
215
+
208
216
  end # module Error
209
217
 
210
218
  end # module Stomp
data/lib/stomp/version.rb CHANGED
@@ -6,7 +6,7 @@ module Stomp
6
6
  module Version #:nodoc: all
7
7
  MAJOR = 1
8
8
  MINOR = 2
9
- PATCH = 11
9
+ PATCH = 12
10
10
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
11
11
  end
12
12
  end
@@ -77,6 +77,18 @@ error).
77
77
 
78
78
  -----------------------------------------------------------
79
79
 
80
+ General advice:
81
+
82
+ Set your heartbeat intervals to the maximum possible to obtain your desired
83
+ behavior. Do *not* set them at extremely low values even if the broker allows
84
+ that. An absurd example:
85
+
86
+ heart-beat:1,1
87
+
88
+ which will likely not work well.
89
+
90
+ -----------------------------------------------------------
91
+
80
92
  General notes:
81
93
 
82
94
  In your real world apps, think about whether one or both of these parameters
@@ -98,6 +110,60 @@ We have done a variety of informal tests here, using both server kill and
98
110
  packet drop strategies as appropriate. We believe more real world testing is
99
111
  required.
100
112
 
101
- We already know that the use of IO#ready? will diminish (probably break) JRuby
102
- functionality.
113
+ -----------------------------------------------------------
114
+
115
+ 08/07/2013
116
+
117
+ Issue #63 related, specifically fast send heart beats are being used and
118
+ spurious fail overs occur in rapid succession.
119
+
120
+ Background:
121
+
122
+ Fail over from heartbeat failures was introduced in gem version 1.2.10.
123
+
124
+ Subsequently:
125
+
126
+ This issue has been observed and documented in the following environment:
127
+
128
+ -- JRuby engine 1.7.4 *and*
129
+ -- ActiveMQ 5.8.0 *and*
130
+ -- 'fast' client send heartbeats
131
+
132
+ Heartbeat sends were at 2000ms.
133
+
134
+ At this point in time, fast send heart beats and spurious fail overs have
135
+ *not* been observed using:
136
+
137
+ -- Any native RUBY_ENGINE and ActiveMQ
138
+ -- Any native RUBY_ENGINE and Apollo (client send rates are limited by default)
139
+ -- Any native RUBY_ENGINE and RabbitMQ
140
+ -- JRuby and Apollo (client send rates are limited by default)
141
+ -- JRuby and RabbitMQ
142
+
143
+ Note that 'fast' will depend on your use case for heartbeats. Observations
144
+ are that sending heartbeat times less than 5000ms might be considered 'fast'
145
+ in the targeted environment.
146
+
147
+ The solution / bypass being put in place as of the above date was developed
148
+ through experimentation and is as follows:
149
+
150
+ - Add 'adjustment' logic to the heartbeat sender (thanks to ppaul for this idea).
151
+ - Re-introduce tolerance logic removed in d922fa.
152
+ - Add a new connection hash parameter to adjust heartbeat sends.
153
+
154
+ The newly introduced connection hash parameter is:
155
+
156
+ :fast_hbs_adjust => 0.0 # The default, no adjustment to sender sleep times (sec)
157
+
158
+ Recommendation for gem users that:
159
+
160
+ - Use fast send heartbeats
161
+ - Actually notice spurious fail overs
162
+
163
+ is to provide a very sender sleep time adjustment when connecting. Examples:
164
+
165
+ :fast_hbs_adjust => 0.05 # 50 milliseconds
166
+ :fast_hbs_adjust => 0.10 # 100 milliseconds
167
+
168
+ As usual, YMMV.
103
169
 
data/spec/client_spec.rb CHANGED
@@ -254,7 +254,7 @@ describe Stomp::Client do
254
254
  end
255
255
 
256
256
  it "should properly parse a URL with failover:" do
257
- url = "failover:(stomp://login1:passcode1@localhost:61616,stomp://login2:passcode2@remotehost1:61617),stomp://login3:passcode3@remotehost2:61618)"
257
+ url = "failover:(stomp://login1:passcode1@localhost:61616,stomp://login2:passcode2@remotehost1:61617,stomp://login3:passcode3@remotehost2:61618)"
258
258
 
259
259
  @parameters[:hosts] = [
260
260
  {:login => "login1", :passcode => "passcode1", :host => "localhost", :port => 61616, :ssl => false},
@@ -283,7 +283,7 @@ describe Stomp::Client do
283
283
  end
284
284
 
285
285
  it "should properly parse a URL with user and/or password blank" do
286
- url = "failover:(stomp://:@localhost:61616,stomp://:@remotehost:61617)"
286
+ url = "failover:(stomp://@localhost:61616,stomp://@remotehost:61617)"
287
287
 
288
288
  @parameters[:hosts] = [
289
289
  {:login => "", :passcode => "", :host => "localhost", :port => 61616, :ssl => false},
@@ -27,6 +27,7 @@ describe Stomp::Connection do
27
27
  :usecrlf => false,
28
28
  :max_hbread_fails => 0,
29
29
  :max_hbrlck_fails => 0,
30
+ :fast_hbs_adjust => 0.0,
30
31
  }
31
32
 
32
33
  #POG:
@@ -89,11 +90,12 @@ describe Stomp::Connection do
89
90
  "backOffMultiplier" => 2,
90
91
  "maxReconnectAttempts" => 0,
91
92
  "randomize" => false,
92
- "connect_timeout" => 0,
93
- "parse_timeout" => 5,
93
+ "connectTimeout" => 0,
94
+ "parseTimeout" => 5,
94
95
  "usecrlf" => false,
95
- :max_hbread_fails => 0,
96
- :max_hbrlck_fails => 0,
96
+ :maxHbreadFails => 0,
97
+ :maxHbrlckFails => 0,
98
+ :fastHbsAdjust => 0.0,
97
99
  }
98
100
 
99
101
  @connection = Stomp::Connection.new(used_hash)
@@ -272,7 +274,9 @@ describe Stomp::Connection do
272
274
 
273
275
  before(:each) do
274
276
  ssl_parameters = {:hosts => [{:login => "login2", :passcode => "passcode2", :host => "remotehost", :ssl => true}]}
275
- @ssl_socket = mock(:ssl_socket, :puts => nil, :write => nil, :setsockopt => nil, :flush => true)
277
+ @ssl_socket = mock(:ssl_socket, :puts => nil, :write => nil,
278
+ :setsockopt => nil, :flush => true)
279
+ @ssl_socket.stub!(:sync_close=)
276
280
 
277
281
  TCPSocket.should_receive(:open).and_return @tcp_socket
278
282
  OpenSSL::SSL::SSLSocket.should_receive(:new).and_return(@ssl_socket)
@@ -344,6 +348,7 @@ describe Stomp::Connection do
344
348
  :stompconn => false,
345
349
  :max_hbread_fails => 0,
346
350
  :max_hbrlck_fails => 0,
351
+ :fast_hbs_adjust => 0.0,
347
352
  }
348
353
 
349
354
  used_hash = {
@@ -382,6 +387,7 @@ describe Stomp::Connection do
382
387
  :usecrlf => true,
383
388
  :max_hbread_fails => 123,
384
389
  :max_hbrlck_fails => 456,
390
+ :fast_hbs_adjust => 0.2,
385
391
  }
386
392
 
387
393
  @connection = Stomp::Connection.new(used_hash)
@@ -430,7 +436,14 @@ describe Stomp::Connection do
430
436
 
431
437
  @connection.instance_variable_set(:@connection_attempts, limit)
432
438
  @connection.send(:max_reconnect_attempts?).should be_true
439
+ end
440
+
441
+ # These should be raised for the user to deal with
442
+ it "should not rescue MaxReconnectAttempts" do
443
+ @connection = Stomp::Connection.new(@parameters)
444
+ @connection.stub(:socket).and_raise(Stomp::Error::MaxReconnectAttempts)
433
445
 
446
+ expect { @connection.receive() }.to raise_error
434
447
  end
435
448
  end
436
449
 
data/stomp.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{stomp}
8
- s.version = "1.2.11"
8
+ s.version = "1.2.12"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Brian McCallister", "Marius Mathiesen", "Thiago Morello", "Guy M. Allard"]
12
- s.date = %q{2013-07-28}
12
+ s.date = %q{2013-08-11}
13
13
  s.description = %q{Ruby client for the Stomp messaging protocol. Note that this gem is no longer supported on rubyforge.}
14
14
  s.email = ["brianm@apache.org", "marius@stones.com", "morellon@gmail.com", "allard.guy.m@gmail.com"]
15
15
  s.executables = ["catstomp", "stompcat"]
@@ -65,6 +65,7 @@ Gem::Specification.new do |s|
65
65
  "test/test_helper.rb",
66
66
  "test/test_message.rb",
67
67
  "test/test_ssl.rb",
68
+ "test/test_urlogin.rb",
68
69
  "test/tlogger.rb"
69
70
  ]
70
71
  s.files = [
@@ -129,6 +130,7 @@ Gem::Specification.new do |s|
129
130
  "test/test_helper.rb",
130
131
  "test/test_message.rb",
131
132
  "test/test_ssl.rb",
133
+ "test/test_urlogin.rb",
132
134
  "test/tlogger.rb"
133
135
  ]
134
136
  s.homepage = %q{https://github.com/stompgem/stomp}
@@ -484,10 +484,11 @@ class TestConnection < Test::Unit::TestCase
484
484
  def test_conn10_simple
485
485
  @conn.disconnect
486
486
  #
487
+ vhost = ENV['STOMP_RABBIT'] ? "/" : host
487
488
  hash = { :hosts => [
488
489
  {:login => user, :passcode => passcode, :host => host, :port => port, :ssl => false},
489
490
  ],
490
- :connect_headers => {"accept-version" => "1.0", "host" => host},
491
+ :connect_headers => {"accept-version" => "1.0", "host" => vhost},
491
492
  :reliable => false,
492
493
  }
493
494
  c = nil
@@ -499,7 +500,7 @@ class TestConnection < Test::Unit::TestCase
499
500
  hash = { :hosts => [
500
501
  {:login => user, :passcode => passcode, :host => host, :port => port, :ssl => false},
501
502
  ],
502
- :connect_headers => {"accept-version" => "3.14159,1.0,12.0", "host" => host},
503
+ :connect_headers => {"accept-version" => "3.14159,1.0,12.0", "host" => vhost},
503
504
  :reliable => false,
504
505
  }
505
506
  c = nil
data/test/test_helper.rb CHANGED
@@ -84,7 +84,7 @@ module TestBase
84
84
  # Get a Stomp SSL Connection.
85
85
  def get_ssl_connection()
86
86
  ch = get_conn_headers()
87
- ssl_params = Stomp::SSLParams.new # S/B safe for all Ruby versions tested
87
+ ssl_params = Stomp::SSLParams.new(:use_ruby_ciphers => jruby?())
88
88
  hash = { :hosts => [
89
89
  {:login => user, :passcode => passcode, :host => host, :port => ssl_port, :ssl => ssl_params},
90
90
  ],
@@ -164,5 +164,10 @@ module TestBase
164
164
  end
165
165
  end
166
166
 
167
+ # Check for JRuby before a connection exists
168
+ def jruby?()
169
+ jr = defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/ ? true : false
170
+ end
171
+
167
172
  end
168
173
 
@@ -0,0 +1,86 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ if Kernel.respond_to?(:require_relative)
4
+ require_relative("test_helper")
5
+ else
6
+ $:.unshift(File.dirname(__FILE__))
7
+ require 'test_helper'
8
+ end
9
+
10
+ =begin
11
+
12
+ Main class for testing Stomp::Client URL based Logins.
13
+
14
+ =end
15
+ class TestURLLogins < Test::Unit::TestCase
16
+ include TestBase
17
+
18
+ def setup
19
+ hostname = host()
20
+ portnum = port()
21
+ sslpn = ssl_port()
22
+ @tdstomp = [
23
+ "stomp://guestl:guestp@#{hostname}:#{portnum}",
24
+ "stomp://#{hostname}:#{portnum}",
25
+ "stomp://@#{hostname}:#{portnum}",
26
+ "stomp://f@#$$%^&*()_+=o.o:@#{hostname}:#{portnum}",
27
+ 'stomp://f@#$$%^&*()_+=o.o::b~!@#$%^&*()+-_=?:<>,.@@' + hostname + ":#{portnum}",
28
+ ]
29
+ @tdfailover = [
30
+ "failover://(stomp://#{hostname}:#{portnum})",
31
+ "failover://(stomp+ssl://#{hostname}:#{sslpn})",
32
+ "failover://(stomp://#{hostname}:#{portnum})",
33
+ "failover://(stomp://#{hostname}:#{portnum})?whatup=doc&coyote=kaboom",
34
+ "failover://(stomp://#{hostname}:#{portnum})?whatup=doc",
35
+ "failover://(stomp://#{hostname}:#{portnum})?whatup=doc&coyote=kaboom&randomize=true",
36
+ 'failover://(stomp://f@#$$%^&*()_+=o.o::b~!@#$%^&*()+-_=?:<>,.@@' + "localhost" + ":#{portnum}" + ")",
37
+ 'failover://(stomp://f@#$$%^&*()_+=o.o::b~!@#$%^&*()+-_=:<>,.@@' + "localhost" + ":#{portnum}" + ")",
38
+ 'failover://(stomp://f@#$$%^&*()_+=o.o::b~!@#$%^&*()+-_=?:<>,.@@' + "localhost" + ":#{portnum}" + ")?a=b",
39
+ 'failover://(stomp://f@#$$%^&*()_+=o.o::b~!@#$%^&*()+-_=:<>,.@@' + "localhost" + ":#{portnum}" + ")?c=d&e=f",
40
+ "failover://(stomp://usera:passa@#{hostname}:#{portnum})",
41
+ "failover://(stomp+ssl://usera:passa@#{hostname}:#{sslpn})",
42
+ "failover://(stomp://usera:@#{hostname}:#{portnum})",
43
+ "failover://(stomp://#{hostname}:#{portnum},stomp://#{hostname}:#{portnum})",
44
+ "failover://(stomp://usera:passa@#{hostname}:#{portnum},stomp://#{hostname}:#{portnum})",
45
+ "failover://(stomp://usera:@#{hostname}:#{portnum},stomp://#{hostname}:#{portnum})",
46
+ "failover://(stomp://usera:@#{hostname}:#{portnum},stomp+ssl://#{hostname}:#{sslpn})",
47
+ "failover://(stomp://#{hostname}:#{portnum},stomp://#{hostname}:#{portnum})?a=b&c=d",
48
+ "failover://(stomp://#{hostname}:#{portnum},stomp://#{hostname}:#{portnum})?a=b&c=d&connect_timeout=2020",
49
+ ]
50
+
51
+ @badparms = "failover://(stomp://#{hostname}:#{portnum})?a=b&noequal"
52
+ end
53
+
54
+ def teardown
55
+ @client.close if @client && @client.open? # allow tests to close
56
+ end
57
+
58
+ # test stomp:// URLs
59
+ def test_0010_stomp_urls()
60
+ @tdstomp.each_with_index do |url, ndx|
61
+ c = Stomp::Client.new(url)
62
+ assert !c.nil?, url
63
+ assert c.open?, url
64
+ c.close
65
+ end
66
+ end
67
+
68
+ # test failover:// urls
69
+ def test_0020_failover_urls()
70
+ @tdfailover.each_with_index do |url, ndx|
71
+ c = Stomp::Client.new(url)
72
+ assert !c.nil?, url
73
+ assert c.open?, url
74
+ c.close
75
+ end
76
+ end
77
+
78
+ # test failover:// with bad parameters
79
+ def test_0020_failover_badparms()
80
+ assert_raise(Stomp::Error::MalformedFailoverOptionsError) {
81
+ c = Stomp::Client.new(@badparms)
82
+ }
83
+ end
84
+
85
+ end unless ENV['STOMP_RABBIT']
86
+
data/test/tlogger.rb CHANGED
@@ -51,11 +51,11 @@ class Tlogger
51
51
  end
52
52
 
53
53
  # Stomp 1.1+ - heart beat thread fires
54
- def on_hbfire(parms, type, time)
54
+ def on_hbfire(parms, type, firedata)
55
55
  begin
56
56
  @log.debug "HBfire #{type} " + "=" * 30
57
57
  @log.debug "HBfire #{type} Parms #{info(parms)}"
58
- @log.debug "HBfire #{type} Time #{time}"
58
+ @log.debug "HBfire #{type} Firedata #{firedata.inspect}"
59
59
  rescue
60
60
  @log.debug "HBfire #{type} oops"
61
61
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stomp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 11
10
- version: 1.2.11
9
+ - 12
10
+ version: 1.2.12
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brian McCallister
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2013-07-28 00:00:00 -04:00
21
+ date: 2013-08-11 00:00:00 -04:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -99,6 +99,7 @@ extra_rdoc_files:
99
99
  - test/test_helper.rb
100
100
  - test/test_message.rb
101
101
  - test/test_ssl.rb
102
+ - test/test_urlogin.rb
102
103
  - test/tlogger.rb
103
104
  files:
104
105
  - CHANGELOG.rdoc
@@ -162,6 +163,7 @@ files:
162
163
  - test/test_helper.rb
163
164
  - test/test_message.rb
164
165
  - test/test_ssl.rb
166
+ - test/test_urlogin.rb
165
167
  - test/tlogger.rb
166
168
  has_rdoc: true
167
169
  homepage: https://github.com/stompgem/stomp