beetle 2.3.2 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 807f79dd4cc32720d7d4c4b1b642419296175f9382379dedb1291e03a89b3989
4
- data.tar.gz: ac8fe19b561ff2717e2be0be1a0c391e76b115608dffb856fa4d619d6466c45a
3
+ metadata.gz: 299657b394d85d53b70417554db9a3ca53de5339dc0fc777e1555536237ccf1b
4
+ data.tar.gz: a4fda19185d645fbb26e563b7b7c72ffe67d03ef3cc621a581b7b1cee38b3178
5
5
  SHA512:
6
- metadata.gz: 9b68750fe9385741dc7ae98cbbe65e8e5f48c1e628c0be596c6db2210e98976a8f2158875a80716b4987150cac08da2b937480e4bd7925be743192993a95a822
7
- data.tar.gz: 2c0ee5d09050b3ea4ad319bcae89f4e5684d7318ba3f871ad33691ae6f86ec2d2a84b4dcb55b1daed3589702c7fb40e8b63559b807b3f5408d2c6a714721a141
6
+ metadata.gz: 3b6c98dd094e445db0424aab1c992eb9245df6fb4e402c45d087c8ca395c9bfd2f3ec57d95999a79ce5f4853d1c02e139a829b962f6cef896c73004a299743ad
7
+ data.tar.gz: 1324bd1753c97574cf0dd657f7096be41e26d76f271525c124aa198286056cbd8673bf5ff0894bc761b94351cdd14d1dbd3504e3925fcc6e11804f6ae99b19dd
data/README.rdoc CHANGED
@@ -96,6 +96,7 @@ For development, you'll need
96
96
  * {mocha}[http://github.com/floehopper/mocha]
97
97
  * {cucumber}[http://github.com/aslakhellesoy/cucumber]
98
98
  * {daemon_controller}[http://github.com/FooBarWidget/daemon_controller]
99
+ * {consul}[https://www.consul.io/downloads.html]
99
100
 
100
101
  For tests, you'll need
101
102
  * {activerecord}[https://github.com/rails/rails/tree/master/activerecord]
@@ -120,9 +121,11 @@ distribution.
120
121
 
121
122
  1. Fork it
122
123
  2. Create your feature branch (`git checkout -b my-new-feature`)
123
- 3. Commit your changes (`git commit -am 'Add some feature'`)
124
- 4. Push to the branch (`git push origin my-new-feature`)
125
- 5. Create new Pull Request
124
+ 3. Hack along and test your code using rake test and rake
125
+ cucumber. You must start consul in order to use cucumber.
126
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
127
+ 5. Push to the branch (`git push origin my-new-feature`)
128
+ 6. Create new Pull Request
126
129
 
127
130
  Don't increase the gem version in your pull requests. It will be done after merging the request,
128
131
  to allow merging of pull requests in a flexible order.
data/RELEASE_NOTES.rdoc CHANGED
@@ -1,5 +1,13 @@
1
1
  = Release Notes
2
2
 
3
+
4
+ == Version 3.0.0.rc1
5
+ * provide client method to setup queues and queue policies.
6
+ Setting up queue policies on demand in publisher and subscriber is OK
7
+ for a small number of queues, publishers and subscribers. But the HTTP
8
+ API of RabbitMQ doesn't scale all that well, so that a large number
9
+ of HTPP calls to set up queue policies can in fact crash a server.
10
+
3
11
  == Version 2.3.2
4
12
  * config server: fixed a race condition when accessing server state.
5
13
  HTTP requests run in threads separate from the server dispatcher
data/Rakefile CHANGED
@@ -82,6 +82,13 @@ namespace :redis do
82
82
  end
83
83
  end
84
84
 
85
+ namespace :consul do
86
+ desc "start consul agent in development mode"
87
+ task :start do
88
+ system "consul agent -dev -node machine"
89
+ end
90
+ end
91
+
85
92
  Cucumber::Rake::Task.new(:cucumber) do |t|
86
93
  t.cucumber_opts = "features --format progress"
87
94
  end
@@ -5,6 +5,7 @@ Feature: Redis auto failover
5
5
  Background:
6
6
  Given a redis server "redis-1" exists as master
7
7
  And a redis server "redis-2" exists as slave of "redis-1"
8
+ And consul state has been cleared
8
9
 
9
10
  Scenario: Successful redis master switch
10
11
  Given a redis configuration server using redis servers "redis-1,redis-2" with clients "rc-client-1,rc-client-2" exists
@@ -1,3 +1,10 @@
1
+ Given /^consul state has been cleared$/ do
2
+ system "killall beetle beetle_handler >/dev/null 2>/dev/null"
3
+ system "curl --silent --request PUT http://localhost:8500/v1/kv/apps/beetle/config/ >/dev/null"
4
+ system "curl --silent --request PUT http://localhost:8500/v1/kv/shared/config/ >/dev/null"
5
+ system "curl --silent --request DELETE http://localhost:8500/v1/kv/apps/beetle/state/redis_master_file_content >/dev/null"
6
+ end
7
+
1
8
  Given /^a redis server "([^\"]*)" exists as master$/ do |redis_name|
2
9
  TestDaemons::Redis[redis_name].restart
3
10
  TestDaemons::Redis[redis_name].master
@@ -27,7 +27,7 @@ module TestDaemons
27
27
  clients_parameter_string = @@redis_configuration_clients.blank? ? "" : "--client-ids #{@@redis_configuration_clients}"
28
28
  DaemonController.new(
29
29
  :identifier => "Redis configuration test server",
30
- :start_command => "./beetle configuration_server -v -d --redis-master-file #{redis_master_file} --redis-servers '#{@@redis_servers}' #{clients_parameter_string} --redis-master-retry-interval 1 --pid-file #{pid_file} --log-file #{log_file} --redis-failover-confidence-level #{@@confidence_level}",
30
+ :start_command => "./beetle configuration_server -v -d --redis-master-file #{redis_master_file} --redis-servers '#{@@redis_servers}' #{clients_parameter_string} --redis-master-retry-interval 1 --pid-file #{pid_file} --log-file #{log_file} --redis-failover-confidence-level #{@@confidence_level} --consul http://localhost:8500",
31
31
  :ping_command => lambda{ answers_text_requests? },
32
32
  :pid_file => pid_file,
33
33
  :log_file => log_file,
data/lib/beetle/base.rb CHANGED
@@ -12,7 +12,7 @@ module Beetle
12
12
  @server = @servers[rand @servers.size]
13
13
  @exchanges = {}
14
14
  @queues = {}
15
- @dead_lettering = DeadLettering.new(@client.config)
15
+ @dead_lettering = DeadLettering.new(@client)
16
16
  end
17
17
 
18
18
  private
@@ -54,7 +54,13 @@ module Beetle
54
54
  @queues[@server] ||= {}
55
55
  end
56
56
 
57
- def queue(name)
57
+ QueueInfo = Struct.new(:queue, :create_policies)
58
+
59
+ def queue(name, create_policies: false)
60
+ info = queues[name]
61
+ if info && create_policies && !info.create_policies
62
+ queues.delete(name)
63
+ end
58
64
  queues[name] ||=
59
65
  begin
60
66
  opts = @client.queues[name]
@@ -66,10 +72,11 @@ module Beetle
66
72
  @client.bindings[name].each do |binding_options|
67
73
  exchange_name = binding_options[:exchange]
68
74
  binding_options = binding_options.slice(*QUEUE_BINDING_KEYS)
69
- the_queue = bind_queue!(queue_name, creation_options, exchange_name, binding_options)
75
+ the_queue = bind_queue!(queue_name, creation_options, exchange_name, binding_options, create_policies: create_policies)
70
76
  end
71
- the_queue
77
+ info = QueueInfo.new(the_queue, create_policies)
72
78
  end
79
+ info.queue
73
80
  end
74
81
 
75
82
  end
data/lib/beetle/client.rb CHANGED
@@ -73,12 +73,19 @@ module Beetle
73
73
  # the name of the exchange this queue will be bound to (defaults to the name of the queue)
74
74
  # [<tt>:key</tt>]
75
75
  # the binding key (defaults to the name of the queue)
76
+ # [<tt>:lazy</tt>]
77
+ # whether the queue should use lazy mode (defaults to <tt>config.lazy_queues_enabled</tt>)
78
+ # [<tt>:dead_lettering</tt>]
79
+ # whether the queue should use dead lettering (defaults to <tt>config.dead_lettering_enabled</tt>)
76
80
  # automatically registers the specified exchange if it hasn't been registered yet
77
81
 
78
82
  def register_queue(name, options={})
79
83
  name = name.to_s
80
84
  raise ConfigurationError.new("queue #{name} already configured") if queues.include?(name)
81
- opts = {:exchange => name, :key => name, :auto_delete => false, :amqp_name => name}.merge!(options.symbolize_keys)
85
+ opts = {
86
+ :exchange => name, :key => name, :auto_delete => false, :amqp_name => name,
87
+ :lazy => config.lazy_queues_enabled, :dead_lettering => config.dead_lettering_enabled
88
+ }.merge!(options.symbolize_keys)
82
89
  opts.merge! :durable => true, :passive => false, :exclusive => false
83
90
  exchange = opts.delete(:exchange).to_s
84
91
  key = opts.delete(:key)
@@ -202,6 +209,11 @@ module Beetle
202
209
  publisher.purge(queues)
203
210
  end
204
211
 
212
+ # declares all queues, binds them and creates/updates all policies
213
+ def setup_queues_and_policies(queues)
214
+ publisher.setup_queues_and_policies(queues)
215
+ end
216
+
205
217
  # start listening to all registered queues. Calls #listen_queues internally
206
218
  # runs the given block before entering the eventmachine loop.
207
219
  def listen(_deprecated_messages=nil, &block)
@@ -5,29 +5,34 @@ module Beetle
5
5
  class DeadLettering
6
6
  class FailedRabbitRequest < StandardError; end
7
7
 
8
- def initialize(config)
9
- @config = config
8
+ attr_reader :client, :config
9
+
10
+ def initialize(client)
11
+ @client = client
12
+ @config = client.config
10
13
  end
11
14
 
12
15
  def bind_dead_letter_queues!(channel, servers, target_queue, creation_keys = {})
13
- if @config.dead_lettering_enabled?
16
+ policy_options = client.queues[target_queue].slice(:dead_lettering, :lazy)
17
+ if policy_options[:dead_lettering]
14
18
  dead_letter_queue_name = dead_letter_queue_name(target_queue)
15
- logger.debug("Beetle: creating dead letter queue #{dead_letter_queue_name} with opts: #{creation_keys.inspect}")
19
+ logger.info("Beetle: creating dead letter queue #{dead_letter_queue_name} with opts: #{creation_keys.inspect}")
16
20
  channel.queue(dead_letter_queue_name, creation_keys)
17
21
  end
18
22
 
19
- if @config.dead_lettering_enabled?
20
- logger.debug("Beetle: setting #{dead_letter_queue_name} as dead letter queue of #{target_queue} on all servers")
23
+ if policy_options[:dead_lettering]
24
+ logger.info("Beetle: setting #{dead_letter_queue_name} as dead letter queue of #{target_queue} on all servers")
21
25
  end
22
- set_queue_policies!(servers, target_queue)
26
+ set_queue_policies!(servers, target_queue, policy_options)
23
27
 
24
- if @config.dead_lettering_enabled?
25
- logger.debug("Beetle: setting #{target_queue} as dead letter queue of #{dead_letter_queue_name} on all servers")
28
+ if policy_options[:dead_lettering]
29
+ logger.info("Beetle: setting #{target_queue} as dead letter queue of #{dead_letter_queue_name} on all servers")
26
30
  set_queue_policies!(
27
31
  servers,
28
32
  dead_letter_queue_name,
29
- :message_ttl => @config.dead_lettering_msg_ttl,
30
- :routing_key => target_queue
33
+ { :message_ttl => config.dead_lettering_msg_ttl,
34
+ :routing_key => target_queue
35
+ }.merge(policy_options)
31
36
  )
32
37
  end
33
38
  end
@@ -40,21 +45,21 @@ module Beetle
40
45
  raise ArgumentError.new("server missing") if server.blank?
41
46
  raise ArgumentError.new("queue name missing") if queue_name.blank?
42
47
 
43
- return unless @config.dead_lettering_enabled? || @config.lazy_queues_enabled?
48
+ return unless options[:dead_lettering] || options[:lazy]
44
49
 
45
- vhost = CGI.escape(@config.vhost)
50
+ vhost = CGI.escape(config.vhost)
46
51
  request_url = URI("http://#{server}/api/policies/#{vhost}/#{queue_name}_policy")
47
52
  request = Net::HTTP::Put.new(request_url)
48
53
 
49
54
  # set up queue policy
50
55
  definition = {}
51
- if @config.dead_lettering_enabled?
56
+ if options[:dead_lettering]
52
57
  definition["dead-letter-routing-key"] = dead_letter_routing_key(queue_name, options)
53
58
  definition["dead-letter-exchange"] = ""
54
59
  definition["message-ttl"] = options[:message_ttl] if options[:message_ttl]
55
60
  end
56
61
 
57
- definition["queue-mode"] = "lazy" if @config.lazy_queues_enabled?
62
+ definition["queue-mode"] = "lazy" if options[:lazy]
58
63
 
59
64
  request_body = {
60
65
  "pattern" => "^#{queue_name}$",
@@ -84,9 +89,9 @@ module Beetle
84
89
  end
85
90
 
86
91
  def run_rabbit_http_request(uri, request, &block)
87
- request.basic_auth(@config.user, @config.password)
92
+ request.basic_auth(config.user, config.password)
88
93
  request["Content-Type"] = "application/json"
89
- Net::HTTP.start(uri.hostname, @config.api_port, :read_timeout => @config.dead_lettering_read_timeout) do |http|
94
+ Net::HTTP.start(uri.hostname, config.api_port, :read_timeout => config.dead_lettering_read_timeout) do |http|
90
95
  block.call(http) if block_given?
91
96
  end
92
97
  end
@@ -98,7 +103,7 @@ module Beetle
98
103
  end
99
104
 
100
105
  def logger
101
- @config.logger
106
+ config.logger
102
107
  end
103
108
  end
104
109
  end
@@ -154,7 +154,7 @@ module Beetle
154
154
  system_name = @config.system_name
155
155
  redis_master = ""
156
156
  text.each_line do |line|
157
- parts = line.split('/')
157
+ parts = line.split('/', 2)
158
158
  case parts.size
159
159
  when 1
160
160
  redis_master = parts[0]
@@ -143,6 +143,14 @@ module Beetle
143
143
  end
144
144
  end
145
145
 
146
+ def setup_queues_and_policies(queue_names) #:nodoc:
147
+ each_server do
148
+ queue_names.each do |name|
149
+ queue(name, create_policies: true)
150
+ end
151
+ end
152
+ end
153
+
146
154
  def stop #:nodoc:
147
155
  each_server { stop! }
148
156
  end
@@ -214,10 +222,12 @@ module Beetle
214
222
  end
215
223
 
216
224
  # TODO: Refactor, fetch the keys and stuff itself
217
- def bind_queue!(queue_name, creation_keys, exchange_name, binding_keys)
225
+ def bind_queue!(queue_name, creation_keys, exchange_name, binding_keys, create_policies: false)
218
226
  logger.debug("Beetle: creating queue with opts: #{creation_keys.inspect}")
219
227
  queue = bunny.queue(queue_name, creation_keys)
220
- @dead_lettering.bind_dead_letter_queues!(bunny, @client.servers, queue_name, creation_keys)
228
+ if create_policies
229
+ @dead_lettering.bind_dead_letter_queues!(bunny, @client.servers, queue_name, creation_keys)
230
+ end
221
231
  logger.debug("Beetle: binding queue #{queue_name} to #{exchange_name} with opts: #{binding_keys.inspect}")
222
232
  queue.bind(exchange(exchange_name), binding_keys)
223
233
  queue
@@ -144,19 +144,19 @@ module Beetle
144
144
  callback = create_subscription_callback(queue_name, amqp_queue_name, handler, opts)
145
145
  keys = opts.slice(*SUBSCRIPTION_KEYS).merge(:key => "#", :ack => true)
146
146
  logger.debug "Beetle: subscribing to queue #{amqp_queue_name} with key # on server #{@server}"
147
- queues[queue_name].subscribe(keys, &callback)
147
+ queues[queue_name].queue.subscribe(keys, &callback)
148
148
  subscriptions[queue_name] = [keys, callback]
149
149
  end
150
150
 
151
151
  def pause(queue_name)
152
- return unless queues[queue_name].subscribed?
153
- queues[queue_name].unsubscribe
152
+ return unless queues[queue_name].queue.subscribed?
153
+ queues[queue_name].queue.unsubscribe
154
154
  end
155
155
 
156
156
  def resume(queue_name)
157
- return if queues[queue_name].subscribed?
157
+ return if queues[queue_name].queue.subscribed?
158
158
  keys, callback = subscriptions[queue_name]
159
- queues[queue_name].subscribe(keys, &callback)
159
+ queues[queue_name].queue.subscribe(keys, &callback)
160
160
  end
161
161
 
162
162
  def create_subscription_callback(queue_name, amqp_queue_name, handler, opts)
@@ -204,10 +204,12 @@ module Beetle
204
204
  channel.__send__(opts[:type], name, opts.slice(*EXCHANGE_CREATION_KEYS))
205
205
  end
206
206
 
207
- def bind_queue!(queue_name, creation_keys, exchange_name, binding_keys)
207
+ def bind_queue!(queue_name, creation_keys, exchange_name, binding_keys, create_policies: false)
208
208
  queue = channel.queue(queue_name, creation_keys)
209
209
  target_servers = @client.servers + @client.additional_subscription_servers
210
- @dead_lettering.bind_dead_letter_queues!(channel, target_servers, queue_name, creation_keys)
210
+ if create_policies
211
+ @dead_lettering.bind_dead_letter_queues!(channel, target_servers, queue_name, creation_keys)
212
+ end
211
213
  exchange = exchange(exchange_name)
212
214
  queue.bind(exchange, binding_keys)
213
215
  queue
@@ -1,3 +1,3 @@
1
1
  module Beetle
2
- VERSION = "2.3.2"
2
+ VERSION = "3.0.0.rc1"
3
3
  end
@@ -79,7 +79,7 @@ module Beetle
79
79
 
80
80
  test "registering a queue should store it in the configuration with symbolized option keys and force durable=true and passive=false and set the amqp queue name" do
81
81
  @client.register_queue("some_queue", "durable" => false, "exchange" => "some_exchange")
82
- assert_equal({:durable => true, :passive => false, :auto_delete => false, :exclusive => false, :amqp_name => "some_queue"}, @client.queues["some_queue"])
82
+ assert_equal({:durable => true, :passive => false, :lazy=>false, :dead_lettering=>false, :auto_delete => false, :exclusive => false, :amqp_name => "some_queue"}, @client.queues["some_queue"])
83
83
  end
84
84
 
85
85
  test "registering a queue should add the queue to the list of queues of the queue's exchange" do
@@ -308,6 +308,13 @@ module Beetle
308
308
  assert_equal "ha!", client.purge(:queue1, :queue2)
309
309
  end
310
310
 
311
+ test "should delegate queue setup to the publisher instance" do
312
+ client = Client.new
313
+ client.register_queue(:queue)
314
+ client.send(:publisher).expects(:setup_queues_and_policies).with(["queue"]).returns("ha!")
315
+ assert_equal "ha!", client.setup_queues_and_policies(["queue"])
316
+ end
317
+
311
318
  test "should delegate rpc calls to the publisher instance" do
312
319
  client = Client.new
313
320
  client.register_message("deadletter")
@@ -4,7 +4,8 @@ module Beetle
4
4
  class SetDeadLetteringsTest < Minitest::Test
5
5
  def setup
6
6
  @config = Configuration.new
7
- @dead_lettering = DeadLettering.new(@config)
7
+ @client = Client.new @config
8
+ @dead_lettering = DeadLettering.new(@client)
8
9
  @config.dead_lettering_enabled = true
9
10
  end
10
11
 
@@ -25,9 +26,9 @@ module Beetle
25
26
  @server = "localhost:15672"
26
27
  @queue_name = "QUEUE_NAME"
27
28
  @config = Configuration.new
29
+ @client = Client.new @config
28
30
  @config.logger = Logger.new("/dev/null")
29
- @dead_lettering = DeadLettering.new(@config)
30
- @config.dead_lettering_enabled = true
31
+ @dead_lettering = DeadLettering.new(@client)
31
32
  end
32
33
 
33
34
  test "raises exception when queue name wasn't specified" do
@@ -55,12 +56,10 @@ module Beetle
55
56
  }}.to_json)
56
57
  .to_return(:status => 204)
57
58
 
58
- @dead_lettering.set_queue_policy!(@server, @queue_name)
59
+ @dead_lettering.set_queue_policy!(@server, @queue_name, :lazy => false, :dead_lettering => true)
59
60
  end
60
61
 
61
62
  test "creates a policy by posting to the rabbitmq if lazy queues are enabled" do
62
- @config.lazy_queues_enabled = true
63
- @config.dead_lettering_enabled = false
64
63
  stub_request(:put, "http://localhost:15672/api/policies/%2F/QUEUE_NAME_policy")
65
64
  .with(basic_auth: ['guest', 'guest'])
66
65
  .with(:body => {
@@ -72,7 +71,7 @@ module Beetle
72
71
  }}.to_json)
73
72
  .to_return(:status => 204)
74
73
 
75
- @dead_lettering.set_queue_policy!(@server, @queue_name)
74
+ @dead_lettering.set_queue_policy!(@server, @queue_name, :lazy => true, :dead_lettering => false)
76
75
  end
77
76
 
78
77
  test "raises exception when policy couldn't successfully be created" do
@@ -81,7 +80,7 @@ module Beetle
81
80
  .to_return(:status => [405])
82
81
 
83
82
  assert_raises DeadLettering::FailedRabbitRequest do
84
- @dead_lettering.set_queue_policy!(@server, @queue_name)
83
+ @dead_lettering.set_queue_policy!(@server, @queue_name, :lazy => true, :dead_lettering => true)
85
84
  end
86
85
  end
87
86
 
@@ -99,7 +98,7 @@ module Beetle
99
98
  }}.to_json)
