user3908406
user3908406

Reputation: 1786

Spring AMQP: RabbitAdmin unable to recreate queue when it was manually deleted

I have the following code which declares a queue test-amqp-queue. When I run this code initially, it can automatically create the queue.

CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setHost(host);
connectionFactory.setPort(port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.NONE);
connectionFactory.setPublisherReturns(false);

SimpleMessageListenerContainer rabbitContainer = new SimpleMessageListenerContainer(connectionFactory);

RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitAdmin.setAutoStartup(true);

rabbitContainer.setDeclarationRetries(Integer.MAX_VALUE);
rabbitContainer.setRetryDeclarationInterval(30000);

rabbitAdmin.declareQueue(new Queue("test-amqp-queue"));
rabbitContainer.start();

However, when I delete the queue on the rabbitmq console. I got below log keep popping up

WARN 19354 --- [cTaskExecutor-2] o.s.a.r.listener.BlockingQueueConsumer   : Failed to declare queue: test-amqp-queue
WARN 19354 --- [cTaskExecutor-2] o.s.a.r.listener.BlockingQueueConsumer   : Queue declaration failed; retries left=2147483636

org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[test-amqp-queue]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:743) ~[spring-rabbit-2.4.1.jar:2.4.1]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.passiveDeclarations(BlockingQueueConsumer.java:620) ~[spring-rabbit-2.4.1.jar:2.4.1]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:607) ~[spring-rabbit-2.4.1.jar:2.4.1]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1350) ~[spring-rabbit-2.4.1.jar:2.4.1]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1195) ~[spring-rabbit-2.4.1.jar:2.4.1]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.io.IOException: null
    at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:129) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:125) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:147) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:1012) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:46) ~[amqp-client-5.13.1.jar:5.13.1]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:1157) ~[spring-rabbit-2.4.1.jar:2.4.1]
    at jdk.proxy2/jdk.proxy2.$Proxy133.queueDeclarePassive(Unknown Source) ~[na:na]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:721) ~[spring-rabbit-2.4.1.jar:2.4.1]
    ... 5 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'test-amqp-queue' in vhost '/', class-id=50, method-id=10)
    at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:502) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:293) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:141) ~[amqp-client-5.13.1.jar:5.13.1]
    ... 14 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'test-amqp-queue' in vhost '/', class-id=50, method-id=10)
    at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:517) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:341) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:182) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:114) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:739) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQConnection.access$300(AMQConnection.java:47) ~[amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:666) ~[amqp-client-5.13.1.jar:5.13.1]
    ... 1 common frames omitted

It keeps retrying but keep failing. It seems like it only does passive declaration, if no queue found it will throw error instead of creating it.

If I manually add the queue back in the rabbitmq console, it will start working. Or if I restart the problem, the queue will be automatically created.

The user has all permissions.

Any idea why spring-amqp only auto create queue during initialization, but not when queue is deleted afterward?

Upvotes: 0

Views: 1904

Answers (1)

Gary Russell
Gary Russell

Reputation: 174494

You need to add the connection factory, RabbitAdmin and queue as @Beans.

The admin will create the queue automatically when a connection is opened (it looks for queues, exchanges, bindings in the application context).

Even then, deleting the queue manually will not cause it to be recreated, unless you also cause the connection to close - either from the management console, or resetting the connection factory.

The admin always does the declarations whenever a new connection is opened.

The listener container only does passive declaration, to check the queue is present, because it doesn't know the other properties of the queue (durable, exclusive, arguments, etc).

https://docs.spring.io/spring-amqp/docs/current/reference/html/#broker-configuration

Upvotes: 1

Related Questions