net.roboconf.messaging.rabbitmq.internal.utils.RabbitMqUtilsTest.java Source code

Java tutorial

Introduction

Here is the source code for net.roboconf.messaging.rabbitmq.internal.utils.RabbitMqUtilsTest.java

Source

/**
 * Copyright 2014-2017 Linagora, Universit Joseph Fourier, Floralis
 *
 * The present code is developed in the scope of the joint LINAGORA -
 * Universit Joseph Fourier - Floralis research program and is designated
 * as a "Result" pursuant to the terms and conditions of the LINAGORA
 * - Universit Joseph Fourier - Floralis research program. Each copyright
 * holder of Results enumerated here above fully & independently holds complete
 * ownership of the complete Intellectual Property rights applicable to the whole
 * of said Results, and may freely exploit it in any manner which does not infringe
 * the moral rights of the other copyright holders.
 *
 * 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 net.roboconf.messaging.rabbitmq.internal.utils;

import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.EXCHANGE_DM;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.EXCHANGE_INTER_APP;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_SERVER_IP;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_SERVER_PASSWORD;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_SERVER_USERNAME;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_SSL_AS_USER_DATA;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_SSL_KEY_STORE_PASSPHRASE;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_SSL_KEY_STORE_PATH;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_SSL_TRUST_STORE_PASSPHRASE;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_SSL_TRUST_STORE_PATH;
import static net.roboconf.messaging.rabbitmq.RabbitMqConstants.RABBITMQ_USE_SSL;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConnectionFactory;

import net.roboconf.core.utils.Utils;
import net.roboconf.messaging.api.extensions.MessagingContext;
import net.roboconf.messaging.api.extensions.MessagingContext.RecipientKind;
import net.roboconf.messaging.api.extensions.MessagingContext.ThoseThat;
import net.roboconf.messaging.rabbitmq.RabbitMqConstants;

/**
 * @author Vincent Zurczak - Linagora
 */
public class RabbitMqUtilsTest {

    private static boolean rabbitMqIsRunning = false;

    @BeforeClass
    public static void checkRabbitMqIsRunning() throws Exception {
        rabbitMqIsRunning = RabbitMqTestUtils.checkRabbitMqIsRunning();
    }

    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    @Test
    public void testDeclareApplicationExchanges() throws Exception {

        Channel channel = Mockito.mock(Channel.class);
        RabbitMqUtils.declareApplicationExchanges(null, null, channel);
        Mockito.verifyZeroInteractions(channel);

        RabbitMqUtils.declareApplicationExchanges("domain", "te", channel);
        String exchangeName = RabbitMqUtils.buildExchangeNameForAgent("domain", "te");
        Mockito.verify(channel, Mockito.times(1)).exchangeDeclare(exchangeName, "topic");
    }

    @Test
    public void testDeclareGlobalExchanges() throws Exception {

        Channel channel = Mockito.mock(Channel.class);
        RabbitMqUtils.declareGlobalExchanges("d", channel);

        Mockito.verify(channel, Mockito.times(1)).exchangeDeclare("d." + EXCHANGE_DM, "topic");
        Mockito.verify(channel, Mockito.times(1)).exchangeDeclare("d." + EXCHANGE_INTER_APP, "topic");
    }

    @Test
    public void testBuildExchangeNameForAgent() {

        Assert.assertEquals("d1.test.agents", RabbitMqUtils.buildExchangeNameForAgent("d1", "test"));
        Assert.assertEquals("d2.te.agents", RabbitMqUtils.buildExchangeNameForAgent("d2", "te"));
    }

    @Test
    public void testBuildExchangeName() {

        MessagingContext ctx = new MessagingContext(RecipientKind.DM, "domain", "app1");
        Assert.assertEquals("domain." + EXCHANGE_DM, RabbitMqUtils.buildExchangeName(ctx));

        ctx = new MessagingContext(RecipientKind.DM, "domain", "app2");
        Assert.assertEquals("domain." + EXCHANGE_DM, RabbitMqUtils.buildExchangeName(ctx));

        ctx = new MessagingContext(RecipientKind.INTER_APP, "domain", "app1");
        Assert.assertEquals("domain." + EXCHANGE_INTER_APP, RabbitMqUtils.buildExchangeName(ctx));

        ctx = new MessagingContext(RecipientKind.INTER_APP, "domain", "facet", ThoseThat.IMPORT, "app1");
        Assert.assertEquals("domain." + EXCHANGE_INTER_APP, RabbitMqUtils.buildExchangeName(ctx));

        ctx = new MessagingContext(RecipientKind.AGENTS, "domain", "facet", ThoseThat.IMPORT, "app1");
        Assert.assertEquals("domain.app1.agents", RabbitMqUtils.buildExchangeName(ctx));

        ctx = new MessagingContext(RecipientKind.AGENTS, "domain1", "facet", ThoseThat.EXPORT, "app2");
        Assert.assertEquals("domain1.app2.agents", RabbitMqUtils.buildExchangeName(ctx));
    }