100
99
  .to_return(:status => 204)
101
100
 
102
- @dead_lettering.set_queue_policy!(@server, @queue_name, :message_ttl => 10000)
101
+ @dead_lettering.set_queue_policy!(@server, @queue_name, :dead_lettering => true, :message_ttl => 10000)
103
102
  end
104
103
 
105
104
  test "properly encodes the vhost from the configuration" do
@@ -117,7 +116,7 @@ module Beetle
117
116
 
118
117
  @config.vhost = "foo/"
119
118
 
120
- @dead_lettering.set_queue_policy!(@server, @queue_name)
119
+ @dead_lettering.set_queue_policy!(@server, @queue_name, :dead_lettering => true)
121
120
  end
122
121
  end
123
122
 
@@ -125,28 +124,31 @@ module Beetle
125
124
  def setup
126
125
  @queue_name = "QUEUE_NAME"
127
126
  @config = Configuration.new
127
+ @client = Client.new @config
128
128
  @config.logger = Logger.new("/dev/null")
129
- @dead_lettering = DeadLettering.new(@config)
129
+ @dead_lettering = DeadLettering.new(@client)
130
130
  @servers = ["localhost:55672"]
131
131
  end
132
132
 
133
133
  test "is does not call out to rabbit if neither dead lettering nor lazy queues are enabled" do
