bunny 2.15.0 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -12
  3. data/lib/bunny/channel.rb +2 -2
  4. data/lib/bunny/reader_loop.rb +11 -11
  5. data/lib/bunny/session.rb +32 -9
  6. data/lib/bunny/transport.rb +12 -11
  7. data/lib/bunny/version.rb +1 -1
  8. data/spec/higher_level_api/integration/basic_consume_spec.rb +14 -6
  9. data/spec/higher_level_api/integration/connection_spec.rb +26 -0
  10. data/spec/higher_level_api/integration/tls_connection_spec.rb +25 -32
  11. data/spec/issues/issue609_spec.rb +84 -0
  12. data/spec/lower_level_api/integration/basic_cancel_spec.rb +1 -1
  13. data/spec/lower_level_api/integration/basic_consume_spec.rb +8 -8
  14. metadata +28 -87
  15. data/.github/ISSUE_TEMPLATE.md +0 -18
  16. data/.gitignore +0 -28
  17. data/.rspec +0 -1
  18. data/.travis.yml +0 -33
  19. data/.yardopts +0 -8
  20. data/CONTRIBUTING.md +0 -132
  21. data/ChangeLog.md +0 -2084
  22. data/Gemfile +0 -55
  23. data/LICENSE +0 -21
  24. data/Rakefile +0 -54
  25. data/benchmarks/basic_publish/with_128K_messages.rb +0 -35
  26. data/benchmarks/basic_publish/with_1k_messages.rb +0 -35
  27. data/benchmarks/basic_publish/with_4K_messages.rb +0 -35
  28. data/benchmarks/basic_publish/with_64K_messages.rb +0 -35
  29. data/benchmarks/channel_open.rb +0 -28
  30. data/benchmarks/mutex_and_monitor.rb +0 -42
  31. data/benchmarks/queue_declare.rb +0 -29
  32. data/benchmarks/queue_declare_and_bind.rb +0 -29
  33. data/benchmarks/queue_declare_bind_and_delete.rb +0 -29
  34. data/benchmarks/synchronized_sorted_set.rb +0 -53
  35. data/benchmarks/write_vs_write_nonblock.rb +0 -49
  36. data/bunny.gemspec +0 -34
  37. data/docker/Dockerfile +0 -24
  38. data/docker/apt/preferences.d/erlang +0 -3
  39. data/docker/apt/sources.list.d/bintray.rabbitmq.list +0 -2
  40. data/docker/docker-entrypoint.sh +0 -26
  41. data/docker/rabbitmq.conf +0 -29
  42. data/docker-compose.yml +0 -28
  43. data/examples/connection/authentication_failure.rb +0 -16
  44. data/examples/connection/automatic_recovery_with_basic_get.rb +0 -40
  45. data/examples/connection/automatic_recovery_with_client_named_queues.rb +0 -36
  46. data/examples/connection/automatic_recovery_with_multiple_consumers.rb +0 -46
  47. data/examples/connection/automatic_recovery_with_republishing.rb +0 -109
  48. data/examples/connection/automatic_recovery_with_server_named_queues.rb +0 -35
  49. data/examples/connection/channel_level_exception.rb +0 -27
  50. data/examples/connection/disabled_automatic_recovery.rb +0 -34
  51. data/examples/connection/heartbeat.rb +0 -17
  52. data/examples/connection/manually_reconnecting_consumer.rb +0 -23
  53. data/examples/connection/manually_reconnecting_publisher.rb +0 -28
  54. data/examples/connection/unknown_host.rb +0 -16
  55. data/examples/consumers/high_and_low_priority.rb +0 -50
  56. data/examples/guides/exchanges/direct_exchange_routing.rb +0 -36
  57. data/examples/guides/exchanges/fanout_exchange_routing.rb +0 -28
  58. data/examples/guides/exchanges/headers_exchange_routing.rb +0 -31
  59. data/examples/guides/exchanges/mandatory_messages.rb +0 -30
  60. data/examples/guides/extensions/alternate_exchange.rb +0 -30
  61. data/examples/guides/extensions/basic_nack.rb +0 -33
  62. data/examples/guides/extensions/connection_blocked.rb +0 -35
  63. data/examples/guides/extensions/consumer_cancellation_notification.rb +0 -39
  64. data/examples/guides/extensions/dead_letter_exchange.rb +0 -32
  65. data/examples/guides/extensions/exchange_to_exchange_bindings.rb +0 -29
  66. data/examples/guides/extensions/per_message_ttl.rb +0 -36
  67. data/examples/guides/extensions/per_queue_message_ttl.rb +0 -36
  68. data/examples/guides/extensions/publisher_confirms.rb +0 -28
  69. data/examples/guides/extensions/queue_lease.rb +0 -26
  70. data/examples/guides/extensions/sender_selected_distribution.rb +0 -32
  71. data/examples/guides/getting_started/blabbr.rb +0 -27
  72. data/examples/guides/getting_started/hello_world.rb +0 -22
  73. data/examples/guides/getting_started/weathr.rb +0 -49
  74. data/examples/guides/queues/one_off_consumer.rb +0 -25
  75. data/examples/guides/queues/redeliveries.rb +0 -81
  76. data/profiling/basic_publish/with_4K_messages.rb +0 -33
  77. data/repl +0 -3
  78. data/spec/tls/ca_certificate.pem +0 -29
  79. data/spec/tls/ca_key.pem +0 -52
  80. data/spec/tls/client_certificate.pem +0 -29
  81. data/spec/tls/client_key.pem +0 -51
  82. data/spec/tls/generate-server-cert.sh +0 -8
  83. data/spec/tls/server-openssl.cnf +0 -10
  84. data/spec/tls/server.csr +0 -16
  85. data/spec/tls/server_certificate.pem +0 -29
  86. data/spec/tls/server_key.pem +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6abcaa979facd973a801a4433d3a6985e15e89aa84cc0078cc464af3be6c4542
