-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Default binding for DLX queues instead of wildcard (#129)
* Default binding for DLX queues instead of wildcard Since rabbitMQ by default sends messages in DLX with the original routing key, the default binding for the `*_errored` queue should be the same as the original queue. ```elixir %{ exchanges: [ %{ name: "exchange_name", routing_keys: ["example_key"], type: :topic } ], opts: [ durable: true, arguments: [ {"x-dead-letter-exchange", :longstr, "errors_exchange"} ] ], queue: "queue_name" } ``` **before:** ``` TO queue_name_errored ROUTING KEY # ``` **after:** ``` TO queue_name_errored ROUTING KEY example_key ``` Of course things could be very complex if the original queue has more than one exchange etc, but then a DLX may not be feasible at all 🤷🏻 * restrict empty dead letter exchange configuration * scarsezza * Fix entrypoint * Fix format * Bump major since this is a change in the behaviour of the APIs * Add some tests * Add missing test * Fix match * Fix test * Update test/helper_test.exs Co-authored-by: Daniele Bartocci <[email protected]> * Fix behaviour * Fix behaviour * My bad * It's the final fix * io non credo * Collapse into one error * Update test/helper_test.exs Co-authored-by: Cristiano Piemontese <[email protected]> * Update test/helper_test.exs Co-authored-by: Cristiano Piemontese <[email protected]> * Fix test description * Better error message * Update lib/amqp/helper.ex Co-authored-by: Cristiano Piemontese <[email protected]> * Fix test description Co-authored-by: Enrico Galassi <[email protected]> Co-authored-by: Cristiano Piemontese <[email protected]>
- Loading branch information
1 parent
b286282
commit 4ca8613
Showing
4 changed files
with
158 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
defmodule HelperTest do | ||
use ExUnit.Case | ||
|
||
alias Amqpx.{Channel, Connection, Queue, Exchange, Helper} | ||
|
||
setup do | ||
{:ok, conn} = Connection.open(Application.fetch_env!(:amqpx, :amqp_connection)) | ||
{:ok, chan} = Channel.open(conn) | ||
on_exit(fn -> :ok = Connection.close(conn) end) | ||
{:ok, conn: conn, chan: chan} | ||
end | ||
|
||
test "declare a queue with a bind to an exchange and a dead letter queue with an errored exchange", meta do | ||
queue_name = rand_name() | ||
routing_key_name = rand_name() | ||
exchange_name = rand_name() | ||
|
||
queue_name_errored = "#{queue_name}_errored" | ||
exchange_name_errored = "#{exchange_name}_errored" | ||
|
||
assert :ok = | ||
Helper.declare(meta[:chan], %{ | ||
exchanges: [ | ||
%{name: exchange_name, opts: [durable: true], routing_keys: [routing_key_name], type: :topic} | ||
], | ||
opts: [ | ||
durable: true, | ||
arguments: [ | ||
{"x-dead-letter-exchange", :longstr, exchange_name_errored}, | ||
{"x-dead-letter-routing-key", :longstr, routing_key_name} | ||
] | ||
], | ||
queue: queue_name | ||
}) | ||
|
||
assert :ok = Queue.unbind(meta[:chan], queue_name, exchange_name) | ||
assert :ok = Queue.unbind(meta[:chan], queue_name_errored, exchange_name_errored) | ||
assert :ok = Exchange.delete(meta[:chan], exchange_name) | ||
assert :ok = Exchange.delete(meta[:chan], exchange_name_errored) | ||
assert {:ok, %{message_count: 0}} = Queue.delete(meta[:chan], queue_name) | ||
assert {:ok, %{message_count: 0}} = Queue.delete(meta[:chan], queue_name_errored) | ||
end | ||
|
||
test "configuration without an exchange and with routing key set with correct dead letter queue should not raise an error", | ||
meta do | ||
queue_name = rand_name() | ||
routing_key_name = rand_name() | ||
exchange_name = rand_name() | ||
|
||
queue_name_errored = "#{queue_name}_errored" | ||
|
||
assert :ok = | ||
Helper.declare(meta[:chan], %{ | ||
exchanges: [ | ||
%{name: exchange_name, opts: [durable: true], routing_keys: [routing_key_name], type: :topic} | ||
], | ||
opts: [ | ||
durable: true, | ||
arguments: [ | ||
{"x-dead-letter-exchange", :longstr, ""}, | ||
{"x-dead-letter-routing-key", :longstr, queue_name_errored} | ||
] | ||
], | ||
queue: queue_name | ||
}) | ||
|
||
assert :ok = Queue.unbind(meta[:chan], queue_name, exchange_name) | ||
assert :ok = Exchange.delete(meta[:chan], exchange_name) | ||
assert {:ok, %{message_count: 0}} = Queue.delete(meta[:chan], queue_name) | ||
assert {:ok, %{message_count: 0}} = Queue.delete(meta[:chan], queue_name_errored) | ||
end | ||
|
||
test "bad configuration with dead letter exchange empty and routing key set should raise an error", meta do | ||
queue_name = rand_name() | ||
routing_key_name = rand_name() | ||
exchange_name = rand_name() | ||
|
||
queue_name_errored = "BadDeadLetterQueue" | ||
|
||
assert_raise RuntimeError, | ||
"If x-dead-letter-exchange is an empty string, x-dead-letter-routing-key should be '#{queue_name}_errored' instead of '#{queue_name_errored}'", | ||
fn -> | ||
Helper.declare(meta[:chan], %{ | ||
exchanges: [ | ||
%{name: exchange_name, opts: [durable: true], routing_keys: [routing_key_name], type: :topic} | ||
], | ||
opts: [ | ||
durable: true, | ||
arguments: [ | ||
{"x-dead-letter-exchange", :longstr, ""}, | ||
{"x-dead-letter-routing-key", :longstr, queue_name_errored} | ||
] | ||
], | ||
queue: queue_name | ||
}) | ||
end | ||
end | ||
|
||
test "bad configuration with empty dead letter exchange and routing key should raise an error", meta do | ||
queue_name = rand_name() | ||
routing_key_name = rand_name() | ||
exchange_name = rand_name() | ||
|
||
assert_raise RuntimeError, | ||
"If x-dead-letter-exchange is an empty string, x-dead-letter-routing-key should be '#{queue_name}_errored' instead of ''", | ||
fn -> | ||
Helper.declare(meta[:chan], %{ | ||
exchanges: [ | ||
%{name: exchange_name, opts: [durable: true], routing_keys: [routing_key_name], type: :topic} | ||
], | ||
opts: [ | ||
durable: true, | ||
arguments: [ | ||
{"x-dead-letter-exchange", :longstr, ""}, | ||
{"x-dead-letter-routing-key", :longstr, ""} | ||
] | ||
], | ||
queue: queue_name | ||
}) | ||
end | ||
end | ||
|
||
defp rand_name do | ||
:crypto.strong_rand_bytes(8) |> Base.encode64() | ||
end | ||
end |