134
- @config.dead_lettering_enabled = false
134
+ @client.register_queue(@queue_name, :dead_lettering => false, :lazy => false)
135
135
  channel = stub('channel')
136
136
  @dead_lettering.expects(:run_rabbit_http_request).never
137
137
  @dead_lettering.bind_dead_letter_queues!(channel, @servers, @queue_name)
138
138
  end
139
139
 
140
140
  test "creates and connects the dead letter queue via policies when enabled" do
141
- @config.dead_lettering_enabled = true
141
+ @client.register_queue(@queue_name, :dead_lettering => true, :lazy => false)
142
142
 
143
143
  channel = stub('channel')
144
144
 
145
145
  channel.expects(:queue).with("#{@queue_name}_dead_letter", {})
146
- @dead_lettering.expects(:set_queue_policies!).with(@servers, @queue_name)
146
+ @dead_lettering.expects(:set_queue_policies!).with(@servers, @queue_name, :dead_lettering => true, :lazy => false)
147
147
  @dead_lettering.expects(:set_queue_policies!).with(@servers, "#{@queue_name}_dead_letter",
148
148
  :routing_key => @queue_name,
149
- :message_ttl => 1000
149
+ :message_ttl => 1000,
150
+ :dead_lettering => true,
151
+ :lazy => false
150
152
  )
