com.nxttxn.vramel.components.rabbitMQ.RabbitMQEndpoint.java Source code

Java tutorial

Introduction

Here is the source code for com.nxttxn.vramel.components.rabbitMQ.RabbitMQEndpoint.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 com.nxttxn.vramel.components.rabbitMQ;

import java.io.IOException;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ssl.TrustManager;

import com.nxttxn.vramel.Consumer;
import com.nxttxn.vramel.Exchange;
import com.nxttxn.vramel.ExchangePattern;
import com.nxttxn.vramel.Message;
import com.nxttxn.vramel.Processor;
import com.nxttxn.vramel.Producer;
import com.nxttxn.vramel.impl.DefaultEndpoint;
import com.nxttxn.vramel.impl.DefaultExchange;
import com.nxttxn.vramel.impl.DefaultMessage;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Address;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.LongString;

//@UriEndpoint(scheme = "rabbitMQ", consumerClass = RabbitMQConsumer.class, label = "messaging")
public class RabbitMQEndpoint extends DefaultEndpoint {

    //    @UriPath
    private String hostname;
    //    @UriPath
    private int portNumber;
    //    @UriPath
    private String exchangeName;
    //    @UriParam(defaultValue = ConnectionFactory.DEFAULT_USER)
    private String username = ConnectionFactory.DEFAULT_USER;
    //    @UriParam(defaultValue = ConnectionFactory.DEFAULT_PASS)
    private String password = ConnectionFactory.DEFAULT_PASS;
    //    @UriParam(defaultValue = ConnectionFactory.DEFAULT_VHOST)
    private String vhost = ConnectionFactory.DEFAULT_VHOST;
    //    @UriParam(defaultValue = "10")
    private int threadPoolSize = 10;
    //    @UriParam(defaultValue = "true")
    private boolean autoAck = true;
    //    @UriParam(defaultValue = "true")
    private boolean autoDelete = true;
    //    @UriParam(defaultValue = "true")
    private boolean durable = true;
    // Default deliveryMode if not set on message, by default only use RabbitMQConstants.DELIVERY_MODE
    private Integer deliveryMode;
    //    @UriParam(defaultValue = "false")
    private boolean bridgeEndpoint;
    private String queue = String.valueOf(UUID.randomUUID().toString().hashCode());
    //    @UriParam(defaultValue = "direct")
    private String exchangeType = "direct";
    //    @UriParam
    private String routingKey;
    //    @UriParam
    private Address[] addresses;
    //    @UriParam(defaultValue = "" + ConnectionFactory.DEFAULT_CONNECTION_TIMEOUT)
    private int connectionTimeout = ConnectionFactory.DEFAULT_CONNECTION_TIMEOUT;
    //    @UriParam(defaultValue = "" + ConnectionFactory.DEFAULT_CHANNEL_MAX)
    private int requestedChannelMax = ConnectionFactory.DEFAULT_CHANNEL_MAX;
    //    @UriParam(defaultValue = "" + ConnectionFactory.DEFAULT_FRAME_MAX)
    private int requestedFrameMax = ConnectionFactory.DEFAULT_FRAME_MAX;
    //    @UriParam(defaultValue = "" + ConnectionFactory.DEFAULT_HEARTBEAT)
    private int requestedHeartbeat = ConnectionFactory.DEFAULT_HEARTBEAT;
    //    @UriParam
    private String sslProtocol;
    //    @UriParam
    private TrustManager trustManager;
    //    @UriParam
    private Map<String, Object> clientProperties;
    //    @UriParam
    private ConnectionFactory connectionFactory;
    //    @UriParam(defaultValue = "false")
    private Boolean automaticRecoveryEnabled;
    //    @UriParam
    private Integer networkRecoveryInterval = 5000;
    //    @UriParam(defaultValue = "false")
    private Boolean topologyRecoveryEnabled;
    //If it is true, prefetchSize, prefetchCount, prefetchGlobal will be used for basicOqs before starting RabbitMQConsumer
    //    @UriParam(defaultValue = "false")
    private boolean prefetchEnabled;
    //Default in RabbitMq is 0.
    //    @UriParam
    private int prefetchSize;
    //    @UriParam
    private int prefetchCount;
    //Default value in RabbitMQ is false.
    //    @UriParam(defaultValue = "false")
    private boolean prefetchGlobal;
    /**
     * Number of concurrent consumer threads
     */
    //    @UriParam(defaultValue = "1")
    private int concurrentConsumers = 1;
    //Declares a queue and exchange in RabbitMQ, then binds both.
    //    @UriParam(defaultValue = "true")
    private boolean declare = true;
    //Declare dead letter exchange.
    //    @UriParam
    private String deadLetterExchange;
    //Declare dead letter routing key.
    //    @UriParam
    private String deadLetterRoutingKey;
    //Declare dead letter queue to declare.
    //    @UriParam
    private String deadLetterQueue;
    //Dead letter exchange type.
    //    @UriParam(defaultValue = "direct")
    private String deadLetterExchangeType = "direct";
    //Maximum number of opened channel in pool
    //    @UriParam(defaultValue = "10")
    private int channelPoolMaxSize = 10;
    //Maximum time (in milliseconds) waiting for channel
    //    @UriParam(defaultValue = "1000")
    private long channelPoolMaxWait = 1000;

