Search in sources :

Example 1 with RecordedBinding

use of com.rabbitmq.client.impl.recovery.RecordedBinding in project rabbitmq-java-client by rabbitmq.

the class TopologyRecoveryRetry method topologyRecoveryBindingFailure.

@Test
public void topologyRecoveryBindingFailure() throws Exception {
    final String queue = "topology-recovery-retry-binding-failure" + System.currentTimeMillis();
    channel.queueDeclare(queue, false, false, true, new HashMap<>());
    channel.queueBind(queue, "amq.topic", "topic1");
    channel.queueBind(queue, "amq.topic", "topic2");
    final CountDownLatch messagesReceivedLatch = new CountDownLatch(2);
    channel.basicConsume(queue, true, new DefaultConsumer(channel) {

        @Override
        public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body) {
            messagesReceivedLatch.countDown();
        }
    });
    final CountDownLatch recoveryLatch = new CountDownLatch(1);
    ((AutorecoveringConnection) connection).addRecoveryListener(new RecoveryListener() {

        @Override
        public void handleRecoveryStarted(Recoverable recoverable) {
        // no-op
        }

        @Override
        public void handleRecovery(Recoverable recoverable) {
            recoveryLatch.countDown();
        }
    });
    // we want recovery to fail when recovering the 2nd binding
    // give the 2nd recorded binding a bad queue name so it fails
    final RecordedBinding binding2 = ((AutorecoveringConnection) connection).getRecordedBindings().get(1);
    binding2.destination(UUID.randomUUID().toString());
    // use the backoffConsumer to know that it has failed
    // then delete the real queue & fix the recorded binding
    // it should fail once more because queue is gone, and then succeed
    final CountDownLatch backoffLatch = new CountDownLatch(1);
    backoffConsumer = attempt -> {
        if (attempt == 1) {
            binding2.destination(queue);
            try {
                Host.rabbitmqctl("delete_queue " + queue);
                Thread.sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        backoffLatch.countDown();
    };
    // close connection
    Host.closeAllConnections();
    // assert backoff was called
    assertTrue(backoffLatch.await(90, TimeUnit.SECONDS));
    // wait for full recovery
    assertTrue(recoveryLatch.await(90, TimeUnit.SECONDS));
    // publish messages to verify both bindings were recovered
    basicPublishVolatile("test1".getBytes(), "amq.topic", "topic1");
    basicPublishVolatile("test2".getBytes(), "amq.topic", "topic2");
    assertTrue(messagesReceivedLatch.await(10, TimeUnit.SECONDS));
}
Also used : DefaultConsumer(com.rabbitmq.client.DefaultConsumer) BasicProperties(com.rabbitmq.client.AMQP.BasicProperties) RecordedBinding(com.rabbitmq.client.impl.recovery.RecordedBinding) CountDownLatch(java.util.concurrent.CountDownLatch) Envelope(com.rabbitmq.client.Envelope) IOException(java.io.IOException) RecoveryListener(com.rabbitmq.client.RecoveryListener) AutorecoveringConnection(com.rabbitmq.client.impl.recovery.AutorecoveringConnection) Recoverable(com.rabbitmq.client.Recoverable) Test(org.junit.Test)

Aggregations

BasicProperties (com.rabbitmq.client.AMQP.BasicProperties)1 DefaultConsumer (com.rabbitmq.client.DefaultConsumer)1 Envelope (com.rabbitmq.client.Envelope)1 Recoverable (com.rabbitmq.client.Recoverable)1 RecoveryListener (com.rabbitmq.client.RecoveryListener)1 AutorecoveringConnection (com.rabbitmq.client.impl.recovery.AutorecoveringConnection)1 RecordedBinding (com.rabbitmq.client.impl.recovery.RecordedBinding)1 IOException (java.io.IOException)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 Test (org.junit.Test)1