vert-x3/vertx-rabbitmq-client

queueDeclare fails when queue TTL is set

jacek-wojciechowski-dell opened this issue · 1 comments

I'm experiencing the following issue with 3.5.1:
This code:

JsonObject config = new JsonObject();
config.put("x-message-ttl", 5000L);
rabbitClient.queueDeclare(queueName, isQueueDurable(), false, false, config, result -> {
// the result is failed

Returns the exception as result.cause():

java.io.IOException: null
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105)
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:123)
	at com.rabbitmq.client.impl.ChannelN.queueDeclare(ChannelN.java:843)
	at com.rabbitmq.client.impl.recovery.AutorecoveringChannel.queueDeclare(AutorecoveringChannel.java:281)
	at io.vertx.rabbitmq.impl.RabbitMQClientImpl.lambda$queueDeclare$17(RabbitMQClientImpl.java:322)
	at io.vertx.rabbitmq.impl.RabbitMQClientImpl.lambda$forChannel$26(RabbitMQClientImpl.java:429)
	at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:273)
	at io.vertx.core.impl.TaskQueue.run(TaskQueue.java:76)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-message-ttl' for queue 'storage.states.save.retries.5000' in vhost '/workers': received the value '5000' of type 'long' but current is none, class-id=50, method-id=10)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:32)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:360)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:225)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:117)
	... 10 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-message-ttl' for queue 'storage.states.save.retries.5000' in vhost '/workers': received the value '5000' of type 'long' but current is none, class-id=50, method-id=10)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:483)
	at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:320)
	at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:143)
	at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:90)
	at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:559)
	... 1 common frames omitted

The actual error message seems to be:
#method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-message-ttl' for queue 'storage.states.save.retries.5000' in vhost '/workers': received the value '5000' of type 'long' but current is none, class-id=50, method-id=10)

When I remove the following: config.put("x-message-ttl", 5000L); the code works.

Please also notice that a similar code can be found in the docs: https://vertx.io/docs/vertx-rabbitmq-client/java/#_declare_queue_with_additional_config :

JsonObject config = new JsonObject();
config.put("x-message-ttl", 10_000L);

client.queueDeclare("my-queue", true, false, true, config, queueResult -> {
  if (queueResult.succeeded()) {
    System.out.println("Queue declared!");
  } else {
    System.err.println("Queue failed to be declared!");
    queueResult.cause().printStackTrace();
  }
});

I'm aware that I can also set up TTL on messages directly but I cannot use it in my code (it's a long story)

Can you take a look at this please?

I think you'll find that the queue already exists and currently has no TTL.
You cannot change many of the configuration aspects of a queue (or any other object) when declaring it if it already exists.