message-driver 0.1.0 → 0.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +18 -7
  4. data/CHANGELOG.md +12 -2
  5. data/Gemfile +17 -0
  6. data/Guardfile +8 -4
  7. data/README.md +14 -5
  8. data/Rakefile +44 -11
  9. data/examples/basic_producer_and_consumer/Gemfile +5 -0
  10. data/examples/basic_producer_and_consumer/common.rb +17 -0
  11. data/examples/basic_producer_and_consumer/consumer.rb +24 -0
  12. data/examples/basic_producer_and_consumer/producer.rb +33 -0
  13. data/features/.nav +8 -0
  14. data/features/CHANGELOG.md +12 -2
  15. data/features/amqp_specific_features/binding_amqp_destinations.feature +7 -7
  16. data/features/amqp_specific_features/declaring_amqp_exchanges.feature +3 -3
  17. data/features/amqp_specific_features/nack_redelivered_messages.feature +92 -0
  18. data/features/amqp_specific_features/requeueing_on_nack.feature +44 -0
  19. data/features/amqp_specific_features/server_named_destinations.feature +5 -5
  20. data/features/client_acks.feature +92 -0
  21. data/features/destination_metadata.feature +9 -11
  22. data/features/dynamic_destinations.feature +7 -7
  23. data/features/error_handling.feature +11 -9
  24. data/features/logging.feature +14 -0
  25. data/features/message_consumers/auto_ack_consumers.feature +79 -0
  26. data/features/message_consumers/manual_ack_consumers.feature +95 -0
  27. data/features/message_consumers/transactional_ack_consumers.feature +77 -0
  28. data/features/message_consumers.feature +54 -0
  29. data/features/publishing_a_message.feature +6 -10
  30. data/features/publishing_with_transactions.feature +10 -14
  31. data/features/rabbitmq_specific_features/dead_letter_queueing.feature +116 -0
  32. data/features/step_definitions/dynamic_destinations_steps.rb +3 -3
  33. data/features/step_definitions/error_handling_steps.rb +4 -2
  34. data/features/step_definitions/logging_steps.rb +28 -0
  35. data/features/step_definitions/message_consumers_steps.rb +29 -0
  36. data/features/step_definitions/steps.rb +60 -9
  37. data/features/support/broker_config_helper.rb +19 -0
  38. data/features/support/env.rb +1 -0
  39. data/features/support/firewall_helper.rb +8 -11
  40. data/features/support/message_table_matcher.rb +21 -5
  41. data/features/support/test_runner.rb +39 -16
  42. data/lib/message_driver/adapters/base.rb +51 -4
  43. data/lib/message_driver/adapters/bunny_adapter.rb +251 -127
  44. data/lib/message_driver/adapters/in_memory_adapter.rb +97 -18
  45. data/lib/message_driver/adapters/stomp_adapter.rb +127 -0
  46. data/lib/message_driver/broker.rb +23 -24
  47. data/lib/message_driver/client.rb +157 -0
  48. data/lib/message_driver/destination.rb +7 -4
  49. data/lib/message_driver/errors.rb +27 -0
  50. data/lib/message_driver/logging.rb +11 -0
  51. data/lib/message_driver/message.rb +8 -0
  52. data/lib/message_driver/subscription.rb +18 -0
  53. data/lib/message_driver/vendor/.document +0 -0
  54. data/lib/message_driver/vendor/nesty/nested_error.rb +26 -0
  55. data/lib/message_driver/vendor/nesty.rb +1 -0
  56. data/lib/message_driver/version.rb +1 -1
  57. data/lib/message_driver.rb +4 -2
  58. data/message-driver.gemspec +4 -4
  59. data/spec/integration/{amqp_integration_spec.rb → bunny/amqp_integration_spec.rb} +29 -28
  60. data/spec/integration/bunny/bunny_adapter_spec.rb +339 -0
  61. data/spec/integration/in_memory/in_memory_adapter_spec.rb +126 -0
  62. data/spec/integration/stomp/stomp_adapter_spec.rb +142 -0
  63. data/spec/spec_helper.rb +5 -2
  64. data/spec/support/shared/adapter_examples.rb +17 -0
  65. data/spec/support/shared/client_ack_examples.rb +18 -0
  66. data/spec/support/shared/context_examples.rb +14 -0
  67. data/spec/support/shared/destination_examples.rb +4 -5
  68. data/spec/support/shared/subscription_examples.rb +146 -0
  69. data/spec/support/shared/transaction_examples.rb +43 -0
  70. data/spec/support/utils.rb +14 -0
  71. data/spec/units/message_driver/adapters/base_spec.rb +38 -19
  72. data/spec/units/message_driver/broker_spec.rb +71 -18
  73. data/spec/units/message_driver/client_spec.rb +375 -0
  74. data/spec/units/message_driver/destination_spec.rb +9 -0
  75. data/spec/units/message_driver/logging_spec.rb +18 -0
  76. data/spec/units/message_driver/message_spec.rb +36 -0
  77. data/spec/units/message_driver/subscription_spec.rb +24 -0
  78. data/test_lib/broker_config.rb +50 -20
  79. metadata +83 -45
  80. data/.rbenv-version +0 -1
  81. data/lib/message_driver/exceptions.rb +0 -18
  82. data/lib/message_driver/message_publisher.rb +0 -15
  83. data/spec/integration/message_driver/adapters/bunny_adapter_spec.rb +0 -301
  84. data/spec/units/message_driver/adapters/in_memory_adapter_spec.rb +0 -43
  85. data/spec/units/message_driver/message_publisher_spec.rb +0 -65
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ee1e524ed1e97823d1bf57bebb54afdd7be3d377
4
+ data.tar.gz: a1e55de021a74bcbf71b4df3be92e3f28506464f
5
+ SHA512:
6
+ metadata.gz: aaa3bd79fe84ddb7020fbb1173824d4bd24dba54b86737712bf412f450d07bee650ea1636d411f55a7d19668a950e87d4a583ac28fd2f167814fad1ea253accb
7
+ data.tar.gz: b71dbc3eb07d9f75b00032ea1c8bdcf8412026cc8b51a77c257ec62b8b578d754efdbeaf7a2b5b3a46763f2723150bfd181d970756b3d7852cf01a254a205d4e
data/.gitignore CHANGED
@@ -5,6 +5,7 @@
5
5
  .yardoc