4
- data.tar.gz: d8bc430b598d1a267fe075028e9536efeeb008c72d9387daaaa30c79391d54d8
3
+ metadata.gz: d6de535f1d386dbf46fd89a733c1c44915280af55c3cc3cc56467abe0ead9c24
4
+ data.tar.gz: 6048aea84078fb8995718ed774d9a3956dc91645b24c09382cd54283b444aabe
5
5
  SHA512:
6
- metadata.gz: 384472c28da9fabdf01a9e1c403c9009bf000cd8a3256cbffab531f7e5582425d15320255a966b89c5075f1fb1bc029deef21e1d5fd776de2d4f9714e8f1553f
7
- data.tar.gz: 2ccbfbde0c9f0a2ff0202cb1160d569cbbdc94095e79d021d59a9e7949fd1579189fddcb61849125d4cfefce7ad0a733943f7d3a54097e7fb2ed83117f15ec1f
6
+ metadata.gz: b3575710f81dabf6c116c92c4ac1807a29f0c0bcd1bd5fb35ae1fd9dd468df193efac49d0ad5e77ef04ecc53e97b9b4e13e70f4207972ba0c2335c28afcd6c9b
7
+ data.tar.gz: 8b90dd4da7dab28b529e78cf1282656ca1904432b1017ee5574545c1972315f975d175c718481372604b61796e9ae56b293a342dcba800fa0929e4b80cd7a3c4
data/README.md CHANGED
@@ -43,12 +43,11 @@ Specific examples:
43
43
  Web applications that display that information in the real time.
44
44
 
45
45
 
46
-
47
46
  ## Supported Ruby Versions
48
47
 
49
48
  Modern Bunny versions support
50
49
 
51
- * CRuby 2.3 through 2.6 (inclusive)
50
+ * CRuby 2.5 through 3.0 (inclusive)
52
51
 
53
52
  Bunny works sufficiently well on JRuby but there are known
54
53
  JRuby bugs in versions prior to JRuby 9000 that cause high CPU burn. JRuby users should
@@ -71,10 +70,8 @@ a stable public API.
71
70
  Change logs per release series:
72
71
 