    public RabbitMQEndpoint() {
    }

    public RabbitMQEndpoint(String endpointUri, RabbitMQComponent component) throws URISyntaxException {
        super(endpointUri, component);
    }

    public RabbitMQEndpoint(String endpointUri, RabbitMQComponent component, ConnectionFactory connectionFactory)
            throws URISyntaxException {
        super(endpointUri, component);
        this.connectionFactory = connectionFactory;
    }

    public Exchange createRabbitExchange(Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
        Exchange exchange = new DefaultExchange(getVramelContext(), getExchangePattern(getExchangeType()));

        Message message = new DefaultMessage();
        exchange.setIn(message);

        message.setHeader(RabbitMQConstants.ROUTING_KEY, envelope.getRoutingKey());
        message.setHeader(RabbitMQConstants.EXCHANGE_NAME, envelope.getExchange());
        message.setHeader(RabbitMQConstants.DELIVERY_TAG, envelope.getDeliveryTag());

        Map<String, Object> headers = properties.getHeaders();
        if (headers != null) {
            for (Map.Entry<String, Object> entry : headers.entrySet()) {
                // Convert LongStrings to String.
                if (entry.getValue() instanceof LongString) {
                    message.setHeader(entry.getKey(), entry.getValue().toString());
                } else if (entry.getKey().equals(RabbitMQConstants.VRAMEL_SERIALIZABLE_HEADERS)) {
                    SerializableHeaderContainer serializedHeaders = new SerializableHeaderContainer(
                            (byte[]) entry.getValue());
                    serializedHeaders.deserializeInto(message);
                } else {
                    message.setHeader(entry.getKey(), entry.getValue());
                }
            }
        }

        message.setBody(body);

        return exchange;
    }

    private ExchangePattern getExchangePattern(String exchangeType) {
        return (exchangeType == "direct" ? ExchangePattern.InOut : ExchangePattern.InOnly);
    }

    @Override
    public Consumer createConsumer(Processor processor) throws Exception {
        RabbitMQConsumer consumer = new RabbitMQConsumer(this, processor);
        configureConsumer(consumer);
        return consumer;
    }

    public Connection connect(ExecutorService executor) throws IOException {
        if (getAddresses() == null) {
            return getOrCreateConnectionFactory().newConnection(executor);
        } else {
            return getOrCreateConnectionFactory().newConnection(executor, getAddresses());
        }
    }

    /**
     * If needed, declare Exchange, declare Queue and bind them with Routing Key
     */
    public void declareExchangeAndQueue(Channel channel) throws IOException {
        HashMap<String, Object> queueArgs = null;
        if (deadLetterExchange != null) {
            queueArgs = new HashMap<String, Object>();
            queueArgs.put(RabbitMQConstants.RABBITMQ_DEAD_LETTER_EXCHANGE, getDeadLetterExchange());
            queueArgs.put(RabbitMQConstants.RABBITMQ_DEAD_LETTER_ROUTING_KEY, getDeadLetterRoutingKey());

            channel.exchangeDeclare(getDeadLetterExchange(), getDeadLetterExchangeType(), isDurable(),
                    isAutoDelete(), new HashMap<String, Object>());
            channel.queueDeclare(getDeadLetterQueue(), isDurable(), false, isAutoDelete(), null);
            channel.queueBind(getDeadLetterQueue(), getDeadLetterExchange(),
                    getDeadLetterRoutingKey() == null ? "" : getDeadLetterRoutingKey());
        }
        channel.exchangeDeclare(getExchangeName(), getExchangeType(), isDurable(), isAutoDelete(),
                new HashMap<String, Object>());
        if (getQueue() != null) {
            // need to make sure the queueDeclare is same with the exchange declare
            channel.queueDeclare(getQueue(), isDurable(), false, isAutoDelete(), queueArgs);
            channel.queueBind(getQueue(), getExchangeName(), getRoutingKey() == null ? "" : getRoutingKey());
        }
    }