6
6
  .rvmrc
7
7
  .ruby-version
8
+ .rbenv-version
8
9
  Gemfile.lock
9
10
  InstalledFiles
10
11
  _yardoc
data/.travis.yml CHANGED
@@ -5,19 +5,30 @@ services:
5
5
  before_script:
6
6
  - sudo rabbitmqctl add_vhost message-driver-test
7
7
  - sudo rabbitmqctl set_permissions -p message-driver-test guest ".*" ".*" ".*"
8
+ - sudo rabbitmq-plugins enable rabbitmq_stomp
9
+ - sudo service rabbitmq-server restart
10
+ env:
11
+ - ADAPTER=in_memory
12
+ - ADAPTER=bunny:0.9.0
13
+ - ADAPTER=bunny:0.10.0
14
+ - ADAPTER=stomp
15
+ - ADAPTER=bunny:1.0.0.pre
8
16
  rvm:
9
- - 1.9.2
10
- - 1.9.3
11
17
  - 2.0.0
18
+ - 1.9.3
19
+ - 1.9.2
12
20
  - jruby-19mode
13
- - ruby-head
14
21
  - jruby-head
15
22
  - rbx-19mode
16
- env:
17
- - ADAPTER=in_memory
18
- - ADAPTER=bunny
19
23
  matrix:
24
+ exclude:
25
+ - rvm: jruby-19mode
26
+ env: ADAPTER=bunny:0.9.0
27
+ - rvm: jruby-head
28
+ env: ADAPTER=bunny:0.9.0
20
29
  allow_failures:
21
- - rvm: ruby-head
30
+ - env: ADAPTER=bunny:1.0.0.pre
22
31
  - rvm: jruby-head
23
32
  - rvm: rbx-19mode
33
+ - rvm: jruby-19mode
34
+ env: ADAPTER=stomp
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
- # Change Log
1
+ # Changelog
2
2
 
3
- ## 0.1.0
3
+ ## 0.2.0.rc1 - 2013-09-23
4
+
5
+ * Features
6
+ * Message Consumers
7
+ * Bunny and InMemory adapters
8
+ * Client Acks
9
+ * Bunny adapter
10
+ * Adapters
11
+ * begin work on Stomp 1.1/1.2 adapter
12
+
13
+ ## 0.1.0 - 2013-04-05
4
14
 
5
15
  Initial Release
6
16
 
data/Gemfile CHANGED
@@ -16,5 +16,22 @@ group :tools do
16
16
  gem 'ruby_gntp'
17
17
  gem 'rb-fsevent'
18
18
  gem 'relish'
19
+ gem 'lunchy'
20
+ end
21
+ end
22
+
23
+ require File.expand_path("../test_lib/broker_config", __FILE__)
24
+
25
+ adapter = BrokerConfig.current_adapter.to_s
26
+ version = BrokerConfig.adapter_version
27
+
28
+ case adapter
29
+ when 'in_memory'
30
+ else
31
+ case version
32
+ when nil
33
+ gem adapter
34
+ else
35
+ gem adapter.to_s, "~> #{version}"
19
36
  end
20
37
  end
data/Guardfile CHANGED
@@ -8,8 +8,9 @@ guard 'bundler' do
8
8
  watch(/^.+\.gemspec/)
9
9
  end
10
10
 
11
- unit_spec_opts = {spec_paths: ["spec/units"], cli: '-f doc', run_all: {cli: ''}}
12
- acceptance_spec_opts = {spec_paths: ["spec/integration"], cli: '-f doc -t all_adapters', run_all: {cli: '-t all_adapters'}}
11
+ common_rspec_opts = {keep_failed: true, all_after_pass: true}
12
+ unit_spec_opts = common_rspec_opts.merge({spec_paths: ["spec/units"], cli: '-f doc', run_all: {cli: ''}})
13
+ integration_spec_opts = common_rspec_opts.merge({spec_paths: ["spec/integration/#{BrokerConfig.current_adapter}"], cli: '-f doc -t all_adapters', run_all: {cli: '-t all_adapters'}})
13
14
 
14
15
  group 'specs' do
15
16
  guard 'rspec', unit_spec_opts do
@@ -21,15 +22,18 @@ group 'specs' do
21
22
  end
22
23
 
23
24
  group 'integration' do
24
- guard 'rspec', acceptance_spec_opts do
25
+ guard 'rspec', integration_spec_opts do
25
26
  watch(%r{^spec/integration/.+_spec\.rb$})
26
27
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/integration/#{m[1]}_spec.rb" }
27
28
  watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
28
29
  watch('spec/spec_helper.rb') { "spec" }
29
30
  end
31
+ end
30
32
 
33
+ group 'features' do
31
34
  cucumber_cli = "--no-profile --color --format progress --strict --tag @all_adapters,@#{BrokerConfig.current_adapter} --tag ~@wip"
32
- guard 'cucumber', change_format: 'pretty', cli: cucumber_cli do
35
+ cucumber_run_all_cli = "#{cucumber_cli} --tag ~@slow"
36
+ guard 'cucumber', change_format: 'pretty', all_on_start: false, cli: cucumber_cli, run_all: { cli: cucumber_run_all_cli } do
33
37
  watch(%r{^features/.+\.feature$})
34
38
  watch(%r{^features/support/.+$}) { 'features' }
35
39
  watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
data/README.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  Easy message queues for ruby
4
4
 
