Search in sources :

Example 1 with RabbitBindingCleaner

use of org.springframework.cloud.stream.binder.rabbit.admin.RabbitBindingCleaner in project spring-cloud-stream by spring-cloud.

the class RabbitBinderCleanerTests method testCleanStream.

@Test
public void testCleanStream() {
    final RabbitBindingCleaner cleaner = new RabbitBindingCleaner();
    final String stream1 = new Base64UrlNamingStrategy("foo").generateName();
    String stream2 = stream1 + "-1";
    String firstQueue = null;
    CachingConnectionFactory connectionFactory = rabbitTestSupport.getResource();
    RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
    for (int i = 0; i < 5; i++) {
        String queue1Name = AbstractBinder.applyPrefix(BINDER_PREFIX, stream1 + ".default." + i);
        String queue2Name = AbstractBinder.applyPrefix(BINDER_PREFIX, stream2 + ".default." + i);
        if (firstQueue == null) {
            firstQueue = queue1Name;
        }
        rabbitAdmin.declareQueue(new Queue(queue1Name, true, false, false));
        rabbitAdmin.declareQueue(new Queue(queue2Name, true, false, false));
        rabbitAdmin.declareQueue(new Queue(AbstractBinder.constructDLQName(queue1Name), true, false, false));
        TopicExchange exchange = new TopicExchange(queue1Name);
        rabbitAdmin.declareExchange(exchange);
        rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(queue1Name)).to(exchange).with(queue1Name));
        exchange = new TopicExchange(queue2Name);
        rabbitAdmin.declareExchange(exchange);
        rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(queue2Name)).to(exchange).with(queue2Name));
    }
    final TopicExchange topic1 = new TopicExchange(AbstractBinder.applyPrefix(BINDER_PREFIX, stream1 + ".foo.bar"));
    rabbitAdmin.declareExchange(topic1);
    rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(firstQueue)).to(topic1).with("#"));
    String foreignQueue = UUID.randomUUID().toString();
    rabbitAdmin.declareQueue(new Queue(foreignQueue));
    rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(foreignQueue)).to(topic1).with("#"));
    final TopicExchange topic2 = new TopicExchange(AbstractBinder.applyPrefix(BINDER_PREFIX, stream2 + ".foo.bar"));
    rabbitAdmin.declareExchange(topic2);
    rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(firstQueue)).to(topic2).with("#"));
    new RabbitTemplate(connectionFactory).execute(new ChannelCallback<Void>() {

        @Override
        public Void doInRabbit(Channel channel) throws Exception {
            String queueName = AbstractBinder.applyPrefix(BINDER_PREFIX, stream1 + ".default." + 4);
            String consumerTag = channel.basicConsume(queueName, new DefaultConsumer(channel));
            try {
                waitForConsumerStateNot(queueName, 0);
                doClean(cleaner, stream1, false);
                fail("Expected exception");
            } catch (RabbitAdminException e) {
                assertThat(e).hasMessageContaining("Queue " + queueName + " is in use");
            }
            channel.basicCancel(consumerTag);
            waitForConsumerStateNot(queueName, 1);
            try {
                doClean(cleaner, stream1, false);
                fail("Expected exception");
            } catch (RabbitAdminException e) {
                assertThat(e).hasMessageContaining("Cannot delete exchange ");
                assertThat(e).hasMessageContaining("; it has bindings:");
            }
            return null;
        }

        private void waitForConsumerStateNot(String queueName, long state) throws InterruptedException {
            int n = 0;
            QueueInfo queue = client.getQueue("/", queueName);
            while (n++ < 100 && (queue == null || queue.getConsumerCount() == state)) {
                Thread.sleep(100);
                queue = client.getQueue("/", queueName);
            }
            assertThat(n).withFailMessage("Consumer state remained at " + state + " after 10 seconds").isLessThan(100);
        }
    });
    // easier than deleting the binding
    rabbitAdmin.deleteExchange(topic1.getName());
    rabbitAdmin.declareExchange(topic1);
    rabbitAdmin.deleteQueue(foreignQueue);
    connectionFactory.destroy();
    Map<String, List<String>> cleanedMap = doClean(cleaner, stream1, false);
    assertThat(cleanedMap).hasSize(2);
    List<String> cleanedQueues = cleanedMap.get("queues");
    // should *not* clean stream2
    assertThat(cleanedQueues).hasSize(10);
    for (int i = 0; i < 5; i++) {
        assertThat(cleanedQueues.get(i * 2)).isEqualTo(BINDER_PREFIX + stream1 + ".default." + i);
        assertThat(cleanedQueues.get(i * 2 + 1)).isEqualTo(BINDER_PREFIX + stream1 + ".default." + i + ".dlq");
    }
    List<String> cleanedExchanges = cleanedMap.get("exchanges");
    assertThat(cleanedExchanges).hasSize(6);
    // wild card *should* clean stream2
    cleanedMap = doClean(cleaner, stream1 + "*", false);
    assertThat(cleanedMap).hasSize(2);
    cleanedQueues = cleanedMap.get("queues");
    assertThat(cleanedQueues).hasSize(5);
    for (int i = 0; i < 5; i++) {
        assertThat(cleanedQueues.get(i)).isEqualTo(BINDER_PREFIX + stream2 + ".default." + i);
    }
    cleanedExchanges = cleanedMap.get("exchanges");
    assertThat(cleanedExchanges).hasSize(6);
}
Also used : RabbitTemplate(org.springframework.amqp.rabbit.core.RabbitTemplate) QueueInfo(com.rabbitmq.http.client.domain.QueueInfo) DefaultConsumer(com.rabbitmq.client.DefaultConsumer) Channel(com.rabbitmq.client.Channel) RabbitAdmin(org.springframework.amqp.rabbit.core.RabbitAdmin) RabbitBindingCleaner(org.springframework.cloud.stream.binder.rabbit.admin.RabbitBindingCleaner) URISyntaxException(java.net.URISyntaxException) MalformedURLException(java.net.MalformedURLException) RabbitAdminException(org.springframework.cloud.stream.binder.rabbit.admin.RabbitAdminException) TopicExchange(org.springframework.amqp.core.TopicExchange) Base64UrlNamingStrategy(org.springframework.amqp.core.Base64UrlNamingStrategy) CachingConnectionFactory(org.springframework.amqp.rabbit.connection.CachingConnectionFactory) List(java.util.List) Queue(org.springframework.amqp.core.Queue) RabbitAdminException(org.springframework.cloud.stream.binder.rabbit.admin.RabbitAdminException) Test(org.junit.jupiter.api.Test)

Aggregations

Channel (com.rabbitmq.client.Channel)1 DefaultConsumer (com.rabbitmq.client.DefaultConsumer)1 QueueInfo (com.rabbitmq.http.client.domain.QueueInfo)1 MalformedURLException (java.net.MalformedURLException)1 URISyntaxException (java.net.URISyntaxException)1 List (java.util.List)1 Test (org.junit.jupiter.api.Test)1 Base64UrlNamingStrategy (org.springframework.amqp.core.Base64UrlNamingStrategy)1 Queue (org.springframework.amqp.core.Queue)1 TopicExchange (org.springframework.amqp.core.TopicExchange)1 CachingConnectionFactory (org.springframework.amqp.rabbit.connection.CachingConnectionFactory)1 RabbitAdmin (org.springframework.amqp.rabbit.core.RabbitAdmin)1 RabbitTemplate (org.springframework.amqp.rabbit.core.RabbitTemplate)1 RabbitAdminException (org.springframework.cloud.stream.binder.rabbit.admin.RabbitAdminException)1 RabbitBindingCleaner (org.springframework.cloud.stream.binder.rabbit.admin.RabbitBindingCleaner)1