151
153
 
152
154
  @dead_lettering.bind_dead_letter_queues!(channel, @servers, @queue_name)
@@ -273,6 +273,19 @@ module Beetle
273
273
  end
274
274
 
275
275
  test "binding a queue should create it using the config and bind it to the exchange with the name specified" do
276
+ @client.register_queue("some_queue", :exchange => "some_exchange", :key => "haha.#", :arguments => {"foo" => "fighter"})
277
+ @pub.expects(:exchange).with("some_exchange").returns(:the_exchange)
278
+ q = mock("queue")
279
+ q.expects(:bind).with(:the_exchange, {:key => "haha.#"})
280
+ m = mock("Bunny")
281
+ m.expects(:queue).with("some_queue", :durable => true, :passive => false, :auto_delete => false, :exclusive => false, :arguments => {"foo" => "fighter"}).returns(q)
282
+ @pub.expects(:bunny).returns(m)
283
+
284
+ @pub.send(:queue, "some_queue")
285
+ assert_equal Base::QueueInfo.new(q, false), @pub.send(:queues)["some_queue"]
286
+ end
287
+
288
+ test "binding a queue should create it using the config and bind it to the exchange with the name specified and setup policies if requested" do
276
289
  @client.register_queue("some_queue", :exchange => "some_exchange", :key => "haha.#", :arguments => {"foo" => "fighter"})
