package dk.kb.yggdrasil.messaging; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URISyntaxException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Connection; import com.rabbitmq.client.Channel; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.ConsumerCancelledException; import com.rabbitmq.client.QueueingConsumer; import com.rabbitmq.client.ShutdownSignalException; import dk.kb.yggdrasil.MqFixtureTestAPI; import dk.kb.yggdrasil.config.RabbitMqSettings; import dk.kb.yggdrasil.config.RunningMode; import dk.kb.yggdrasil.exceptions.RabbitException; import dk.kb.yggdrasil.exceptions.YggdrasilException; import dk.kb.yggdrasil.messaging.MQ; import dk.kb.yggdrasil.messaging.MqResponse; /** * These tests assume the rabbitmq on localhost, if not override RABBITMQ_HOSTNAME * (e.g. export RABBITMQ_HOSTNAME=dia-prod-udv-01.kb.dk or DRABBITMQ_HOSTNAME=dia-prod-udv-01.kb.dk,) * and another port than 5672 by setting the RABBITMQ_PORT ( * (e.g. export RABBITMQ_PORT=5673 or DRABBITMQ_PORT=5673); * * You can have several rabbitmq brokers running on the same server. * Each though must have their own port, and nodename which can be set * using export RABBITMQ_NODENAME=bunny * See manpage for rabbitmq-server for more details. * */ @RunWith(JUnit4.class) public class MqTest extends MqFixtureTestAPI { public static String RABBITMQ_CONF_FILE = "src/test/resources/config/rabbitmq.yml"; @BeforeClass public static void initialize() { System.setProperty(RunningMode.RUNNINGMODE_PROPERTY, RunningMode.TEST.name()); } /** * Testing of queue publish and consume for MQ class * @throws YggdrasilException * @throws IOException * @throws RabbitException */ @Test public void finalTest() throws YggdrasilException, IOException, RabbitException { String methodName = this.getClass().getName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName(); RabbitMqSettings settings = fetchMqSettings(); settings.setPreservationDestination(settings.getPreservationDestination() + "-" + methodName); MQ mq = instantiatePurgesMQ(settings); assertTrue(settings.equals(mq.getSettings())); String message = "Hello world from " + methodName; String queueName = settings.getPreservationDestination(); mq.publishOnQueue(queueName, message.getBytes(), MQ.PRESERVATIONREQUEST_MESSAGE_TYPE); MqResponse messageReceived = mq.receiveMessageFromQueue(queueName); Assert.assertArrayEquals(message.getBytes(), messageReceived.getPayload()); message = "Hello X from " + methodName; mq.publishOnQueue(queueName, message.getBytes(), MQ.PRESERVATIONREQUEST_MESSAGE_TYPE); messageReceived = mq.receiveMessageFromQueue(queueName); Assert.assertArrayEquals(message.getBytes(), messageReceived.getPayload()); mq.close(); } /** * Unit test for sending a Yggdrasil shutdown message * @throws YggdrasilException * @throws IOException * @throws RabbitException */ @Test public void sendShutdown() throws YggdrasilException, IOException, RabbitException { String methodName = this.getClass().getName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName(); RabbitMqSettings settings = fetchMqSettings(); settings.setPreservationDestination(settings.getPreservationDestination() + "-" + methodName); MQ mq = instantiatePurgesMQ(settings); String queueName = settings.getPreservationDestination(); String message = "Shutdown Message"; mq.publishOnQueue(queueName, message.getBytes(), MQ.SHUTDOWN_MESSAGE_TYPE); MqResponse messageReceived = mq.receiveMessageFromQueue(queueName); assertTrue(messageReceived.getMessageType().equals(MQ.SHUTDOWN_MESSAGE_TYPE)); Assert.assertArrayEquals(message.getBytes(), messageReceived.getPayload()); mq.close(); } /** * Unit test for general testing of queue publish and consume * @throws KeyManagementException * @throws NoSuchAlgorithmException * @throws URISyntaxException * @throws IOException * @throws YggdrasilException * @throws ShutdownSignalException * @throws ConsumerCancelledException * @throws InterruptedException */ @Test public void testReceived() throws KeyManagementException,NoSuchAlgorithmException, URISyntaxException, IOException, YggdrasilException, ShutdownSignalException, ConsumerCancelledException, InterruptedException { String methodName = this.getClass().getName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName(); RabbitMqSettings settings = fetchMqSettings(); ConnectionFactory factory = new ConnectionFactory(); factory.setUri(settings.getBrokerUri()); Connection conn = factory.newConnection(); final Channel channel = conn.createChannel(); String exchangeName = "exchange" + "-" + this.getClass().getName(); String queueName = settings.getPreservationDestination() + "-" + methodName; String routingKey = "routing"; boolean queueDurable = true; channel.exchangeDeclare(exchangeName, "direct", true); channel.queueDeclare(queueName, queueDurable, false, false, null); channel.queueBind(queueName, exchangeName, routingKey); String message = "Hello world from " + methodName; byte[] messageBodyBytes = message.getBytes(); channel.basicPublish(exchangeName, routingKey, new AMQP.BasicProperties.Builder().contentType("text/plain").deliveryMode(2) .priority(1).build(), messageBodyBytes); final boolean AUTO_ACK = false; QueueingConsumer consumer = new QueueingConsumer(channel); channel.basicConsume(queueName, AUTO_ACK, consumer); QueueingConsumer.Delivery delivery = consumer.nextDelivery(); channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); Assert.assertArrayEquals(messageBodyBytes, delivery.getBody()); channel.exchangeDelete(exchangeName, false); channel.queueDelete(queueName, false, true); channel.close(); conn.close(); } /** * Unit test for alternate constructor for RabbitMq setting * @throws YggdrasilException * @throws FileNotFoundException */ @Test public void testRabbitMqSettingsAlternateConstructor() throws YggdrasilException, FileNotFoundException { File f = new File(RABBITMQ_CONF_FILE); RabbitMqSettings settings = new RabbitMqSettings(f); String brokerUri = settings.getBrokerUri(); String presDest = settings.getPreservationDestination(); String presRecDest = settings.getPreservationResponseDestination(); RabbitMqSettings settingsCopy = new RabbitMqSettings(brokerUri, presDest, presRecDest); assertEquals(brokerUri, settingsCopy.getBrokerUri()); assertEquals(presDest, settingsCopy.getPreservationDestination()); } /** * Helper method that fetch RabbitMq settings * @throws YggdrasilException * @throws FileNotFoundException */ private RabbitMqSettings fetchMqSettings() throws YggdrasilException, FileNotFoundException { File f = new File(RABBITMQ_CONF_FILE); RabbitMqSettings settings = new RabbitMqSettings(f); return settings; } }