Reputation: 43
I have a simple spring-boot application with a rabbit sender and a receiver. I want to write some receiver tests where I am running a rabbitmq docker instance as Junit Class Rule (RabbitContainerRule)and then sending a message using rabbitTemplate and the test verifies if the receiver receives the same message. But I am getting the following exception:
Caused by: org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.amqp.rabbit.config.internalRabbitListenerEndpointRegistry'; nested exception is org.springframework.amqp.AmqpIllegalStateException: Fatal exception on listener startup
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178)
Caused by: org.springframework.amqp.rabbit.listener.QueuesNotAvailableException: Cannot prepare queue for listener. Either the queue doesn't exist or the broker will not allow us to use it.
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:599)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1424)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'my-message-queue' in vhost '/', class-id=50, method-id=10)
at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
If I create the queue manually(by stopping at a breakpoint) in the docker instance using admin console, my test passes.
Also, if I test it manually using the docker rabbit instance, my spring boot application creates queue successfully. So what is causing it to not create in the test?
I am using spring-amqp 1.7.4 RELEASE
Receiver code:
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "my-message-queue", durable = "true",
arguments = {
@Argument(name = "x-dead-letter-exchange", value = "my-message-exchange-dead-letter"),
@Argument(name = "x-dead-letter-routing-key", value = "my-message-queue")}),
exchange = @Exchange(value = "my-message-exchange", type = "topic", durable = "true"),
key = "my-message-rk")
)
public void handleMessage(MyMessage message) {
MESSAGE_LOG.info("Receiving message: " + message);
}
Also I am not creating any @Bean for my-message-queue in Configurations and rely on @RabbitListener to create one for me. But I am creating ConnectionFactory, RabbitTemplate and SimpleRabbitListenerContainerFactory beans in my config.
Upvotes: 4
Views: 18325
Reputation: 1561
The class where you are building your queues should be annotated with @Configuration annotation, otherwise, spring will not be able to create the queues at the time of start up
Upvotes: 0
Reputation: 121552
The @EnableRabbit
is necessary on some @Configuration
class to let your application context to parse @RabbitListener
.
To let the application to create queues and exchanges and bindings between them automatically, and the RabbitAdmin
bean must be present in the configuration.
See Reference Manual for more information: https://docs.spring.io/spring-amqp/docs/2.0.0.RELEASE/reference/html/
Upvotes: 4