277
290
  @pub.expects(:exchange).with("some_exchange").returns(:the_exchange)
278
291
  q = mock("queue")
@@ -281,8 +294,29 @@ module Beetle
281
294
  m.expects(:queue).with("some_queue", :durable => true, :passive => false, :auto_delete => false, :exclusive => false, :arguments => {"foo" => "fighter"}).returns(q)
282
295
  @pub.expects(:bunny).returns(m).twice
283
296
 
297
+ @pub.send(:queue, "some_queue", create_policies: true)
298
+ assert_equal Base::QueueInfo.new(q, true), @pub.send(:queues)["some_queue"]
299
+ end
300
+
301
+ test "binding a queue with create_plocies: true after having already declared it with create_plocies: false creates the policies" do
302
+ @client.register_queue("some_queue", :exchange => "some_exchange", :key => "haha.#", :arguments => {"foo" => "fighter"})
303
+ @pub.expects(:exchange).with("some_exchange").returns(:the_exchange)
304
+ q = mock("queue")
305
+ q.expects(:bind).with(:the_exchange, {:key => "haha.#"})
306
+ m = mock("Bunny")
307
+ m.expects(:queue).with("some_queue", :durable => true, :passive => false, :auto_delete => false, :exclusive => false, :arguments => {"foo" => "fighter"}).returns(q)
308
+ @pub.expects(:bunny).returns(m)
309
+
284
310
  @pub.send(:queue, "some_queue")
