2

Using the remote procedure call pattern, I need to send an answer to a reply-queue, i.e. I need to send the message to the default exchange with the name of the queue as the routing key.

I am using the SmallRye Reactive Messing RabbitMQ plugin on Quarkus. All channels are defined statically in the configuration files (which is ok), however, due to the way the configuration mechanism works (microprofile config), I cannot use the empty string as a configuration value, which is the name of the default exchange.

It does not help to omit the name of the exchange, as by default the channel name is used.

Is there a way to send a message to the default exchange using the SmallRye RabbitMQ plugin?

Edit: I have no control over the RabbitMQ server.

1 Answers1

0

You should be able to send messages to the default direct RabbitMQ exchange by setting below attributes:

  • exchange.name (set to empty string)
  • exchange.type (set to direct)

Assuming your Reactive Messaging channel is named pets-out, here down a configuration sample:

mp.messaging.outgoing.pets-out.connector=smallrye-rabbitmq
mp.messaging.outgoing.pets-out.exchange.name=
mp.messaging.outgoing.pets-out.exchange.declare=false
mp.messaging.outgoing.pets-out.exchange.type=direct
mp.messaging.outgoing.pets-out.default-routing-key=pets

EDIT

After digging into smallrye-reactive-messaging implementation, I figured out that an empty exchange name will cause a fallback to the channel name as the exchange name.

Hence, there should be no way to send direct messages to the default RabbitMQ exchange.

The alternative solution, neglecting the out-of-the-box offered default exchange would be to

  1. Create a direct exchange without any bound queues and have the Outgoing message handler using a dedicated channel config bound to it:

     mp.messaging.outgoing.pets-out.connector=smallrye-rabbitmq
     mp.messaging.outgoing.pets-out.exchange.name=my-direct
     mp.messaging.outgoing.pets-out.exchange.declare=true
     mp.messaging.outgoing.pets-out.exchange.type=direct
     mp.messaging.outgoing.pets-out.default-routing-key=pets
    
  2. Create an alternate exchange configuration for the my-direct exchange routing messages to the default one. This can be operated on the RabbitMQ broker directly using rabbitmqctl:

     rabbitmqctl set_policy AE "^my-direct$" '{"alternate-exchange":""}' --apply-to exchanges
    
tmarwen
  • 15,750
  • 5
  • 43
  • 62
  • Hi @tmwaren, as far as I know (and I tried it, too) it is not possible to set a config property to the empty string. If you found a way to set the exchange name to the empty string, please let me know! – ReactiveMessenger Jun 21 '22 at 06:25
  • Hi @tmarwen, I misspelt your name in the comment above. – ReactiveMessenger Jun 21 '22 at 06:33
  • Another question @tmarwen: are you using the **amqp** client to communicate with RabbitMQ? If yes, what are the advantages/disadvantages over using the RabbitMQ client? – ReactiveMessenger Jun 21 '22 at 06:51
  • @ReactiveMessenger sorry for spreading confusion. My answer was base don previous experiments where it seems to have used to work. I have updated the answer with an alternate solution (outside Quarkus / SmallRye realms). You should stick with the **rabbitmq** connector as this supports *AMQP 0.9.1* (sorry for the miss-typing) – tmarwen Jun 22 '22 at 12:28
  • no problem, thank you for your comments. I have no control over the RabbitMQ (edited my question), but I will ask them if they would integrate the redirect exchange for me. Although this seems quite hacky, the amount of boilerplate code we can omit when using reactive messaging is worth is, in my opinion. – ReactiveMessenger Jun 23 '22 at 14:50
  • I cannot edit your answer. From trying out in code, an empty exchange name gives an error (because microprofile config treats empty as `null`). However if you do not define the exchange name, then it is treated as `Optional.Empty` and will be replaced the channel name. With this edit, I would like to accept your answer. – ReactiveMessenger Jul 06 '22 at 09:05