bunny 2.15.0 → 2.19.0
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.
- checksums.yaml +4 -4
- data/README.md +30 -12
- data/lib/bunny/channel.rb +2 -2
- data/lib/bunny/reader_loop.rb +11 -11
- data/lib/bunny/session.rb +32 -9
- data/lib/bunny/transport.rb +12 -11
- data/lib/bunny/version.rb +1 -1
- data/spec/higher_level_api/integration/basic_consume_spec.rb +14 -6
- data/spec/higher_level_api/integration/connection_spec.rb +26 -0
- data/spec/higher_level_api/integration/tls_connection_spec.rb +25 -32
- data/spec/issues/issue609_spec.rb +84 -0
- data/spec/lower_level_api/integration/basic_cancel_spec.rb +1 -1
- data/spec/lower_level_api/integration/basic_consume_spec.rb +8 -8
- metadata +28 -87
- data/.github/ISSUE_TEMPLATE.md +0 -18
- data/.gitignore +0 -28
- data/.rspec +0 -1
- data/.travis.yml +0 -33
- data/.yardopts +0 -8
- data/CONTRIBUTING.md +0 -132
- data/ChangeLog.md +0 -2084
- data/Gemfile +0 -55
- data/LICENSE +0 -21
- data/Rakefile +0 -54
- data/benchmarks/basic_publish/with_128K_messages.rb +0 -35
- data/benchmarks/basic_publish/with_1k_messages.rb +0 -35
- data/benchmarks/basic_publish/with_4K_messages.rb +0 -35
- data/benchmarks/basic_publish/with_64K_messages.rb +0 -35
- data/benchmarks/channel_open.rb +0 -28
- data/benchmarks/mutex_and_monitor.rb +0 -42
- data/benchmarks/queue_declare.rb +0 -29
- data/benchmarks/queue_declare_and_bind.rb +0 -29
- data/benchmarks/queue_declare_bind_and_delete.rb +0 -29
- data/benchmarks/synchronized_sorted_set.rb +0 -53
- data/benchmarks/write_vs_write_nonblock.rb +0 -49
- data/bunny.gemspec +0 -34
- data/docker/Dockerfile +0 -24
- data/docker/apt/preferences.d/erlang +0 -3
- data/docker/apt/sources.list.d/bintray.rabbitmq.list +0 -2
- data/docker/docker-entrypoint.sh +0 -26
- data/docker/rabbitmq.conf +0 -29
- data/docker-compose.yml +0 -28
- data/examples/connection/authentication_failure.rb +0 -16
- data/examples/connection/automatic_recovery_with_basic_get.rb +0 -40
- data/examples/connection/automatic_recovery_with_client_named_queues.rb +0 -36
- data/examples/connection/automatic_recovery_with_multiple_consumers.rb +0 -46
- data/examples/connection/automatic_recovery_with_republishing.rb +0 -109
- data/examples/connection/automatic_recovery_with_server_named_queues.rb +0 -35
- data/examples/connection/channel_level_exception.rb +0 -27
- data/examples/connection/disabled_automatic_recovery.rb +0 -34
- data/examples/connection/heartbeat.rb +0 -17
- data/examples/connection/manually_reconnecting_consumer.rb +0 -23
- data/examples/connection/manually_reconnecting_publisher.rb +0 -28
- data/examples/connection/unknown_host.rb +0 -16
- data/examples/consumers/high_and_low_priority.rb +0 -50
- data/examples/guides/exchanges/direct_exchange_routing.rb +0 -36
- data/examples/guides/exchanges/fanout_exchange_routing.rb +0 -28
- data/examples/guides/exchanges/headers_exchange_routing.rb +0 -31
- data/examples/guides/exchanges/mandatory_messages.rb +0 -30
- data/examples/guides/extensions/alternate_exchange.rb +0 -30
- data/examples/guides/extensions/basic_nack.rb +0 -33
- data/examples/guides/extensions/connection_blocked.rb +0 -35
- data/examples/guides/extensions/consumer_cancellation_notification.rb +0 -39
- data/examples/guides/extensions/dead_letter_exchange.rb +0 -32
- data/examples/guides/extensions/exchange_to_exchange_bindings.rb +0 -29
- data/examples/guides/extensions/per_message_ttl.rb +0 -36
- data/examples/guides/extensions/per_queue_message_ttl.rb +0 -36
- data/examples/guides/extensions/publisher_confirms.rb +0 -28
- data/examples/guides/extensions/queue_lease.rb +0 -26
- data/examples/guides/extensions/sender_selected_distribution.rb +0 -32
- data/examples/guides/getting_started/blabbr.rb +0 -27
- data/examples/guides/getting_started/hello_world.rb +0 -22
- data/examples/guides/getting_started/weathr.rb +0 -49
- data/examples/guides/queues/one_off_consumer.rb +0 -25
- data/examples/guides/queues/redeliveries.rb +0 -81
- data/profiling/basic_publish/with_4K_messages.rb +0 -33
- data/repl +0 -3
- data/spec/tls/ca_certificate.pem +0 -29
- data/spec/tls/ca_key.pem +0 -52
- data/spec/tls/client_certificate.pem +0 -29
- data/spec/tls/client_key.pem +0 -51
- data/spec/tls/generate-server-cert.sh +0 -8
- data/spec/tls/server-openssl.cnf +0 -10
- data/spec/tls/server.csr +0 -16
- data/spec/tls/server_certificate.pem +0 -29
- data/spec/tls/server_key.pem +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6de535f1d386dbf46fd89a733c1c44915280af55c3cc3cc56467abe0ead9c24
|
4
|
+
data.tar.gz: 6048aea84078fb8995718ed774d9a3956dc91645b24c09382cd54283b444aabe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
75
|
-
* [2.
|
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.
|
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
|
-
#
|
128
|
-
|
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 "
|
137
|
+
puts "Done"
|
131
138
|
|
139
|
+
ch.close
|
132
140
|
# close the connection
|
133
|
-
conn.
|
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
|
-
|
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
|
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 +
|
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
|
|
data/lib/bunny/reader_loop.rb
CHANGED
@@ -9,17 +9,17 @@ module Bunny
|
|
9
9
|
# @private
|
10
10
|
class ReaderLoop
|
11
11
|
|
12
|
-
def initialize(transport, session,
|
13
|
-
@transport
|
14
|
-
@session
|
15
|
-
@
|
16
|
-
@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
|
18
|
+
@mutex = Mutex.new
|
19
19
|
|
20
|
-
@stopping
|
21
|
-
@stopped
|
22
|
-
@network_is_down
|
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
|
-
@
|
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
|
-
@
|
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]
|
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
|
-
@
|
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
|
-
|
822
|
-
|
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
|
-
@
|
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,
|
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
|
-
@
|
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(:
|
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
|
data/lib/bunny/transport.rb
CHANGED
@@ -35,7 +35,7 @@ module Bunny
|
|
35
35
|
|
36
36
|
def initialize(session, host, port, opts)
|
37
37
|
@session = session
|
38
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
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 =~
|
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
@@ -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.
|
66
|
-
|
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
|
-
|
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.
|
309
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|