org.springframework.amqp.rabbit.connection.RoutingConnectionFactoryTests.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.amqp.rabbit.connection.RoutingConnectionFactoryTests.java

Source

/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.amqp.rabbit.connection;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import org.junit.Test;
import org.mockito.Mockito;

import org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;

import com.rabbitmq.client.Channel;

/**
 * @author Artem Bilan
 * @author Josh Chappelle
 * @author Gary Russell
 * @since 1.3
 */
public class RoutingConnectionFactoryTests {

    @Test
    public void testAbstractRoutingConnectionFactory() {
        ConnectionFactory connectionFactory1 = Mockito.mock(ConnectionFactory.class);
        ConnectionFactory connectionFactory2 = Mockito.mock(ConnectionFactory.class);
        Map<Object, ConnectionFactory> factories = new HashMap<Object, ConnectionFactory>(2);
        factories.put(Boolean.TRUE, connectionFactory1);
        factories.put(Boolean.FALSE, connectionFactory2);
        ConnectionFactory defaultConnectionFactory = Mockito.mock(ConnectionFactory.class);

        final AtomicBoolean lookupFlag = new AtomicBoolean(true);
        final AtomicInteger count = new AtomicInteger();

        AbstractRoutingConnectionFactory connectionFactory = new AbstractRoutingConnectionFactory() {

            @Override
            protected Object determineCurrentLookupKey() {
                return count.incrementAndGet() > 3 ? null : lookupFlag.getAndSet(!lookupFlag.get());
            }
        };

        connectionFactory.setDefaultTargetConnectionFactory(defaultConnectionFactory);
        connectionFactory.setTargetConnectionFactories(factories);

        for (int i = 0; i < 5; i++) {
            connectionFactory.createConnection();
        }

        verify(connectionFactory1, times(2)).createConnection();
        verify(connectionFactory2).createConnection();
        verify(defaultConnectionFactory, times(2)).createConnection();
    }

    @Test
    public void testSimpleRoutingConnectionFactory() throws InterruptedException {
        ConnectionFactory connectionFactory1 = Mockito.mock(ConnectionFactory.class);
        ConnectionFactory connectionFactory2 = Mockito.mock(ConnectionFactory.class);
        Map<Object, ConnectionFactory> factories = new HashMap<Object, ConnectionFactory>(2);
        factories.put("foo", connectionFactory1);
        factories.put("bar", connectionFactory2);

        final AbstractRoutingConnectionFactory connectionFactory = new SimpleRoutingConnectionFactory();
        connectionFactory.setTargetConnectionFactories(factories);

        ExecutorService executorService = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 3; i++) {
            final AtomicInteger count = new AtomicInteger(i);
            executorService.execute(() -> {
                SimpleResourceHolder.bind(connectionFactory, count.get() % 2 == 0 ? "foo" : "bar");
                connectionFactory.createConnection();
                SimpleResourceHolder.unbind(connectionFactory);
            });
        }

        executorService.shutdown();
        assertTrue(executorService.awaitTermination(10, TimeUnit.SECONDS));

