8

I'm working on a Java application which uses Spring Boot version 2.0.4.RELEASE and RabbitMQ version 3.7.7. The app is caching all the messages from the RabbitMQ in Redis database and has to resend when a new Queue is created in RabbitMQ. Currently, I managed to capture the Queue creation using Event Exchange Plugin and also the Queue name. I am using AMQP outbound adapter to send the messages back to RabbitMQ.

OutFlow

public IntegrationFlow outFlow(AmqpTemplate amqpTemplate) {
    return IntegrationFlows.from(outputChannel())
            .handle(Amqp.outboundAdapter(amqpTemplate)
                    .routingKeyExpression("headers.routingKey")
                    .exchangeNameExpression("headers.exchange"))
            .get();
}

I can send the messages to specific exchange with the routingKey. But, I don't know how to configure the Queue name in the outbound adapter. So that I can send the message to that specific Queue.

Vimal David
  • 555
  • 2
  • 7
  • 20
  • 1
    IIRC, mapping routingKeys to queues is something that you configure in the RabbitMQ server, not in the sender... So the sender only needs to know what the proper routingKey is they should use, and the actual queue is hidden "behind" the exchange ... – moilejter Aug 20 '18 at 17:53
  • yes, the sender only needs to know 'routingKey' and 'exchangeName'. In my scenario, I need to send to a specific Queue, rather than all Queues linked to that particular exchange. If possible I am happy to send the messages straight to the Queue bypassing the exchange. – Vimal David Aug 20 '18 at 18:47
  • But you can configure the RabbitMQ exchange to "know" to route a particular routingKey to a specific queue - then your client, by choosing the right routingKey, would see its messages end up in the right queue... – moilejter Aug 20 '18 at 20:34
  • Yes, we could bind the exchange to the Queue using 'routingKey'. Unfortunately, my specification asked not to create Queues in prior. So a new Queue is created by RabbitMQ when a new client connects and subscribe to the message. So there could be multiple Queues bind to one exchange. But, When a new Queue is created I want to send messages to that particular Queue, rather than all Queues bind to that exchange. – Vimal David Aug 20 '18 at 21:03
  • It's something similar to this Question https://stackoverflow.com/questions/43408096/springamqp-rabbitmq-how-to-send-directly-to-queue-without-exchange Instead of RabbitTemplate, I am using Spring DSL AMQP outbound adapter – Vimal David Aug 20 '18 at 21:04
  • 1
    Don't you just want to create a routing key for each queue, as you register them, then somehow share those keys with all clients? That way, they would use the right routing key for the right queue, and the exchange would deliver it to the corresponding queue? – moilejter Aug 20 '18 at 22:36
  • yes, we are already doing this for the sending the messages. The scenario we got now is to send the cached messages. The producer will send the messages to RabbitMQ and they are cached. It will cache all the messages. On the other side, we got an MQTT client. when the client makes a new connection it creates a new Queue. So we have to filter the cached messages based on routingKey and send it to the Queue bypassing the exchange. – Vimal David Aug 21 '18 at 14:04
  • @VimalDavid, please take a look at this answer: https://stackoverflow.com/questions/18531308/rabbitmq-how-to-specify-the-queue-to-publish-to – Rod Sep 12 '18 at 13:19
  • Thanks, @Rod After reading the answer I can understand producer never sends any messages directly to a queue. But, we had a typical requirement to send the messages to a particular Queue. The Cache service has multiple consumers with each individual Queue and the Cache messaged need to be sent to a particular Consumer. This following StackOverflow question is also insisting the same answer https://stackoverflow.com/questions/17766928/dynamically-selecting-a-rabbitmq-queue-in-exchange-using-spring-integration?rq=1 – Vimal David Sep 12 '18 at 13:32
  • @VimalDavid, but according to the answer I linked there is a workaround that makes it possible to do excatly what you want. I didn't test it yet though... it states: "Each queue is automatically bound to the AMQP default exchange, with the queue's name as the routing key. The default exchange is also known as the "nameless exchange" - ie its name is the empty string. So if you publish to the exchange named "" with routing key equal to your queue's name, the message will go to just that queue. " – Rod Sep 12 '18 at 14:22
  • @Rob Yes, we tried that implementation. Sending messages using default exchange will replace the 'routing_key' value in the message with Queue name. In our Scenario, we have to retain the 'routing_key' in the message. In the consumer end, we got multiple MQTT clients which filter the messages using 'routing_key'. – Vimal David Sep 13 '18 at 10:21

1 Answers1

0

If you want to send to the specific queue, use the queue name for the routing key and default global exchange - empty name. There is one special direct exchange which has all the queue bound to it by their names as routing keys.

See AMQP protocol docs for more info: https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118