Bluelock / camel-spring-amqp

Spring AMQP Component for Apache Camel
61 stars 54 forks source link

Exchange-Queue binding not getting created #70

Open abhijitkottur opened 6 years ago

abhijitkottur commented 6 years ago

Thank you for the library. I am trying to produce a message to RabbitMQ with Camel on Spring Boot. The destination endpoint I am trying to use is

spring-amqp:myExchange:myQueue:myRoutingKey

I get the following logs when I run the route:

[Camel (camel-1) thread #1 - JmsConsumer[abc]] INFO  amqp.spring.camel.component.SpringAMQPEndpoint - Creating endpoint for myExchange:myQueue:myRoutingKey
[Camel (camel-1) thread #1 - JmsConsumer[abc]] INFO  amqp.spring.camel.component.SpringAMQPProducer - Declaring exchange myExchange of type DirectExchange

But the binding to the queue is not getting created and thus the message is getting lost. If I create the queue and the binding to the exchange manually and then fire a message, it works seamlessly.

Is there something wrong with the syntax of the endpoint that I have used? Please provide a sample endpoint for my use case.

drasil commented 6 years ago

There is nothing wrong.

For producers, the library creates only the target exchange. This is sufficient for producers to publish messages to the broker. It is up to consumers to (create and) subscribe their queues to the exchange with a binding of choice.

For consumers, the library creates exchange, queue and binding. Conceptually, exchanges should be created for producers. But without an exchange consumers cannot bind their queues. That is why exchanges are created also for consumers, hoping that someone will publish messages there. The queue and binding are then needed for filtering the published messages and retrieving them from the broker.

Summarizing - if you want to have your queue and binding created, you can (1) declare the whole setup manually in RabbitMQ administration beforehand or (2) do it explicitly in your code or (3) declare an appropriate consumer.

abhijitkottur commented 6 years ago

@drasil Thank you for the reply. If we use the native rabbitmq client provided by camel the exchanges, bindings and the queues get created by the producer. Please refer: http://camel.apache.org/rabbitmq.html

Regardless, if I have to take the option 2, do you mean I have to get these the queues and bindings created the non-camel way and then kick-off the route?

drasil commented 6 years ago

Creating broker resources for producers/consumers is up to each library. There is no standard for this.

By option 2, I mean using the capabilities of the Spring AMQP library. The exact way depends on the way you write your Spring code - either with Java sources or with XML descriptors. See https://docs.spring.io/spring-amqp/reference/htmlsingle/#broker-configuration for details and examples.

deckerego commented 6 years ago

Camel does take a very opinionated view of AMQP, making it almost like JMS in several approaches. While those conventions may make it easier, it does violate some best practices when it comes to publishing using AMQP and microservices in general.

So I agree with @drasil - producers should fire and forget, not having to worry about discovery to find consumers. In this way the AMQP broker works as a discovery mechanism - the consumers register as consumers, the publishes send messages to exchanges, and the broker is responsible for the matchmaking.