        verify(connectionFactory1, times(2)).createConnection();
        verify(connectionFactory2).createConnection();
    }

    @Test
    public void testGetAddAndRemoveOperationsForTargetConnectionFactories() {
        ConnectionFactory targetConnectionFactory = Mockito.mock(ConnectionFactory.class);

        AbstractRoutingConnectionFactory routingFactory = new AbstractRoutingConnectionFactory() {
            @Override
            protected Object determineCurrentLookupKey() {
                return null;
            }
        };

        //Make sure map is initialized and doesn't contain lookup key "1"
        assertNull(routingFactory.getTargetConnectionFactory("1"));

        //Add one and make sure it's there
        routingFactory.addTargetConnectionFactory("1", targetConnectionFactory);
        assertEquals(targetConnectionFactory, routingFactory.getTargetConnectionFactory("1"));
        assertNull(routingFactory.getTargetConnectionFactory("2"));

        //Remove it and make sure it's gone
        ConnectionFactory removedConnectionFactory = routingFactory.removeTargetConnectionFactory("1");
        assertEquals(targetConnectionFactory, removedConnectionFactory);
        assertNull(routingFactory.getTargetConnectionFactory("1"));
    }

    @Test
    public void testAddTargetConnectionFactoryAddsExistingConnectionListenersToConnectionFactory() {

        AbstractRoutingConnectionFactory routingFactory = new AbstractRoutingConnectionFactory() {
            @Override
            protected Object determineCurrentLookupKey() {
                return null;
            }
        };
        routingFactory.addConnectionListener(Mockito.mock(ConnectionListener.class));
        routingFactory.addConnectionListener(Mockito.mock(ConnectionListener.class));

        ConnectionFactory targetConnectionFactory = Mockito.mock(ConnectionFactory.class);
        routingFactory.addTargetConnectionFactory("1", targetConnectionFactory);
        verify(targetConnectionFactory, times(2)).addConnectionListener(any(ConnectionListener.class));
    }

    @Test
    public void testAbstractRoutingConnectionFactoryWithListenerContainer() {
        ConnectionFactory connectionFactory1 = mock(ConnectionFactory.class);
        ConnectionFactory connectionFactory2 = mock(ConnectionFactory.class);
        Map<Object, ConnectionFactory> factories = new HashMap<Object, ConnectionFactory>(2);
        factories.put("[baz]", connectionFactory1);
        factories.put("[foo,bar]", connectionFactory2);
        ConnectionFactory defaultConnectionFactory = mock(ConnectionFactory.class);

        SimpleRoutingConnectionFactory connectionFactory = new SimpleRoutingConnectionFactory();

        connectionFactory.setDefaultTargetConnectionFactory(defaultConnectionFactory);
        connectionFactory.setTargetConnectionFactories(factories);

        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueueNames("foo, bar");
        container.afterPropertiesSet();
        container.start();

        verify(connectionFactory1, never()).createConnection();
        verify(connectionFactory2).createConnection();
        verify(defaultConnectionFactory, never()).createConnection();

        reset(connectionFactory1, connectionFactory2, defaultConnectionFactory);
        container.setQueueNames("baz");
        verify(connectionFactory1).createConnection();
        verify(connectionFactory2, never()).createConnection();
        verify(defaultConnectionFactory, never()).createConnection();

        reset(connectionFactory1, connectionFactory2, defaultConnectionFactory);
        container.setQueueNames("qux");
        verify(connectionFactory1, never()).createConnection();
        verify(connectionFactory2, never()).createConnection();
        verify(defaultConnectionFactory).createConnection();

        container.stop();
    }

    @Test
    public void testWithSMLCAndConnectionListener() throws Exception {
        ConnectionFactory connectionFactory1 = mock(ConnectionFactory.class);
        Map<Object, ConnectionFactory> factories = new HashMap<Object, ConnectionFactory>(2);
        factories.put("xxx[foo]", connectionFactory1);

        final SimpleRoutingConnectionFactory connectionFactory = new SimpleRoutingConnectionFactory();

        final Connection connection = mock(Connection.class);
        Channel channel = mock(Channel.class);
        given(connection.createChannel(anyBoolean())).willReturn(channel);
        final AtomicReference<Object> connectionMakerKey1 = new AtomicReference<>();
        final CountDownLatch latch = new CountDownLatch(1);
        willAnswer(i -> {
            connectionMakerKey1.set(connectionFactory.determineCurrentLookupKey());
            latch.countDown();
            return connection;
        }).given(connectionFactory1).createConnection();
        connectionFactory.setTargetConnectionFactories(factories);

        final AtomicReference<Object> connectionMakerKey2 = new AtomicReference<>();
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory) {

            @Override
            protected synchronized void redeclareElementsIfNecessary() {
                connectionMakerKey2.set(connectionFactory.determineCurrentLookupKey());
            }

        };
        container.setQueueNames("foo");
        container.setLookupKeyQualifier("xxx");
        container.afterPropertiesSet();
        container.start();
        assertTrue(latch.await(10, TimeUnit.SECONDS));
        container.stop();
        assertThat(connectionMakerKey1.get(), equalTo("xxx[foo]"));
        assertThat(connectionMakerKey2.get(), equalTo("xxx[foo]"));
    }

    @Test
    public void testWithDMLCAndConnectionListener() throws Exception {
        ConnectionFactory connectionFactory1 = mock(ConnectionFactory.class);
        Map<Object, ConnectionFactory> factories = new HashMap<Object, ConnectionFactory>(2);
        factories.put("xxx[foo]", connectionFactory1);

        final SimpleRoutingConnectionFactory connectionFactory = new SimpleRoutingConnectionFactory();

        final Connection connection = mock(Connection.class);
        Channel channel = mock(Channel.class);
        given(connection.createChannel(anyBoolean())).willReturn(channel);
        final AtomicReference<Object> connectionMakerKey = new AtomicReference<>();
        final CountDownLatch latch = new CountDownLatch(1);
        willAnswer(i -> {
            connectionMakerKey.set(connectionFactory.determineCurrentLookupKey());
            latch.countDown();
            return connection;
        }).given(connectionFactory1).createConnection();
        connectionFactory.setTargetConnectionFactories(factories);

        final AtomicReference<Object> connectionMakerKey2 = new AtomicReference<>();
        DirectMessageListenerContainer container = new DirectMessageListenerContainer(connectionFactory) {

            @Override
            protected synchronized void redeclareElementsIfNecessary() {
                connectionMakerKey2.set(connectionFactory.determineCurrentLookupKey());
            }

        };
        container.setQueueNames("foo");
        container.setLookupKeyQualifier("xxx");
        container.setShutdownTimeout(10);
        container.afterPropertiesSet();
        container.start();
        assertTrue(latch.await(10, TimeUnit.SECONDS));
        container.stop();
        assertThat(connectionMakerKey.get(), equalTo("xxx[foo]"));
        assertThat(connectionMakerKey2.get(), equalTo("xxx[foo]"));
    }

}