5
- [![Build Status](https://travis-ci.org/soupmatt/message-driver.png?branch=master)](https://travis-ci.org/soupmatt/message-driver)
5
+ [![Gem Version](https://badge.fury.io/rb/message-driver.png)](http://badge.fury.io/rb/message-driver)
6
6
 
7
- [![Dependency Status](https://gemnasium.com/soupmatt/message-driver.png)](https://gemnasium.com/soupmatt/message-driver)
7
+ [![Build Status](https://travis-ci.org/message-driver/message-driver.png?branch=master)](https://travis-ci.org/message-driver/message-driver)
8
8
 
9
- [![Code Climate](https://codeclimate.com/github/soupmatt/message-driver.png)](https://codeclimate.com/github/soupmatt/message-driver)
9
+ [![Dependency Status](https://gemnasium.com/message-driver/message-driver.png)](https://gemnasium.com/message-driver/message-driver)
10
+
11
+ [![Code Climate](https://codeclimate.com/github/message-driver/message-driver.png)](https://codeclimate.com/github/message-driver/message-driver)
10
12
 
11
13
  ## Installation
12
14
 
@@ -14,6 +16,11 @@ Add this line to your application's Gemfile:
14
16
 
15
17
  gem 'message-driver'
16
18
 
19
+ You'll also want to add a driver gem:
20
+
21
+ gem 'bunny'
22
+ gem 'stomp'
23
+
17
24
  And then execute:
18
25
 
19
26
  $ bundle
@@ -22,9 +29,11 @@ Or install it yourself as:
22
29
 
23
30
  $ gem install message-driver
24
31
 
25
- ## Usage
32
+ ## Documentation
33
+
34
+ You can find the main documentation here: https://www.relishapp.com/message-driver/message-driver
26
35
 
27
- TODO: Write usage instructions here
36
+ You can also take a look at the [examples](/examples)
28
37
 
29
38
  ## Contributing
30
39
 
data/Rakefile CHANGED
@@ -1,23 +1,56 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
1
4
  require 'bundler/gem_tasks'
2
5
 
3
6
  require 'rspec/core/rake_task'
4
7
  require 'cucumber/rake/task'
5
8
 
6
- require File.join(File.dirname(__FILE__), 'test_lib', 'broker_config')
9
+ #require File.join(File.dirname(__FILE__), 'test_lib', 'broker_config')
10
+
11
+ namespace :spec do
12
+ desc "Run unit specs"
13
+ RSpec::Core::RakeTask.new(:units) do |t|
14
+ t.pattern = "./spec/units{,/*/**}/*_spec.rb"
15
+ end
16
+
17
+ desc "Run the integration specs"
18
+ RSpec::Core::RakeTask.new(:integrations) do |t|
19
+ t.rspec_opts = "--tag all_adapters"
20
+ t.pattern = "./spec/integration/#{BrokerConfig.current_adapter}{,/*/**}/*_spec.rb"
21
+ end
22
+
23
+ cucumber_opts = "--format progress --tag @all_adapters,@#{BrokerConfig.current_adapter} --tag ~@wip"
24
+ cucumber_opts += " --tag ~@no_ci" if ENV['CI']=='true' && ENV['ADAPTER'] && ENV['ADAPTER'].start_with?('bunny')
25
+ Cucumber::Rake::Task.new(:features) do |t|
26
+ t.cucumber_opts = cucumber_opts
27
+ end
28
+
29
+ desc "run all the specs"
30
+ task :all => [:units, :integrations, :features]
7
31
 
8
- RSpec::Core::RakeTask.new(:spec) do |t|
9
- t.pattern = "./spec/units{,/*/**}/*_spec.rb"
32
+ desc "run all the specs for each adapter"
33
+ task :all_adapters do
34
+ current_adapter = BrokerConfig.current_adapter
35
+ BrokerConfig.all_adapters.each do |adapter|
36
+ set_adapter_under_test(adapter)
37
+ system("rake spec:all")
38
+ end
39
+ set_adapter_under_test(current_adapter)
40
+ end
10
41
  end
11
42
 
12
- RSpec::Core::RakeTask.new(:integrations) do |t|
13
- t.rspec_opts = "--tag all_adapters"
14
- t.pattern = "./spec/integration{,/*/**}/*_spec.rb"
43
+ def set_adapter_under_test(adapter)
44
+ system "echo #{adapter} > #{File.join(File.dirname(__FILE__), '.adapter_under_test')}"
15
45
  end
16
46
 
17
- cucumber_opts = "--format progress --tag @all_adapters,@#{BrokerConfig.current_adapter} --tag ~@wip"
18
- cucumber_opts += " --tag ~@no_travis" if ENV['TRAVIS']=='true' && ENV['ADAPTER']=='bunny'
19
- Cucumber::Rake::Task.new do |t|
20
- t.cucumber_opts = cucumber_opts
47
+ namespace :undertest do
48
+ BrokerConfig.all_adapters.each do |adapter|
49
+ desc "set the adapter under test to #{adapter}"
50
+ task adapter do
51
+ set_adapter_under_test(adapter)
52
+ end
53
+ end
21
54
  end
22
55
 
23
- task :default => [:spec, :integrations, :cucumber]
56
+ task :default => ["spec:all"]
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "message-driver", path: "../.."
4
+
5
+ gem 'bunny'
@@ -0,0 +1,17 @@
1
+ require 'bundler/setup'
2
+ require 'message-driver'
3
+ require 'logger'
4
+
5
+ LOG = Logger.new(STDOUT)
6
+ LOG.level = Logger::DEBUG
7
+
8
+ MessageDriver.configure(
9
+ adapter: "bunny",
10
+ vhost: "message-driver-dev",
11
+ heartbeat_interval: 2,
12
+ logger: LOG
13
+ )
14
+
15
+ MessageDriver::Broker.define do |b|
16
+ b.destination :basic_consumer_producer, "basic.consumer.producer", durable: true
17
+ end
@@ -0,0 +1,24 @@
1
+ require_relative "./common"
2
+
3
+ LOG.info("starting consumer")
4
+
5
+ end_thread = Thread.new do
6
+ Thread.stop
7
+ LOG.info("stopping consumer")
8
+ MessageDriver::Broker.stop
9
+ end
10
+
11
+ ending_proc = proc do
12
+ end_thread.wakeup
13
+ end
14
+
15
+ trap "TERM", &ending_proc
16
+ trap "INT", &ending_proc
17
+
18
+ MessageDriver::Broker.consumer(:basic_consumer) do |message|
19
+ LOG.info("I got a message! #{message.body}")
20
+ end
21
+
22
+ MessageDriver::Client.subscribe(:basic_consumer_producer, :basic_consumer)
23
+
24
+ end_thread.join
@@ -0,0 +1,33 @@
1
+ require_relative "./common"
2
+
3
+ LOG.info("starting producer")
4
+
5
+ stopping = false
6
+
7
+ ending_proc = proc do
8
+ stopping = true
9
+ end
10
+
11
+ trap "TERM", &ending_proc
12
+ trap "INT", &ending_proc
13
+
14
+ counter = 0
15
+
16
+ while !stopping do
17
+ 10.times do
18
+ counter += 1
19
+ begin
20
+ MessageDriver::Client.publish(:basic_consumer_producer, "message #{counter}")
21
+ rescue MessageDriver::ConnectionError => e
22
+ LOG.info("The connection is closed! #{e}")
23
+ sleep 1
24
+ LOG.info("retrying...")
25
+ retry
26
+ end
27
+ end
28
+ LOG.info("sent 10 more messages for a total of #{counter}")
29
+ sleep 1
30
+ end
31
+
32
+ LOG.info("stopping producer")
33
+ MessageDriver::Broker.stop
data/features/.nav CHANGED
@@ -4,9 +4,17 @@
4
4
  - publishing_with_transactions.feature
5
5
  - dynamic_destinations.feature
6
6
  - destination_metadata.feature
7
+ - client_acks.feature
8
+ - logging.feature
9
+ - message_consumers.feature
10
+ - message_consumers
11
+ - auto_ack_consumers.feature
12
+ - manual_ack_consumers.feature
13
+ - transactional_ack_consumers.feature
7
14
  - amqp_specific_features (AMQP-Specific Features):
8
15
  - declaring_amqp_destinations.feature
9
16
  - binding_amqp_destinations.feature
10
17
  - server_named_desitnations.feature
18
+ - requeueing_on_nack.feature
11
19
  - error_handling.feature
12
20
  - Rails.md
@@ -1,6 +1,16 @@
1
- # Change Log
1
+ # Changelog
2
2
 
3
- ## 0.1.0
3
+ ## 0.2.0.rc1 - 2013-09-23
4
+
5
+ * Features
6
+ * Message Consumers
7
+ * Bunny and InMemory adapters
8
+ * Client Acks
9
+ * Bunny adapter
10
+ * Adapters
11
+ * begin work on Stomp 1.1/1.2 adapter
12
+
13
+ ## 0.1.0 - 2013-04-05
4
14
 
5
15
  Initial Release
6
16
 
@@ -1,7 +1,7 @@
1
1
  @bunny
2
2
  Feature: Binding AMQP destinations to exchanges
3
3
  Background:
4
- Given the following broker configuration:
4
+ Given the following broker configuration
5
5
  """ruby
6
6
  MessageDriver::Broker.define do |b|
7
7
  b.destination :direct_exchange, "amq.direct", type: :exchange
@@ -9,10 +9,10 @@ Feature: Binding AMQP destinations to exchanges
9
9
  """
10
10
 
11
11
  Scenario: Binding a queue to an exchange
12
- When I execute the following code:
12
+ When I execute the following code
13
13
  """ruby
14
14
  MessageDriver::Broker.define do |b|
15
- b.destination :my_queue, "my_queue", exclusive: true, bindings: [
15
+ b.destination :my_queue, "my_bound_queue", exclusive: true, bindings: [
16
16
  {source: "amq.direct", args: {routing_key: "test_binding"}},
17
17
  {source: "amq.direct", args: {routing_key: "spec_binding"}}
18
18
  ]
@@ -22,7 +22,7 @@ Feature: Binding AMQP destinations to exchanges
22
22
  publish(:direct_exchange, "Spec Message", {}, {routing_key: "spec_binding"})
23
23
  """
24
24
 
25
- Then I expect to find 2 messages on :my_queue with:
25
+ Then I expect to find the following 2 messages on :my_queue
26
26
  | body |
27
27
  | Test Message |
28
28
  | Spec Message |
@@ -30,21 +30,21 @@ Feature: Binding AMQP destinations to exchanges
30
30
  Scenario: Binding an exchange to an exchange
31
31
  RabbitMQ's AMQP 0.9 extenstions support binding exchanges to exchanges
32
32
 
33
- When I execute the following code:
33
+ When I execute the following code
34
34
  """ruby
35
35
  MessageDriver::Broker.define do |b|
36
36
  b.destination :fanout, "amq.fanout", type: :exchange, bindings: [
37
37
  {source: "amq.direct", args: {routing_key: "test_binding"}},
38
38
  {source: "amq.direct", args: {routing_key: "spec_binding"}}
39
39
  ]
40
- b.destination :my_queue, "my_queue", exclusive: true, bindings: [{source: "amq.fanout"}]
40
+ b.destination :my_queue, "my_bound_queue", exclusive: true, bindings: [{source: "amq.fanout"}]
41
41
  end
42
42
 
43
43
  publish(:direct_exchange, "Test Message", {}, {routing_key: "test_binding"})
44
44
  publish(:direct_exchange, "Spec Message", {}, {routing_key: "spec_binding"})
45
45
  """
46
46
 
47
- Then I expect to find 2 messages on :my_queue with:
47
+ Then I expect to find the following 2 messages on :my_queue
48
48
  | body |
49
49
  | Test Message |
50
50
  | Spec Message |
@@ -7,16 +7,16 @@ Feature: Declaring AMQP exchanges
7
7
  Given I am connected to the broker
8
8
 
9
9
  Scenario: Declaring a direct exchange
10
- When I execute the following code:
10
+ When I execute the following code
11
11
  """ruby
12
12
  MessageDriver::Broker.define do |b|
13
13
  b.destination :my_exchange, "my_exchange", type: :exchange, declare: {type: :direct, auto_delete: true}
14
- b.destination :my_queue, "my_queue", exclusive: true, bindings: [{source: "my_exchange", routing_key: "my_queue"}]
14
+ b.destination :my_queue, "", exclusive: true, bindings: [{source: "my_exchange", routing_key: "my_queue"}]
15
15
  end
16
16
 
17
17
  publish(:my_exchange, "Test My New Exchange", routing_key: "my_queue")
18
18
  """
19
19
 
20
- Then I expect to find 1 message on :my_queue with:
20
+ Then I expect to find the following message on :my_queue
21
21
  | body |
22
22
  | Test My New Exchange |
@@ -0,0 +1,92 @@
1
+ @bunny
2
+ Feature: Nacking Redelievered Messages from a consumer
3
+
4
+ You can configure the consumer to nack a re-delievered message. In this example, we use
5
+ a dead letter exchange to show how things end up working.
6
+
7
+ Background:
8
+ Given the following broker configuration
9
+ """ruby
10
+ MessageDriver::Broker.define do |b|
11
+ # declare a dead letter exchange
12
+ b.destination :rabbit_dlx, "rabbit.dead.letter.exchange", type: :exchange, declare: { type: :fanout }
13
+
14
+ # declare a dead letter queue and bind it to the exchange
15
+ b.destination :rabbit_dlq, "rabbit.dead.letter.queue", bindings: [
16
+ { source: "rabbit.dead.letter.exchange" }
17
+ ]
18
+
19
+ # declare a work queue that sends dead letters to our dead letter queue
20
+ b.destination :rabbit_work, "rabbit.work", arguments: { :"x-dead-letter-exchange" => "rabbit.dead.letter.exchange" }
21
+ end
22
+ """
23
+ And I have no messages on :rabbit_work
24
+ And I have no messages on :rabbit_dlq
25
+ And I have a destination :rabbit_track with no messages on it
26
+
27
+
28
+ Scenario: Raising a DontRequeueError in an auto_ack consumer
29
+ Given I have a message consumer
30
+ """ruby
31
+ MessageDriver::Broker.consumer(:manual_redeliver) do |message|
32
+ publish(:rabbit_track, "#{message.body} Attempt")
33
+ raise "oh nos!"
34
+ end
35
+ """
36
+ And I create a subscription
37
+ """ruby
38
+ MessageDriver::Client.subscribe(:rabbit_work, :manual_redeliver, ack: :auto, retry_redelivered: false)
39
+ """
40
+
41
+ When I send the following messages to :rabbit_work
42
+ | body |
43
+ | Auto Retry 1 |
44
+ | Auto Retry 2 |
45
+ And I let the subscription process
46
+
47
+ Then I expect to find no messages on :rabbit_work
48
+ And I expect to find the following 2 messages on :rabbit_dlq
49
+ | body |
50
+ | Auto Retry 1 |
51
+ | Auto Retry 2 |
52
+ And I expect to find the following 4 messages on :rabbit_track
53
+ | body |
54
+ | Auto Retry 1 Attempt |
55
+ | Auto Retry 2 Attempt |
56
+ | Auto Retry 1 Attempt |
57
+ | Auto Retry 2 Attempt |
58
+
59
+
60
+ Scenario: Raising a DontRequeueError in a transactional consumer
61
+ Given I have a message consumer
62
+ """ruby
63
+ @attempts = 0
64
+ MessageDriver::Broker.consumer(:transactional_redeliver) do |message|
65
+ publish(:rabbit_track, "#{message.body} Attempt")
66
+ @attempts += 1
67
+ raise "oh nos!"
68
+ end
69
+ """
70
+ And I create a subscription
71
+ """ruby
72
+ MessageDriver::Client.subscribe(:rabbit_work, :transactional_redeliver, ack: :transactional, retry_redelivered: false)
73
+ """
74
+
75
+ When I send the following messages to :rabbit_work
76
+ | body |
77
+ | Transactional Redeliver 1 |
78
+ | Transactional Redeliver 2 |
79
+ And I let the subscription process
80
+ And I restart the subscription
81
+ And I let the subscription process
82
+
83
+ Then I expect to find no messages on :rabbit_track
84
+ Then I expect to find no messages on :rabbit_work
85
+ Then I expect the following check to pass
86
+ """ruby
87
+ expect(@attempts).to eq(4)
88
+ """
89
+ Then I expect to find the following 2 messages on :rabbit_dlq
90
+ | body |
91
+ | Transactional Redeliver 1 |
92
+ | Transactional Redeliver 2 |
@@ -0,0 +1,44 @@
1
+ @bunny
2
+ Feature: Controlling requeue on message nack
3
+ You can control whether or not a message is requeued when you nack the message.
4
+ Exact behavior when requeue is false is specific to your broker's setup.
5
+
6
+ Background:
7
+ Given I am connected to the broker
8
+ And I have a destination :source_queue
9
+ And I have the following messages on :source_queue
10
+ | body |
11
+ | Test Message |
12
+
13
+ Scenario: Requeue by default
14
+ When I execute the following code
15
+ """ruby
16
+ message = MessageDriver::Client.pop_message(:source_queue, client_ack: true)
17
+ message.nack
18
+ """
19
+
20
+ Then I expect to find the following message on :source_queue
21
+ | body |
22
+ | Test Message |
23
+
24
+
25
+ Scenario: Requeue is true
26
+ When I execute the following code
27
+ """ruby
28
+ message = MessageDriver::Client.pop_message(:source_queue, client_ack: true)
29
+ message.nack(requeue: true)
30
+ """
31
+
32
+ Then I expect to find the following message on :source_queue
33
+ | body |
34
+ | Test Message |
35
+
36
+
37
+ Scenario: Requeue is false
38
+ When I execute the following code
39
+ """ruby
40
+ message = MessageDriver::Client.pop_message(:source_queue, client_ack: true)
41
+ message.nack(requeue: false)
42
+ """
43
+
44
+ Then I expect to find no messages on :source_queue
@@ -9,7 +9,7 @@ Feature: Server-Named Destinations
9
9
  Scenario: Creating a server-named queue
10
10
  I expect my destination to have the queue name given to it by the server
11
11
 
12
- When I execute the following code:
12
+ When I execute the following code
13
13
  """ruby
14
14
  destination = MessageDriver::Broker.dynamic_destination("", exclusive: true)
15
15
  expect(destination.name).to_not be_empty
@@ -18,18 +18,18 @@ Feature: Server-Named Destinations
18
18
  Then I expect to have no errors
19
19
 
20
20
  Scenario: sending and receiving messages through a server-named queue
21
- Given the following broker configuration:
21
+ Given the following broker configuration
22
22
  """ruby
23
23
  MessageDriver::Broker.define do |b|
24
- b.destination :my_queue, "my_queue", exclusive: true
24
+ b.destination :my_queue, "", exclusive: true
25
25
  end
26
26
  """
27
27
 
28
- When I execute the following code:
28
+ When I execute the following code
29
29
  """ruby
30
30
  publish(:my_queue, "server-named queue message")
31
31
  """
32
32
 
33
- Then I expect to find 1 message on :my_queue with:
33
+ Then I expect to find the following message on :my_queue
34
34
  | body |
35
35
  | server-named queue message |