285
- assert_equal q, @pub.send(:queues)["some_queue"]
311
+ assert_equal Base::QueueInfo.new(q, false), @pub.send(:queues)["some_queue"]
312
+
313
+ @pub.expects(:exchange).with("some_exchange").returns(:the_exchange)
314
+ q.expects(:bind).with(:the_exchange, {:key => "haha.#"})
315
+ m.expects(:queue).with("some_queue", :durable => true, :passive => false, :auto_delete => false, :exclusive => false, :arguments => {"foo" => "fighter"}).returns(q)
316
+ @pub.expects(:bunny).returns(m).twice
317
+
318
+ @pub.send(:queue, "some_queue", create_policies: true)
319
+ assert_equal Base::QueueInfo.new(q, true), @pub.send(:queues)["some_queue"]
286
320
  end
287
321
 
288
322
  test "should bind the defined queues for the used exchanges when publishing" do
@@ -325,6 +359,18 @@ module Beetle
325
359
  queue.expects(:purge).in_sequence(s)
326
360
  @pub.purge(["queue"])
327
361
  end
362
+
363
+ test "setting up queues and policies should iterate over all servers" do
364
+ @pub.servers = %w(a b)
365
+ queue = mock("queue")
366
+ s = sequence("setup")
367
+ @pub.expects(:set_current_server).with("a").in_sequence(s)
368
+ @pub.expects(:queue).with("queue", :create_policies => true).returns(queue).in_sequence(s)
369
+ @pub.expects(:set_current_server).with("b").in_sequence(s)
370
+ @pub.expects(:queue).with("queue", :create_policies => true).returns(queue).in_sequence(s)
371
+ @pub.setup_queues_and_policies(["queue"])
372
+ end
373
+
328
374
  end