    @Test
    public void testConfigureFactory() throws Exception {

        String address = "http://roboconf.net/some/path";
        int port = 18547;
        String username = "toto";
        String password = "123456789";

        ConnectionFactory factory = new ConnectionFactory();
        Assert.assertNotSame(address, factory.getHost());
        Assert.assertNotSame(port, factory.getPort());

        Map<String, String> configuration = new HashMap<>();
        configuration.put(RABBITMQ_SERVER_IP, "http://roboconf.net:" + port + "/some/path");
        configuration.put(RABBITMQ_SERVER_USERNAME, username);
        configuration.put(RABBITMQ_SERVER_PASSWORD, password);

        RabbitMqUtils.configureFactory(factory, configuration);
        Assert.assertEquals(address, factory.getHost());
        Assert.assertEquals(port, factory.getPort());
        Assert.assertEquals(username, factory.getUsername());
        Assert.assertEquals(password, factory.getPassword());
    }

    @Test
    public void testConfigureFactory_nullIp() throws Exception {

        ConnectionFactory factory = new ConnectionFactory();
        String username = "toto";
        String password = "123456789";

        Map<String, String> configuration = new HashMap<>();
        configuration.put(RABBITMQ_SERVER_IP, null);
        configuration.put(RABBITMQ_SERVER_USERNAME, username);
        configuration.put(RABBITMQ_SERVER_PASSWORD, password);

        RabbitMqUtils.configureFactory(factory, configuration);
        Assert.assertEquals(username, factory.getUsername());
        Assert.assertEquals(password, factory.getPassword());
    }

    @Test
    public void testConfigureFactory_withoutSslEnabled() throws Exception {

        int port = 18547;
        ConnectionFactory factory = Mockito.mock(ConnectionFactory.class);

        Map<String, String> configuration = new HashMap<>();
        configuration.put(RABBITMQ_SERVER_IP, "http://roboconf.net:" + port);
        configuration.put(RABBITMQ_SERVER_USERNAME, "toto");
        configuration.put(RABBITMQ_SERVER_PASSWORD, "123456789");
        configuration.put(RABBITMQ_SSL_KEY_STORE_PATH, this.folder.newFile().getAbsolutePath());
        configuration.put(RABBITMQ_SSL_KEY_STORE_PASSPHRASE, "key store");
        configuration.put(RABBITMQ_SSL_TRUST_STORE_PATH, this.folder.newFile().getAbsolutePath());
        configuration.put(RABBITMQ_SSL_TRUST_STORE_PASSPHRASE, "trust store");
        configuration.put(RABBITMQ_SSL_AS_USER_DATA, "true");

        RabbitMqUtils.configureFactory(factory, configuration);

        Mockito.verify(factory).setUsername("toto");
        Mockito.verify(factory).setPassword("123456789");
        Mockito.verify(factory).setHost("http://roboconf.net");
        Mockito.verify(factory).setPort(port);

        Mockito.verify(factory).setConnectionTimeout(Mockito.anyInt());
        Mockito.verify(factory).setAutomaticRecoveryEnabled(true);
        Mockito.verify(factory).setNetworkRecoveryInterval(Mockito.anyInt());
        Mockito.verify(factory).setTopologyRecoveryEnabled(true);

        Mockito.verifyZeroInteractions(factory);
    }