    private ConnectionFactory getOrCreateConnectionFactory() {
        if (connectionFactory == null) {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setUsername(getUsername());
            factory.setPassword(getPassword());
            factory.setVirtualHost(getVhost());
            factory.setHost(getHostname());
            factory.setPort(getPortNumber());
            if (getClientProperties() != null) {
                factory.setClientProperties(getClientProperties());
            }
            factory.setConnectionTimeout(getConnectionTimeout());
            factory.setRequestedChannelMax(getRequestedChannelMax());
            factory.setRequestedFrameMax(getRequestedFrameMax());
            factory.setRequestedHeartbeat(getRequestedHeartbeat());
            if (getSslProtocol() != null) {
                try {
                    if (getSslProtocol().equals("true")) {
                        factory.useSslProtocol();
                    } else if (getTrustManager() == null) {
                        factory.useSslProtocol(getSslProtocol());
                    } else {
                        factory.useSslProtocol(getSslProtocol(), getTrustManager());
                    }
                } catch (NoSuchAlgorithmException | KeyManagementException e) {
                    throw new IllegalArgumentException("Invalid sslProtocol " + sslProtocol, e);
                }
            }
            if (getAutomaticRecoveryEnabled() != null) {
                factory.setAutomaticRecoveryEnabled(getAutomaticRecoveryEnabled());
            }
            if (getNetworkRecoveryInterval() != null) {
                factory.setNetworkRecoveryInterval(getNetworkRecoveryInterval());
            }
            if (getTopologyRecoveryEnabled() != null) {
                factory.setTopologyRecoveryEnabled(getTopologyRecoveryEnabled());
            }
            connectionFactory = factory;
        }
        return connectionFactory;
    }