329
375
 
330
376
  class PublisherExchangeManagementTest < Minitest::Test
@@ -89,7 +89,7 @@ module Beetle
89
89
  q = mock("queue a")
90
90
  q.expects(:subscribed?).returns(true)
91
91
  q.expects(:unsubscribe)
92
- @sub.stubs(:queues).returns({"a" =>q})
92
+ @sub.stubs(:queues).returns({"a" => Base::QueueInfo.new(q,false)})
93
93
  @sub.__send__(:pause, "a")
94
94
  end
95
95
 
@@ -97,7 +97,7 @@ module Beetle
97
97
  q = mock("queue a")
98
98
  q.expects(:subscribed?).returns(false)
99
99
  q.expects(:unsubscribe).never
100
- @sub.stubs(:queues).returns({"a" =>q})
100
+ @sub.stubs(:queues).returns({"a" => Base::QueueInfo.new(q,false)})
101
101
  @sub.__send__(:pause, "a")
102
102
  end
103
103
 
@@ -105,7 +105,7 @@ module Beetle
105
105
  q = mock("queue a")
106
106
  q.expects(:subscribed?).returns(false)
107
107
  q.expects(:subscribe)
108
- @sub.stubs(:queues).returns({"a" =>q})
108
+ @sub.stubs(:queues).returns({"a" => Base::QueueInfo.new(q,false)})
109
109
  @sub.__send__(:resume, "a")