    @Test
    public void testConfigureFactory_withSslEnabled() throws Exception {

        int port = 18547;
        ConnectionFactory factory = Mockito.mock(ConnectionFactory.class);

        String keyPassPhrase = "key store";
        File keyStore = generateKeyStore(keyPassPhrase, RabbitMqConstants.DEFAULT_SSL_KEY_STORE_TYPE);

        String trustPassPhrase = "trust store";
        File trustStore = generateKeyStore(trustPassPhrase, RabbitMqConstants.DEFAULT_SSL_TRUST_STORE_TYPE);

        Map<String, String> configuration = new HashMap<>();
        configuration.put(RABBITMQ_SERVER_IP, "http://roboconf.net:" + port);
        configuration.put(RABBITMQ_SERVER_USERNAME, "toto");
        configuration.put(RABBITMQ_SERVER_PASSWORD, "123456789");
        configuration.put(RABBITMQ_SSL_KEY_STORE_PATH, keyStore.getAbsolutePath());
        configuration.put(RABBITMQ_SSL_KEY_STORE_PASSPHRASE, keyPassPhrase);
        configuration.put(RABBITMQ_SSL_TRUST_STORE_PATH, trustStore.getAbsolutePath());
        configuration.put(RABBITMQ_SSL_TRUST_STORE_PASSPHRASE, trustPassPhrase);
        configuration.put(RABBITMQ_SSL_AS_USER_DATA, "true");
        configuration.put(RABBITMQ_USE_SSL, "true");

        RabbitMqUtils.configureFactory(factory, configuration);

        Mockito.verify(factory).setUsername("toto");
        Mockito.verify(factory).setPassword("123456789");
        Mockito.verify(factory).setHost("http://roboconf.net");
        Mockito.verify(factory).setPort(port);

        Mockito.verify(factory).setConnectionTimeout(Mockito.anyInt());
        Mockito.verify(factory).setAutomaticRecoveryEnabled(true);
        Mockito.verify(factory).setNetworkRecoveryInterval(Mockito.anyInt());
        Mockito.verify(factory).setTopologyRecoveryEnabled(true);

        Mockito.verify(factory).useSslProtocol(Mockito.any(SSLContext.class));
        Mockito.verifyZeroInteractions(factory);
    }

    @Test(expected = IOException.class)
    public void testConfigureFactory_withSslEnabled_ioException() throws Exception {

        ConnectionFactory factory = Mockito.mock(ConnectionFactory.class);

        String trustPassPhrase = "trust store";
        File trustStore = generateKeyStore(trustPassPhrase, RabbitMqConstants.DEFAULT_SSL_TRUST_STORE_TYPE);

        Map<String, String> configuration = new HashMap<>();
        configuration.put(RABBITMQ_SERVER_IP, "http://roboconf.net:18547/some/path");
        configuration.put(RABBITMQ_SERVER_USERNAME, "toto");
        configuration.put(RABBITMQ_SERVER_PASSWORD, "123456789");
        configuration.put(RABBITMQ_SSL_KEY_STORE_PATH, "does not exist");
        configuration.put(RABBITMQ_SSL_KEY_STORE_PASSPHRASE, "key store");
        configuration.put(RABBITMQ_SSL_TRUST_STORE_PATH, trustStore.getAbsolutePath());
        configuration.put(RABBITMQ_SSL_TRUST_STORE_PASSPHRASE, trustPassPhrase);
        configuration.put(RABBITMQ_SSL_AS_USER_DATA, "true");
        configuration.put(RABBITMQ_USE_SSL, "true");

        RabbitMqUtils.configureFactory(factory, configuration);
    }

    @Test
    public void testCloseConnection_withNull() throws Exception {
        RabbitMqUtils.closeConnection(null);
    }

    @Test
    public void testCloseConnection() throws Exception {
        Assume.assumeTrue(rabbitMqIsRunning);

        Channel channel = RabbitMqTestUtils.createTestChannel();
        Assert.assertTrue(channel.isOpen());
        Assert.assertTrue(channel.getConnection().isOpen());

        // Close it
        RabbitMqUtils.closeConnection(channel);
        Assert.assertFalse(channel.isOpen());
        Assert.assertFalse(channel.getConnection().isOpen());

        // Make sure closing an already closed channel does not throw an exception
        RabbitMqUtils.closeConnection(channel);
        Assert.assertFalse(channel.isOpen());
        Assert.assertFalse(channel.getConnection().isOpen());
    }

    /**
     * Generates an empty key store.
     * @param passPhrase the pass phrase (not null)
     * @param type the type of the store
     * @return the key store file
     * @throws IOException
     * @throws GeneralSecurityException
     */
    private File generateKeyStore(String passPhrase, String type) throws IOException, GeneralSecurityException {

        File result = this.folder.newFile();
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(result.getAbsolutePath());
            KeyStore ks = KeyStore.getInstance(type);
            ks.load(null, null);
            ks.store(fos, passPhrase.toCharArray());

        } finally {
            Utils.closeQuietly(fos);
        }

        Assert.assertTrue(result.isFile());
        return result;
    }
}