0

I have a project with "n" number of microservices module that uses RabbitMQ. Currently, each microservices have their own implementation of RabbitMQ consumer and producer. But I want to abstract and isolate this interaction with RabbitMQ to a common method in an external library so my project is not tightly coupled with RabbitMQ broker - I would want to change it to an ActiveMQ, etc., in the future with relative ease.

The Producer abstraction seems straight forward but how do I achieve Consumer abstraction? I want to be able to call the consumer method with the queue name as an argument from outside/external method and it should return me the message that it received from the given queue name. I have looked into using SpringAmqp @RabbitListener annotation or RabbitTemplate with Message Listener configured, but it looks like I need to first configure the queue name statically. I also tried Java client Channel basicConsume but I could not figure a way out to extract/send the message to an external method using basicConsume.

Any help with a sample example would be greatly appreciated.

Vemai Clan
  • 33
  • 4

1 Answers1

1

Consider using Spring Integration instead of using Spring AMQP directly.

That way, you can easily swap out the inbound/outbound channel adapters with different technologies because the adapters there use a common (spring-messaging) Message<?> abstraction.

but it looks like I need to first configure the queue name statically.

That is not true; the queue name(s) can be populated via properties and/or SpEL expressions.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks for the prompt response, Gary. That is not true; the queue name(s) can be populated via properties and/or SpEL expressions. – Vemai Clan Jul 16 '20 at 17:07
  • I can assure you that is IS true (I wrote the code). See [this test case](https://github.com/spring-projects/spring-amqp/blob/9d6ce0da33989a8b3814154eb629c248d5d84dce/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/annotation/EnableRabbitIntegrationTests.java#L1080-L1083) - `@RabbitListener(queues = "test.#{'${my.queue.suffix:SIMPLE}'.toLowerCase()}"` - results in `test.simple`. – Gary Russell Jul 16 '20 at 19:37
  • I want to pass the queue name as a method argument and populate the queue name in @RabbitListener using this method arg, so my consumer method listens to the queue name that I passed to the method argument. Is this possible with @RabbitListener? How can I achieve this use case? – Vemai Clan Jul 17 '20 at 11:29
  • 1
    You can use the same technique that I used in my answer to [this question](https://stackoverflow.com/questions/53715268/kafka-spring-how-to-create-listeners-dynamically-or-in-a-loop). It was for Kafka instead of RabbitMQ, but it will work the same way. – Gary Russell Jul 17 '20 at 13:31