110
110
  end
111
111
 
@@ -113,7 +113,7 @@ module Beetle
113
113
  q = mock("queue a")
114
114
  q.expects(:subscribed?).returns(true)
115
115
  q.expects(:subscribe).never
116
- @sub.stubs(:queues).returns({"a" =>q})
116
+ @sub.stubs(:queues).returns({"a" => Base::QueueInfo.new(q,false)})
117
117
  @sub.__send__(:resume, "a")
118
118
  end
119
119
 
@@ -150,10 +150,23 @@ module Beetle
150
150
  q.expects(:bind).with(:the_exchange, {:key => "haha.#"})
151
151
  m = mock("MQ")
152
152
  m.expects(:queue).with("some_queue", :durable => true, :passive => false, :auto_delete => false, :exclusive => false, :arguments => {"schmu" => 5}).returns(q)
153
- @sub.expects(:channel).returns(m).twice
153
+ @sub.expects(:channel).returns(m)
154
154
 
155
155
  @sub.send(:queue, "some_queue")
156
- assert_equal q, @sub.send(:queues)["some_queue"]
156
+ assert_equal q, @sub.send(:queues)["some_queue"].queue
157
+ end
158
+
159
+ test "binding a queue should create it using the config and bind it to the exchange with the name specified and create policies if requested" do
160
+ @client.register_queue("some_queue", "durable" => true, "exchange" => "some_exchange", "key" => "haha.#", "arguments" => {"schmu" => 5})
161
+ @sub.expects(:exchange).with("some_exchange").returns(:the_exchange)
162
+ q = mock("queue")
163
+ q.expects(:bind).with(:the_exchange, {:key => "haha.#"})
164
+ m = mock("MQ")
165
+ m.expects(:queue).with("some_queue", :durable => true, :passive => false, :auto_delete => false, :exclusive => false, :arguments => {"schmu" => 5}).returns(q)
166
+ @sub.expects(:channel).returns(m).twice
167
+
168
+ @sub.send(:queue, "some_queue", create_policies: true)
169
+ assert_equal q, @sub.send(:queues)["some_queue"].queue
157
170
  end
158
171
 
159
172
  test "binding queues should bind all queues" do
@@ -357,7 +370,7 @@ module Beetle
357
370
  q = mock("QUEUE")
358
371
  subscription_options = {:ack => true, :key => "#"}
359
372
  q.expects(:subscribe).with(subscription_options).yields(header, "foo")
360
- @sub.expects(:queues).returns({"some_queue" => q}).once
373
+ @sub.expects(:queues).returns({"some_queue" => Base::QueueInfo.new(q,false)}).once
361
374
  @sub.send(:subscribe, "some_queue")
362
375
  assert block_called
363
376
  assert @sub.__send__(:has_subscription?, "some_queue")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beetle
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 3.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Kaes
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2019-03-26 00:00:00.000000000 Z
15
+ date: 2019-04-26 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bunny
@@ -322,7 +322,6 @@ files:
322
322
  - examples/headers.rb
323
323
  - examples/multiple_exchanges.rb
324
324
  - examples/multiple_queues.rb
325
- - examples/murks.rb
326
325
  - examples/nonexistent_server.rb
327
326
  - examples/pause_and_resume.rb
328
327
  - examples/publish_many_messages.rb
data/examples/murks.rb DELETED
@@ -1,30 +0,0 @@
1
- require 'bunny'
2
-
3
- conn = Bunny.new
4
- conn.start
5
-
6
- # consumer
7
- ch = conn.create_channel
8
- x = ch.topic("echo")
9
- q1 = ch.queue("echo").bind(x, :routing_key => "#")
10
-
11
- consumer = q1.subscribe do |delivery_info, properties, payload|
12
- puts delivery_info.inspect, properties.inspect, payload.inspect
13
- ch.default_exchange.publish(payload.to_s, :routing_key => properties[:reply_to])
14
- end
15
-
16
- # publisher
17
- q2 = ch.queue()
18
- puts "reply queue: #{q2.name}"
19
- x.publish("Hello, everybody!", :routing_key => "echo", :reply_to => q2.name)
20
-
21
- sleep 1
22
-
23
- delivery_info, properties, payload = q2.pop
24
-
25
- puts "This is the message: " + payload.inspect
26
- puts delivery_info.inspect, properties.inspect
27
-
28
- consumer.cancel
29
- ch.close
30
- conn.close