stomp 1.2.11 → 1.2.12

Sign up to get free protection for your applications and to get access to all the features.
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