1

I'm currently working on a rabbit-amqp implementation project and use spring-rabbit to programmatically setup all my queues, bindings and exchanges.

I'm trying to recreate an queue if it was deleted and found the following in the reference documentation :

3.14 Listener Container Queues

Version 1.3 introduced a number of improvements for handling multiple queues in a listener container.

The container must be configured to listen on at least one queue; this was the case previously too, but now queues can be added and removed at runtime. The container will recycle (cancel and re-create) the consumers when any pre-fetched messages have been processed. See methods addQueues, addQueueNames, removeQueues and removeQueueNames. When removing queues, at least one queue must remain.

A consumer will now start if any of its queues are available - previously the container would stop if any queues were unavailable. Now, this is only the case if none of the queues are available. If not all queues are available, the container will attempt to passively declare (and consume from) the missing queue(s) every 60 seconds. ... (source: http://docs.spring.io/spring-amqp/docs/1.3.4.RELEASE/reference/html was down during the time of writing)

I tried this scenario and indeed my queues are recreated, but the bindings between the queues and exchanges are lost. How can I recreate my queues with their bindings after they have been deleted?

Community
  • 1
  • 1
JustinV
  • 165
  • 1
  • 6

1 Answers1

1

Actually it should work, if all your declarations (Queue, Exchange, Binding) are registered as beans.

On each queuesChanged() SimpleMessageListenerContainer invokes rabbitAdmin.initialize(), who, in turn, gets deal with mentioned RabbitMQ environment.

It happens only in this case:

if (queueNames.contains(queue.getName()) && queue.isAutoDelete()
                        && this.rabbitAdmin.getQueueProperties(queue.getName()) == null) {

If the Queue from application context contains in the current queueNames, it is auto-delete and it doesn't exist on Broker (rabbitAdmin.getQueueProperties) tries to connect to Broker to get info about Queue.

UPDATE

Right, of course, the queue is deleted, when there is no consumer.

Looks like you are right regarding x-expires(Queue TTL) and we should get deal with that, too:

if (queueNames.contains(queue.getName())
          && (queue.isAutoDelete() || queue.getArguments().containsKey("x-expires")))
      && this.rabbitAdmin.getQueueProperties(queue.getName()) == null) {

Feel free to raise a JIRA issue: https://jira.spring.io/browse/AMQP

Thank you for pointing it out - +1

Community
  • 1
  • 1
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • but this requires the queue to be autoDelete. As far as I know this means that if no consumer is connected to the queue it will be automatically destroyed and will delete any messages in the queue. Can this be also achieved with x-expires argument on a queue? – JustinV Jun 16 '14 at 08:48
  • Bear in mind that checking the `x-expires` argument is not enough; a queue can be expired when using a [server side policy] (http://www.rabbitmq.com/ttl.html) too. Maybe we should always redeclare when each consumer starts, just in case. That said, this seems to be a rare corner case, where the application context is running, with the container stopped for at least the expiry time. The queue will be declared by the admin when the context is initialized. Can you describe your use case? – Gary Russell Jun 16 '14 at 12:40
  • Gary, I think this question is related: http://stackoverflow.com/questions/24241880/dynamically-add-new-queues-bindings-and-exchanges-as-beans – Artem Bilan Jun 16 '14 at 12:46
  • GaryRussell I didn't want a auto-delete queue because that clears all messages from my queues if services are being restarted and are back within a certain amount of time (lets say 1min). And if the duration is passed and consumers are back and but the queues are missing/deleted I would like them to be recreated. – JustinV Jun 16 '14 at 15:55