73
72
  * [master](https://github.com/ruby-amqp/bunny/blob/master/ChangeLog.md)
74
- * [2.14.x](https://github.com/ruby-amqp/bunny/blob/2.13.x-stable/ChangeLog.md)
75
- * [2.13.x](https://github.com/ruby-amqp/bunny/blob/2.13.x-stable/ChangeLog.md)
76
- * [2.12.x](https://github.com/ruby-amqp/bunny/blob/2.12.x-stable/ChangeLog.md)
77
- * [2.11.x](https://github.com/ruby-amqp/bunny/blob/2.11.x-stable/ChangeLog.md)
73
+ * [2.18.x](https://github.com/ruby-amqp/bunny/blob/2.18.x-stable/ChangeLog.md)
74
+ * [2.17.x](https://github.com/ruby-amqp/bunny/blob/2.17.x-stable/ChangeLog.md)
78
75
 
79
76
 
80
77
 
@@ -97,7 +94,7 @@ gem install bunny
97
94
  To use Bunny in a project managed with Bundler:
98
95
 
99
96
  ``` ruby
100
- gem "bunny", ">= 2.14.1"
97
+ gem "bunny", ">= 2.18.0"
101
98
  ```
102
99
 
103
100
 
@@ -117,20 +114,31 @@ conn.start
117
114
 
118
115
  # open a channel
119
116
  ch = conn.create_channel
117
+ ch.confirm_select
120
118
 
121
119
  # declare a queue
122
120
  q = ch.queue("test1")
121
+ q.subscribe(manual_ack: true) do |delivery_info, metadata, payload|
122
+ puts "This is the message: #{payload}"
123
+ # acknowledge the delivery so that RabbitMQ can mark it for deletion
124
+ ch.ack(delivery_info.delivery_tag)
125
+ end
123
126
 
124
127
  # publish a message to the default exchange which then gets routed to this queue
125
128
  q.publish("Hello, everybody!")
126
129
 
127
- # fetch a message from the queue
128
- delivery_info, metadata, payload = q.pop
130
+ # await confirmations from RabbitMQ, see
131
+ # https://www.rabbitmq.com/publishers.html#data-safety for details
132
+ ch.wait_for_confirms
133
+
134
+ # give the above consumer some time consume the delivery and print out the message
135
+ sleep 1
129
136
 
130
- puts "This is the message: #{payload}"
137
+ puts "Done"
131
138
 
139
+ ch.close
132
140
  # close the connection
133
- conn.stop
141
+ conn.close
134
142
  ```
135
143
 
136
144
 
@@ -142,7 +150,7 @@ For a 15 minute tutorial using more practical examples, see [Getting Started wit
142
150
 
143
151
  ### Guides
144
152
 
145
- Other documentation guides are available at [rubybunny.info](http://rubybunny.info):
153
+ Bunny documentation guides are available at [rubybunny.info](http://rubybunny.info):
146
154
 
147
155
  * [Queues and Consumers](http://rubybunny.info/articles/queues.html)
148
156
  * [Exchanges and Publishers](http://rubybunny.info/articles/exchanges.html)
@@ -154,6 +162,16 @@ Other documentation guides are available at [rubybunny.info](http://rubybunny.in
154
162
  * [Using RabbitMQ Extensions with Bunny](http://rubybunny.info/articles/extensions.html)
155
163
  * [Durability and Related Matters](http://rubybunny.info/articles/durability.html)
156
164
 
165
+ Some highly relevant RabbitMQ documentation guides:
166
+
167
+ * [Connections](https://www.rabbitmq.com/connections.html)
168
+ * [Channels](https://www.rabbitmq.com/channels.html)
169
+ * [Queues](https://www.rabbitmq.com/queues.html)
170
+ * [Publishers](https://www.rabbitmq.com/publishers.html)
171
+ * [Consumers](https://www.rabbitmq.com/consumers.html)
172
+ * Data safety: publisher and consumer [Confirmations](https://www.rabbitmq.com/confirms.html)
173
+ * [Production Checklist](https://www.rabbitmq.com/production-checklist.html)
174
+
157
175
  ### API Reference
158
176
 
159
177
  [Bunny API Reference](http://reference.rubybunny.info/).
data/lib/bunny/channel.rb CHANGED
@@ -1156,7 +1156,7 @@ module Bunny
1156
1156
 
1157
1157
  # @group Exchange operations (exchange.*)
1158
1158
 
1159
- # Declares a exchange using echange.declare AMQP 0.9.1 method.
1159
+ # Declares a exchange using exchange.declare AMQP 0.9.1 method.
1160
1160
  #
1161
1161
  # @param [String] name The name of the exchange. Note that LF and CR characters
1162
1162
  # will be stripped from the value.
@@ -1789,7 +1789,7 @@ module Bunny
1789
1789
  # @private
1790
1790
  def handle_ack_or_nack(delivery_tag_before_offset, multiple, nack)
1791
1791
  delivery_tag = delivery_tag_before_offset + @delivery_tag_offset
1792
- confirmed_range_start = multiple ? @delivery_tag_offset + 1 : delivery_tag
1792
+ confirmed_range_start = multiple ? @delivery_tag_offset + @unconfirmed_set.min : delivery_tag
1793
1793
  confirmed_range_end = delivery_tag
1794
1794
  confirmed_range = (confirmed_range_start..confirmed_range_end)
1795
1795
 
@@ -9,17 +9,17 @@ module Bunny
9
9
  # @private
10
10
  class ReaderLoop
11
11
 
12
- def initialize(transport, session, session_thread)
13
- @transport = transport
14
- @session = session
15
- @session_thread = session_thread
16
- @logger = @session.logger
12
+ def initialize(transport, session, session_error_handler)
13
+ @transport = transport
14
+ @session = session
15
+ @session_error_handler = session_error_handler
16
+ @logger = @session.logger
17
17
 
18
- @mutex = Mutex.new
18
+ @mutex = Mutex.new
19
19
 
20
- @stopping = false
21
- @stopped = false
22
- @network_is_down = false
20
+ @stopping = false
21
+ @stopped = false
22
+ @network_is_down = false
23
23
  end
24
24
 
25
25
 
@@ -47,7 +47,7 @@ module Bunny
47
47
  @session.handle_network_failure(e)
48
48
  else
49
49
  log_exception(e)
50
- @session_thread.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
50
+ @session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
51
51
  end
52
52
  rescue ShutdownSignal => _
53
53
  @mutex.synchronize { @stopping = true }
@@ -58,7 +58,7 @@ module Bunny
58
58
  log_exception(e)
59
59
 
60
60
  @network_is_down = true
61
- @session_thread.raise(Bunny::NetworkFailure.new("caught an unexpected exception in the network loop: #{e.message}", e))
61
+ @session_error_handler.raise(Bunny::NetworkFailure.new("caught an unexpected exception in the network loop: #{e.message}", e))
62
62
  end
63
63
  rescue Errno::EBADF => _ebadf
64
64
  break if terminate?
data/lib/bunny/session.rb CHANGED
@@ -89,6 +89,7 @@ module Bunny
89
89
  # @return [Integer] Timeout for blocking protocol operations (queue.declare, queue.bind, etc), in milliseconds. Default is 15000.
90
90
  attr_reader :continuation_timeout
91
91
  attr_reader :network_recovery_interval
92
+ attr_reader :connection_name
92
93
  attr_accessor :socket_configurator
93
94
 
94
95
  # @param [String, Hash] connection_string_or_opts Connection string or a hash of connection options
@@ -123,10 +124,14 @@ module Bunny
123
124
  # @option connection_string_or_opts [Boolean] :automatically_recover (true) Should automatically recover from network failures?
124
125
  # @option connection_string_or_opts [Integer] :recovery_attempts (nil) Max number of recovery attempts, nil means forever
125
126
  # @option connection_string_or_opts [Integer] :reset_recovery_attempts_after_reconnection (true) Should recovery attempt counter be reset after successful reconnection? When set to false, the attempt counter will last through the entire lifetime of the connection object.
127
+ # @option connection_string_or_opts [Proc] :recovery_attempt_started (nil) Will be called before every connection recovery attempt
128
+ # @option connection_string_or_opts [Proc] :recovery_completed (nil) Will be called after successful connection recovery
126
129
  # @option connection_string_or_opts [Boolean] :recover_from_connection_close (true) Should this connection recover after receiving a server-sent connection.close (e.g. connection was force closed)?
130
+ # @option connection_string_or_opts [Object] :session_error_handler (Thread.current) Object which responds to #raise that will act as a session error handler. Defaults to Thread.current, which will raise asynchronous exceptions in the thread that created the session.
127
131
  #
128
132
  # @option optz [String] :auth_mechanism ("PLAIN") Authentication mechanism, PLAIN or EXTERNAL
129
133
  # @option optz [String] :locale ("PLAIN") Locale RabbitMQ should use
134
+ # @option optz [String] :connection_name (nil) Client-provided connection name, if any. Note that the value returned does not uniquely identify a connection and cannot be used as a connection identifier in HTTP API requests.
130
135
  #
131
136
  # @see http://rubybunny.info/articles/connecting.html Connecting to RabbitMQ guide
132
137
  # @see http://rubybunny.info/articles/tls.html TLS/SSL guide
@@ -169,7 +174,7 @@ module Bunny
169
174
  @automatically_recover = if opts[:automatically_recover].nil? && opts[:automatic_recovery].nil?
170
175
  true
171
176
  else
172
- opts[:automatically_recover] || opts[:automatic_recovery]
177
+ opts[:automatically_recover] | opts[:automatic_recovery]
173
178
  end
174
179
  @recovering_from_network_failure = false
175
180
  @max_recovery_attempts = opts[:recovery_attempts]
@@ -197,7 +202,9 @@ module Bunny
197
202
  @client_heartbeat = self.heartbeat_from(opts)
198
203
 
199
204
  client_props = opts[:properties] || opts[:client_properties] || {}
205
+ @connection_name = client_props[:connection_name] || opts[:connection_name]
200
206
  @client_properties = DEFAULT_CLIENT_PROPERTIES.merge(client_props)
207
+ .merge(connection_name: connection_name)
201
208
  @mechanism = normalize_auth_mechanism(opts.fetch(:auth_mechanism, "PLAIN"))
202
209
  @credentials_encoder = credentials_encoder_for(@mechanism)
203
210
  @locale = @opts.fetch(:locale, DEFAULT_LOCALE)
@@ -213,9 +220,11 @@ module Bunny
213
220
  @address_index_mutex = @mutex_impl.new
214
221
 
215
222
  @channels = Hash.new
216
- @recovery_completed = opts[:recovery_completed]
217
223
 
218
- @origin_thread = Thread.current
224
+ @recovery_attempt_started = opts[:recovery_attempt_started]
225
+ @recovery_completed = opts[:recovery_completed]
226
+
227
+ @session_error_handler = opts.fetch(:session_error_handler, Thread.current)
219
228
 
220
229
  self.reset_continuations
221
230
  self.initialize_transport
@@ -528,6 +537,18 @@ module Bunny
528
537
  end
529
538
  end
530
539
 
540
+ # Defines a callable (e.g. a block) that will be called
541
+ # before every connection recovery attempt.
542
+ def before_recovery_attempt_starts(&block)
543
+ @recovery_attempt_started = block
544
+ end
545
+
546
+ # Defines a callable (e.g. a block) that will be called
547
+ # after successful connection recovery.
548
+ def after_recovery_completed(&block)
549
+ @recovery_completed = block
550
+ end
551
+
531
552
 
532
553
  #
533
554
  # Implementation
@@ -745,6 +766,7 @@ module Bunny
745
766
  def recover_from_network_failure
746
767
  sleep @network_recovery_interval
747
768
  @logger.debug "Will attempt connection recovery..."
769
+ notify_of_recovery_attempt_start
748
770
 
749
771
  self.initialize_transport
750
772
 
@@ -818,8 +840,9 @@ module Bunny
818
840
  end
819
841
  end
820
842
 
821
- def after_recovery_completed(&block)
822
- @recovery_completed = block
843
+ # @private
844
+ def notify_of_recovery_attempt_start
845
+ @recovery_attempt_started.call if @recovery_attempt_started
823
846
  end
824
847
 
825
848
  # @private
@@ -862,7 +885,7 @@ module Bunny
862
885
 
863
886
  clean_up_on_shutdown
864
887
  if threaded?
865
- @origin_thread.raise(@last_connection_error)
888
+ @session_error_handler.raise(@last_connection_error)
866
889
  else
867
890
  raise @last_connection_error
868
891
  end
@@ -1019,7 +1042,7 @@ module Bunny
1019
1042
 
1020
1043
  # @private
1021
1044
  def reader_loop
1022
- @reader_loop ||= ReaderLoop.new(@transport, self, Thread.current)
1045
+ @reader_loop ||= ReaderLoop.new(@transport, self, @session_error_handler)
1023
1046
  end
1024
1047
 
1025
1048
  # @private
@@ -1282,7 +1305,7 @@ module Bunny
1282
1305
  end
1283
1306
 
1284
1307
  if threaded?
1285
- @origin_thread.raise(e)
1308
+ @session_error_handler.raise(e)
1286
1309
  else
1287
1310
  raise e
1288
1311
  end
@@ -1328,7 +1351,7 @@ module Bunny
1328
1351
  @transport = Transport.new(self,
1329
1352
  host_from_address(address),
1330
1353
  port_from_address(address),
1331
- @opts.merge(:session_thread => @origin_thread)
1354
+ @opts.merge(:session_error_handler => @session_error_handler)
1332
1355
  )
1333
1356
 
1334
1357
  # Reset the cached progname for the logger only when no logger was provided
@@ -35,7 +35,7 @@ module Bunny
35
35
 
36
36
  def initialize(session, host, port, opts)
37
37
  @session = session
38
- @session_thread = opts[:session_thread]
38
+ @session_error_handler = opts[:session_error_handler]
39
39
  @host = host
40
40
  @port = port
41
41
  @opts = opts
@@ -146,7 +146,7 @@ module Bunny
146
146
  if @session.automatically_recover?
147
147
  @session.handle_network_failure(e)
148
148
  else
149
- @session_thread.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
149
+ @session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
150
150
  end
151
151
  end
152
152
  end
@@ -170,7 +170,7 @@ module Bunny
170
170
  if @session.automatically_recover?
171
171
  @session.handle_network_failure(e)
172
172
  else
173
- @session_thread.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
173
+ @session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
174
174
  end
175
175
  end
176
176
  end
@@ -188,7 +188,7 @@ module Bunny
188
188
  if @session.automatically_recover?
189
189
  @session.handle_network_failure(e)
190
190
  else
191
- @session_thread.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
191
+ @session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
192
192
  end
193
193
  end
194
194
  end
@@ -245,7 +245,7 @@ module Bunny
245
245
  if @session.automatically_recover?
246
246
  raise
247
247
  else
248
- @session_thread.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
248
+ @session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
249
249
  end
250
250
  end
251
251
  end
@@ -453,9 +453,9 @@ module Bunny
453
453
  end
454
454
  end
455
455
 
456
- def initialize_tls_context(ctx, opts={})
456
+ def initialize_tls_context(ctx, opts = {})
457
457
  ctx.cert = OpenSSL::X509::Certificate.new(@tls_certificate) if @tls_certificate
458
- ctx.key = OpenSSL::PKey::RSA.new(@tls_key) if @tls_key
458
+ ctx.key = OpenSSL::PKey.read(@tls_key) if @tls_key
459
459
  ctx.cert_store = if @tls_certificate_store
460
460
  @tls_certificate_store
461
461
  else
@@ -463,8 +463,9 @@ module Bunny
463
463
  @tls_ca_certificates = tls_ca_certificates_paths_from(opts)
464
464
  initialize_tls_certificate_store(@tls_ca_certificates)
465
465
  end
466
+ should_silence_warnings = opts.fetch(:tls_silence_warnings, false)
466
467
 
467
- if !@tls_certificate
468
+ if !@tls_certificate && !should_silence_warnings
468
469
  @logger.warn <<-MSG
469
470
  Using TLS but no client certificate is provided. If RabbitMQ is configured to require & verify peer
470
471
  certificate, connection will be rejected. Learn more at https://www.rabbitmq.com/ssl.html
@@ -482,14 +483,14 @@ certificate, connection will be rejected. Learn more at https://www.rabbitmq.com
482
483
  @logger.debug { "Will use peer verification mode #{verify_mode}" }
483
484
  ctx.verify_mode = verify_mode
484
485
 
485
- if !@verify_peer
486
+ if !@verify_peer && !should_silence_warnings
486
487
  @logger.warn <<-MSG
487
488
  Using TLS but peer hostname verification is disabled. This is convenient for local development
488
489
  but prone to man-in-the-middle attacks. Please set verify_peer: true in production. Learn more at https://www.rabbitmq.com/ssl.html
489
490
  MSG
490
491
  end
491
492
 
492
- ssl_version = opts[:tls_protocol] || opts[:ssl_version]
493
+ ssl_version = opts[:tls_protocol] || opts[:ssl_version] || :TLSv1_2
493
494
  ctx.ssl_version = ssl_version if ssl_version
494
495
 
495
496
  ctx
@@ -501,7 +502,7 @@ but prone to man-in-the-middle attacks. Please set verify_peer: true in producti
501
502
  certs.each do |cert|
502
503
  # if it starts with / or C:/ then it's a file path that may or may not
503
504
  # exist (e.g. a default OpenSSL path). MK.
504
- if File.readable?(cert) || cert =~ /^([a-z]:?)?\//i
505
+ if File.readable?(cert) || cert =~ /\A([a-z]:?)?\//i
505
506
  cert_files.push(cert)
506
507
  else
507
508
  cert_inlines.push(cert)
data/lib/bunny/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bunny
4
4
  # @return [String] Version of the library
5
- VERSION = "2.15.0"
5
+ VERSION = "2.19.0"
6
6
  end
@@ -62,8 +62,10 @@ describe Bunny::Queue, "#subscribe" do
62
62
  x.publish("hello", routing_key: queue_name)
63
63
  end
64
64
 
65
- sleep 1.0
66
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
65
+ sleep 1.5
66
+ 100.times do |i|
67
+ expect(delivery_tags).to include(i + 1)
68
+ end
67
69
 
68
70
  expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
69
71
 
@@ -95,7 +97,9 @@ describe Bunny::Queue, "#subscribe" do
95
97
  end
96
98
 
97
99
  sleep 1.5
98
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
100
+ 100.times do |i|
101
+ expect(delivery_tags).to include(i + 1)
102
+ end
99
103
 
100
104
  expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
101
105
 
@@ -305,8 +309,10 @@ describe Bunny::Queue, "#subscribe" do
305
309
  x.publish("hello", routing_key: queue_name)
306
310
  end
307
311
 
308
- sleep 1.0
309
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
312
+ sleep 1.5
313
+ 100.times do |i|
314
+ expect(delivery_tags).to include(i + 1)
315
+ end
310
316
 
311
317
  expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
312
318
 
@@ -338,7 +344,9 @@ describe Bunny::Queue, "#subscribe" do
338
344
  end
339
345
 
340
346
  sleep 1.5
341
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
347
+ 100.times do |i|
348
+ expect(delivery_tags).to include(i + 1)
349
+ end
342
350
 
343
351
  expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
344
352
 
@@ -560,4 +560,30 @@ describe Bunny::Session do
560
560
  described_class.new(logger: logger)
561
561
  end
562
562
  end
563
+
564
+ context "initialized with a custom connection name" do
565
+ it "uses provided connection name with default connection string" do
566
+ conn = Bunny.new(connection_name: 'test_name')
567
+
568
+ expect(conn.connection_name).to eq 'test_name'
569
+ end
570
+
571
+ it "uses provided connection name from client property hash" do
572
+ conn = Bunny.new(client_properties: {connection_name: 'cp/test_name'})
573
+
574
+ expect(conn.connection_name).to eq 'cp/test_name'
575
+ end
576
+
577
+ it "uses provided connection name with custom connection string" do
578
+ conn = Bunny.new('amqp://guest:guest@rabbitmq:5672', connection_name: 'test_name3')
579
+
580
+ expect(conn.connection_name).to eq 'test_name3'
581
+ end
582
+
583
+ it "uses provided connection name with hash options" do
584
+ conn = Bunny.new(user: 'user', password: 'p455w0rd', connection_name: 'test_name4')
585
+
586
+ expect(conn.connection_name).to eq 'test_name4'
587
+ end
588
+ end
563
589
  end
@@ -39,20 +39,6 @@ def local_hostname
39
39
  ENV.fetch("BUNNY_RABBITMQ_HOSTNAME", "localhost")
40
40
  end
41
41
 
42
- def no_tls12_supported?
43
- not tls12_supported?
44
- end
45
-
46
- def tls12_supported?
47
- begin
48
- ctx = OpenSSL::SSL::SSLContext.new
49
- ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
50
- true
51
- rescue
52
- false
53
- end
54
- end
55
-
56
42
  context "initialized with tls: true", skip: ENV["CI"] do
57
43
  let(:subject) do
58
44
  Bunny.new(
@@ -102,6 +88,7 @@ describe "TLS connection to RabbitMQ with client certificates", skip: ENV["CI"]
102
88
  password: "bunny_password",
103
89
  vhost: "bunny_testbed",
104
90
  tls: true,
91
+ tls_protocol: :TLSv1_2,
105
92
  tls_cert: "#{CERTIFICATE_DIR}/client_certificate.pem",
106
93
  tls_key: "#{CERTIFICATE_DIR}/client_key.pem",
107
94
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
@@ -126,6 +113,7 @@ describe "TLS connection to RabbitMQ without client certificates", skip: ENV["CI
126
113
  password: "bunny_password",
127
114
  vhost: "bunny_testbed",
128
115
  tls: true,
116
+ tls_protocol: :TLSv1_2,
129
117
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
130
118
  verify_peer: false)
131
119
  c.start
@@ -143,6 +131,7 @@ end
143
131
  describe "TLS connection to RabbitMQ with a connection string", skip: ENV["CI"] do
144
132
  let(:subject) do
145
133
  c = Bunny.new("amqps://bunny_gem:bunny_password@#{local_hostname()}/bunny_testbed",
134
+ tls_protocol: :TLSv1_2,
146
135
  tls_cert: "#{CERTIFICATE_DIR}/client_certificate.pem",
147
136
  tls_key: "#{CERTIFICATE_DIR}/client_key.pem",
148
137
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
@@ -179,6 +168,7 @@ describe "TLS connection to RabbitMQ with a connection string and w/o client cer
179
168
  let(:subject) do
180
169
  c = Bunny.new("amqps://bunny_gem:bunny_password@#{local_hostname()}/bunny_testbed",
181
170
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
171
+ tls_protocol: :TLSv1_2,
182
172
  verify_peer: verify_peer)
183
173
  c.start
184
174
  c
@@ -211,19 +201,13 @@ describe "TLS connection to RabbitMQ with a connection string and w/o client cer
211
201
  end
212
202
  end
213
203
 
214
-
215
- describe "TLS connection to RabbitMQ with client certificates provided inline", skip: ENV["CI"] do
204
+ describe "TLS connection to RabbitMQ w/o client certificate", skip: ENV["CI"] do
216
205
  let(:subject) do
217
- c = Bunny.new(
218
- hostname: local_hostname(),
219
- username: "bunny_gem",
220
- password: "bunny_password",
221
- vhost: "bunny_testbed",
222
- tls: true,
223
- tls_cert: File.read("#{CERTIFICATE_DIR}/client_certificate.pem"),
224
- tls_key: File.read("#{CERTIFICATE_DIR}/client_key.pem"),
206
+ c = Bunny.new("amqps://bunny_gem:bunny_password@#{local_hostname()}/bunny_testbed",
225
207
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
226
- verify_peer: false)
208
+ tls_protocol: :TLSv1_2,
209
+ verify_peer: false,
210
+ tls_silence_warnings: should_silence_warnings)
227
211
  c.start
228
212
  c
229
213
  end
@@ -232,10 +216,21 @@ describe "TLS connection to RabbitMQ with client certificates provided inline",
232
216
  subject.close
233
217
  end
234
218
 
235
- include_examples "successful TLS connection"
219
+ context "TLS-related warnings are enabled" do
220
+ let(:should_silence_warnings) { false }
221
+
222
+ include_examples "successful TLS connection"
223
+ end
224
+
225
+ context "TLS-related warnings are silenced" do
226
+ let(:should_silence_warnings) { true }
227
+
228
+ include_examples "successful TLS connection"
229
+ end
236
230
  end
237
231
 
238
- describe "TLS connection to RabbitMQ with tls_version TLSv1.2 specified", skip: ENV["CI"] do
232
+
233
+ describe "TLS connection to RabbitMQ with client certificates provided inline", skip: ENV["CI"] do
239
234
  let(:subject) do
240
235
  c = Bunny.new(
241
236
  hostname: local_hostname(),
@@ -243,8 +238,10 @@ describe "TLS connection to RabbitMQ with tls_version TLSv1.2 specified", skip:
243
238
  password: "bunny_password",
244
239
  vhost: "bunny_testbed",
245
240
  tls: true,
246
- tls_protocol: :TLSv1_2,
241
+ tls_cert: File.read("#{CERTIFICATE_DIR}/client_certificate.pem"),
242
+ tls_key: File.read("#{CERTIFICATE_DIR}/client_key.pem"),
247
243
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
244
+ tls_protocol: :TLSv1_2,
248
245
  verify_peer: false)
249
246
  c.start
250
247
  c
@@ -255,8 +252,4 @@ describe "TLS connection to RabbitMQ with tls_version TLSv1.2 specified", skip:
255
252
  end
256
253
 
257
254
  include_examples "successful TLS connection"
258
-
259
- it "connects using TLSv1.2", skip: no_tls12_supported? do
260
- expect(subject.transport.socket.ssl_version).to eq "TLSv1.2"
261
- end
262
255
  end