I'm trying to migrate from camel 3.x to camel 4.x version, so I need to migrate from the rabbitmq
component to the replacing one spring-rabbitmq
. With rabbitmq
component I was using the declare
option to let Camel automatically create and bind queues and exchanges, now I'm looking for equivalent options in the spring-rabbitmq
component:
From the documentation it looks like this is possible : https://camel.apache.org/components/3.20.x/spring-rabbitmq-component.html#_auto_declare_exchanges_queues_and_bindings :
Before you can send or receive messages from RabbitMQ, then exchanges, queues and bindings must be setup first.
In development mode it may be desirable to let Camel automatic do this. You can enable this by setting autoDeclare=true on the SpringRabbitMQComponent.
Then Spring RabbitMQ will automatic necessary declare the elements and setup the binding between the exchange, queue and routing keys.
So I've configured the camel.component.spring-rabbitmq.auto-declare
property to true
in my application.properties
: but it seems that this affects only the rabbitmq consumer endpoints, not the producer.
Using this simple route:
<route id="receive-send-rabbitmq">
<from uri="spring-rabbitmq:in-exchange?queues=queue-in"/>
<log message="message received" />
<to uri="spring-rabbitmq:out-exchange"/>
</route>
The in-exchange
and queue-in
objects are properly auto-declared by Camel when starting the route, messages are properly received. But the sending part is failing due to exchange out-exchange
not available. Stack trace :
2023-07-10T11:54:12.094+02:00 DEBUG 3796 --- [pool-2-thread-5] o.s.amqp.rabbit.core.RabbitTemplate : Publishing message [(Body:'[B@149e60f3(byte[3])' MessageProperties [headers={}, contentType=application/octet-stream, contentLength=3, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])] on exchange [out-exchange], routingKey = []
2023-07-10T11:54:12.099+02:00 INFO 3796 --- [ 127.0.0.1:5672] com.rabbitmq.client.impl.AMQConnection : Received a frame on an unknown channel, ignoring it
2023-07-10T11:54:12.099+02:00 DEBUG 3796 --- [pool-2-thread-5] o.s.amqp.rabbit.connection.RabbitUtils : Unexpected exception on closing RabbitMQ Channel
com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'out-exchange' in vhost '/', class-id=60, method-id=40)
at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36)
at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:502)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'out-exchange' in vhost '/', class-id=60, method-id=40)
at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:517)
at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:341)
at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:182)
at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:114)
at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:743)
at com.rabbitmq.client.impl.AMQConnection.access$300(AMQConnection.java:47)
at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:670)
... 1 common frames omitted
I know I could declare these exchange using the RabbitAdmin but I don't want to handle this manually in my application code, the routes delivered as XML files in a dedicated folder, loaded dynamically by the application at startup.
Using Camel 4.0.0-rc1 with Springboot 3.1.1