org.mule.transport.amqp.AmqpEndpointUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.transport.amqp.AmqpEndpointUtil.java

Source

/*
 * $Id$
 * --------------------------------------------------------------------------------------
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 *
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */

package org.mule.transport.amqp;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mule.api.MuleRuntimeException;
import org.mule.api.endpoint.ImmutableEndpoint;
import org.mule.api.endpoint.InboundEndpoint;
import org.mule.config.i18n.MessageFactory;
import org.mule.util.StringUtils;

import com.rabbitmq.client.AMQP.Queue.DeclareOk;
import com.rabbitmq.client.Channel;

public abstract class AmqpEndpointUtil {
    private static final Map<String, Object> NO_ARGS = Collections.<String, Object>emptyMap();

    public static final String QUEUE_EXCLUSIVE = "queueExclusive";

    public static final String QUEUE_AUTO_DELETE = "queueAutoDelete";

    public static final String QUEUE_DURABLE = "queueDurable";

    private final static Log LOG = LogFactory.getLog(AmqpEndpointUtil.class);

    public static final String EXCHANGE_AUTO_DELETE = "exchangeAutoDelete";
    public static final String EXCHANGE_DURABLE = "exchangeDurable";
    public static final String QUEUE_PREFIX = "amqp-queue.";
    public static final String EXCHANGE_TYPE = "exchangeType";
    public static final String ROUTING_KEY = "routingKey";
    public static final String CONSUMER_TAG = "consumerTag";

    public static String getOrCreateQueue(final Channel channel, final ImmutableEndpoint endpoint,
            final boolean activeDeclarationsOnly) throws IOException {
        final String exchangeName = getOrCreateExchange(channel, endpoint, activeDeclarationsOnly);
        final String routingKey = getRoutingKey(endpoint);

        if ((StringUtils.isBlank(exchangeName)) && (StringUtils.isNotBlank(routingKey))) {
            // no exchange name -> enforce routing key to be empty
            throw new MuleRuntimeException(MessageFactory.createStaticMessage(
                    "An exchange name must be provided if a routing key is provided in endpoint: " + endpoint));
        }

        final String queueName = getQueueName(endpoint.getAddress());

        if (StringUtils.isBlank(queueName)) {
            // no queue name -> create a private one on the server
            final DeclareOk queueDeclareResult = channel.queueDeclare();

            final String privateQueueName = queueDeclareResult.getQueue();
            LOG.info("Declared private queue: " + privateQueueName);

            bindQueue(channel, endpoint, exchangeName, routingKey, privateQueueName);
            return privateQueueName;
        }

        // queue name -> either create or ensure the queue exists
        if (endpoint.getProperties().containsKey(QUEUE_DURABLE)
                || endpoint.getProperties().containsKey(QUEUE_AUTO_DELETE)
                || endpoint.getProperties().containsKey(QUEUE_EXCLUSIVE)) {
            // any of the queue declaration parameter provided -> declare the queue
            final boolean queueDurable = BooleanUtils.toBoolean((String) endpoint.getProperty(QUEUE_DURABLE));
            final boolean queueExclusive = BooleanUtils.toBoolean((String) endpoint.getProperty(QUEUE_EXCLUSIVE));
            final boolean queueAutoDelete = BooleanUtils
                    .toBoolean((String) endpoint.getProperty(QUEUE_AUTO_DELETE));

            channel.queueDeclare(queueName, queueDurable, queueExclusive, queueAutoDelete, NO_ARGS);
            LOG.info("Declared queue: " + queueName + ", durable: " + queueDurable + ", exclusive: "
                    + queueExclusive + ", autoDelete: " + queueAutoDelete);

            bindQueue(channel, endpoint, exchangeName, routingKey, queueName);
        } else if (!activeDeclarationsOnly) {
            // no declaration parameter -> ensure the queue exists
            channel.queueDeclarePassive(queueName);

            if (LOG.isDebugEnabled()) {
                LOG.debug("Validated presence of queue: " + queueName);
            }
        }

        return queueName;
    }

    private static void bindQueue(final Channel channel, final ImmutableEndpoint endpoint,
            final String exchangeName, final String routingKey, final String queueName) throws IOException {
        if (StringUtils.isBlank(exchangeName)) {
            // default exchange name -> can not bind a queue to it
            throw new MuleRuntimeException(MessageFactory.createStaticMessage(
                    "No queue can be programmatically bound to the default exchange: " + endpoint));
        }

        // bind queue to exchange
        channel.queueBind(queueName, exchangeName, routingKey);

        LOG.info(
                "Bound queue: " + queueName + " to exchange: " + exchangeName + " with routing key: " + routingKey);
    }

    public static String getOrCreateExchange(final Channel channel, final ImmutableEndpoint endpoint,
            final boolean activeDeclarationsOnly) throws IOException {
        final String outboundEndpointAddress = endpoint.getAddress();
        final String exchangeName = getExchangeName(outboundEndpointAddress);

        if (StringUtils.isBlank(exchangeName)) {
            LOG.info("Using default exchange for endpoint: " + endpoint);
            return exchangeName;
        }

        final String exchangeType = (String) endpoint.getProperty(EXCHANGE_TYPE);
        if (StringUtils.isNotBlank(exchangeType)) {
            // an exchange type is provided -> the exchange must be declared
            final boolean exchangeDurable = BooleanUtils.toBoolean((String) endpoint.getProperty(EXCHANGE_DURABLE));
            final boolean exchangeAutoDelete = BooleanUtils
                    .toBoolean((String) endpoint.getProperty(EXCHANGE_AUTO_DELETE));

            channel.exchangeDeclare(exchangeName, exchangeType, exchangeDurable, exchangeAutoDelete, NO_ARGS);

            LOG.info("Declared exchange: " + exchangeName + " of type: " + exchangeType + ", durable: "
                    + exchangeDurable + ", autoDelete: " + exchangeAutoDelete);
        } else if (!activeDeclarationsOnly) {
            // no exchange type -> ensure the exchange exists
            channel.exchangeDeclarePassive(exchangeName);

            if (LOG.isDebugEnabled()) {
                LOG.debug("Validated presence of exchange: " + exchangeName);
            }
        }

        return exchangeName;
    }

    public static String getRoutingKey(final ImmutableEndpoint endpoint) {
        return StringUtils.defaultString((String) endpoint.getProperty(ROUTING_KEY));
    }

    public static String getConsumerTag(final ImmutableEndpoint endpoint) {
        return StringUtils.defaultString((String) endpoint.getProperty(CONSUMER_TAG));
    }

    public static String getQueueName(final String endpointAddress) {
        return StringUtils.defaultString(StringUtils.substringAfter(trimQuery(endpointAddress), QUEUE_PREFIX));
    }

    public static String getExchangeName(final String endpointAddress) {
        final String trimmedQuery = trimQuery(endpointAddress);
        final String exchangeName = StringUtils.defaultString(
                StringUtils.substringBetween(trimmedQuery, AmqpConnector.AMQP + "://", "/" + QUEUE_PREFIX),
                StringUtils.substringAfter(trimmedQuery, AmqpConnector.AMQP + "://"));

        if (exchangeName.startsWith(QUEUE_PREFIX)) {
            return StringUtils.EMPTY;
        }

        return exchangeName;
    }

    private static String trimQuery(final String address) {
        return StringUtils.substringBefore(address, "?");
    }
}