    @Override
    public Producer createProducer() throws Exception {
        return new RabbitMQProducer(this);
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    protected ExecutorService createExecutor() {
        if (getVramelContext() != null) {
            return getVramelContext().getExecutorServiceManager().newFixedThreadPool(this, "RabbitMQConsumer",
                    getThreadPoolSize());
        } else {
            return Executors.newFixedThreadPool(getThreadPoolSize());
        }
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getVhost() {
        return vhost;
    }

    public void setVhost(String vhost) {
        this.vhost = vhost;
    }

    public String getHostname() {
        return hostname;
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
    }

    public int getThreadPoolSize() {
        return threadPoolSize;
    }

    public void setThreadPoolSize(int threadPoolSize) {
        this.threadPoolSize = threadPoolSize;
    }

    public int getPortNumber() {
        return portNumber;
    }

    public void setPortNumber(int portNumber) {
        this.portNumber = portNumber;
    }

    public boolean isAutoAck() {
        return autoAck;
    }

    public void setAutoAck(boolean autoAck) {
        this.autoAck = autoAck;
    }

    public boolean isAutoDelete() {
        return autoDelete;
    }

    public void setAutoDelete(boolean autoDelete) {
        this.autoDelete = autoDelete;
    }

    public boolean isDurable() {
        return durable;
    }

    public void setDurable(boolean durable) {
        this.durable = durable;
    }

    public Integer getDeliveryMode() {
        return deliveryMode;
    }

    public void setDeliveryMode(Integer deliveryMode) {
        this.deliveryMode = deliveryMode;
    }

    public String getQueue() {
        return queue;
    }

    public void setQueue(String queue) {
        this.queue = queue;
    }

    public String getExchangeName() {
        return exchangeName;
    }

    public void setExchangeName(String exchangeName) {
        this.exchangeName = exchangeName;
    }

    public String getExchangeType() {
        return exchangeType;
    }

    public void setExchangeType(String exchangeType) {
        this.exchangeType = exchangeType;
    }

    public String getRoutingKey() {
        return routingKey;
    }

    public void setRoutingKey(String routingKey) {
        this.routingKey = routingKey;
    }

    public void setBridgeEndpoint(boolean bridgeEndpoint) {
        this.bridgeEndpoint = bridgeEndpoint;
    }

    public boolean isBridgeEndpoint() {
        return bridgeEndpoint;
    }

    public void setAddresses(String addresses) {
        Address[] addressArray = Address.parseAddresses(addresses);
        if (addressArray.length > 0) {
            this.addresses = addressArray;
        }
    }

    public Address[] getAddresses() {
        return addresses;
    }

    public int getConnectionTimeout() {
        return connectionTimeout;
    }

    public void setConnectionTimeout(int connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }

    public int getRequestedChannelMax() {
        return requestedChannelMax;
    }

    public void setRequestedChannelMax(int requestedChannelMax) {
        this.requestedChannelMax = requestedChannelMax;
    }

    public int getRequestedFrameMax() {
        return requestedFrameMax;
    }

    public void setRequestedFrameMax(int requestedFrameMax) {
        this.requestedFrameMax = requestedFrameMax;
    }

    public int getRequestedHeartbeat() {
        return requestedHeartbeat;
    }

    public void setRequestedHeartbeat(int requestedHeartbeat) {
        this.requestedHeartbeat = requestedHeartbeat;
    }

    public String getSslProtocol() {
        return sslProtocol;
    }

    public void setSslProtocol(String sslProtocol) {
        this.sslProtocol = sslProtocol;
    }

    public ConnectionFactory getConnectionFactory() {
        return connectionFactory;
    }

    public void setConnectionFactory(ConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    public TrustManager getTrustManager() {
        return trustManager;
    }

    public void setTrustManager(TrustManager trustManager) {
        this.trustManager = trustManager;
    }

    public Map<String, Object> getClientProperties() {
        return clientProperties;
    }

    public void setClientProperties(Map<String, Object> clientProperties) {
        this.clientProperties = clientProperties;
    }

    public Boolean getAutomaticRecoveryEnabled() {
        return automaticRecoveryEnabled;
    }

    public void setAutomaticRecoveryEnabled(Boolean automaticRecoveryEnabled) {
        this.automaticRecoveryEnabled = automaticRecoveryEnabled;
    }

    public Integer getNetworkRecoveryInterval() {
        return networkRecoveryInterval;
    }

    public void setNetworkRecoveryInterval(Integer networkRecoveryInterval) {
        this.networkRecoveryInterval = networkRecoveryInterval;
    }

    public Boolean getTopologyRecoveryEnabled() {
        return topologyRecoveryEnabled;
    }

    public void setTopologyRecoveryEnabled(Boolean topologyRecoveryEnabled) {
        this.topologyRecoveryEnabled = topologyRecoveryEnabled;
    }

    public boolean isPrefetchEnabled() {
        return prefetchEnabled;
    }

    public void setPrefetchEnabled(boolean prefetchEnabled) {
        this.prefetchEnabled = prefetchEnabled;
    }

    public void setPrefetchSize(int prefetchSize) {
        this.prefetchSize = prefetchSize;
    }

    public int getPrefetchSize() {
        return prefetchSize;
    }

    public void setPrefetchCount(int prefetchCount) {
        this.prefetchCount = prefetchCount;
    }

    public int getPrefetchCount() {
        return prefetchCount;
    }

    public void setPrefetchGlobal(boolean prefetchGlobal) {
        this.prefetchGlobal = prefetchGlobal;
    }

    public boolean isPrefetchGlobal() {
        return prefetchGlobal;
    }

    public int getConcurrentConsumers() {
        return concurrentConsumers;
    }

    public void setConcurrentConsumers(int concurrentConsumers) {
        this.concurrentConsumers = concurrentConsumers;
    }

    public boolean isDeclare() {
        return declare;
    }

    public void setDeclare(boolean declare) {
        this.declare = declare;
    }

    public String getDeadLetterExchange() {
        return deadLetterExchange;
    }

    public void setDeadLetterExchange(String deadLetterExchange) {
        this.deadLetterExchange = deadLetterExchange;
    }

    public String getDeadLetterQueue() {
        return deadLetterQueue;
    }

    public void setDeadLetterQueue(String deadLetterQueue) {
        this.deadLetterQueue = deadLetterQueue;
    }

    public String getDeadLetterRoutingKey() {
        return deadLetterRoutingKey;
    }

    public void setDeadLetterRoutingKey(String deadLetterRoutingKey) {
        this.deadLetterRoutingKey = deadLetterRoutingKey;
    }

    public String getDeadLetterExchangeType() {
        return deadLetterExchangeType;
    }

    public void setDeadLetterExchangeType(String deadLetterExchangeType) {
        this.deadLetterExchangeType = deadLetterExchangeType;
    }

    /**
     * Get maximum number of opened channel in pool
     *
     * @return Maximum number of opened channel in pool
     */
    public int getChannelPoolMaxSize() {
        return channelPoolMaxSize;
    }

    /**
     * Set maximum number of opened channel in pool
     *
     * @param channelPoolMaxSize Maximum number of opened channel in pool
     */
    public void setChannelPoolMaxSize(int channelPoolMaxSize) {
        this.channelPoolMaxSize = channelPoolMaxSize;
    }

    /**
     * Get the maximum number of milliseconds to wait for a channel from the pool
     *
     * @return Maximum number of milliseconds waiting for a channel
     */
    public long getChannelPoolMaxWait() {
        return channelPoolMaxWait;
    }

    /**
     * Set the maximum number of milliseconds to wait for a channel from the pool
     *
     * @param channelPoolMaxWait Maximum number of milliseconds waiting for a channel
     */
    public void setChannelPoolMaxWait(long channelPoolMaxWait) {
        this.channelPoolMaxWait = channelPoolMaxWait;
    }
}