Package org.mule.transport.jms.mulemq

Source Code of org.mule.transport.jms.mulemq.MuleMQJmsConnector

/*
* $Id: MuleMQJmsConnector.java 19191 2010-08-25 21:05:23Z tcarlson $
* --------------------------------------------------------------------------------------
* 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.jms.mulemq;

import org.mule.api.MuleContext;
import org.mule.api.lifecycle.InitialisationException;
import org.mule.config.ExceptionHelper;
import org.mule.transport.jms.JmsConnector;
import org.mule.transport.jms.JmsConstants;
import org.mule.transport.jms.i18n.JmsMessages;
import org.mule.util.ClassUtils;

import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Map;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;

public class MuleMQJmsConnector extends JmsConnector
{
    public static final String MULEMQ_CONNECTION_FACTORY_CLASS = "com.pcbsys.nirvana.nJMS.ConnectionFactoryImpl";

    // The default values for the connection factory properties
    public static final String DEFAULT_REALM_URL = "nsp://localhost:9000";
    public static final String DEFAULT_BUFFER_OUTPUT = "queued";
    public static final boolean DEFAULT_SYNC_WRITES = false;
    public static final int DEFAULT_SYNC_BATCH_SIZE = 50;
    public static final int DEFAULT_SYNC_TIME = 20;
    public static final int DEFAULT_GLOBAL_STORE_CAPACITY = 5000;
    public static final int DEFAULT_MAX_UNACKED_SIZE = 100;
    public static final boolean DEFAULT_USE_JMS_ENGINE = true;
    public static final int DEFAULT_QUEUE_WINDOW_SIZE = 100;
    public static final int DEFAULT_AUTO_ACK_COUNT = 50;
    public static final boolean DEFAULT_ENABLE_SHARED_DURABLE = false;
    public static final boolean DEFAULT_RANDOMISE_R_NAMES = false;
    public static final int DEFAULT_MAX_REDELIVERY = 100;
    public static final int DEFAULT_MESSAGE_THREAD_POOL_SIZE = 30;
    public static final boolean DEFAULT_DISC_ON_CLUSTER_FAILURE = true;
    public static final int DEFAULT_INITIAL_RETRY_COUNT = 2;
    public static final boolean DEFAULT_RETRY_COMMIT = false;
    public static final boolean DEFAULT_ENABLE_MULTIPLEXED_CONNECTIONS = false;

    // properties to be set on the connector all initialised to their respective
    // default value
    private String realmURL = DEFAULT_REALM_URL;
    private String bufferOutput = DEFAULT_BUFFER_OUTPUT;
    private boolean syncWrites = DEFAULT_SYNC_WRITES;
    private int syncBatchSize = DEFAULT_SYNC_BATCH_SIZE;
    private int syncTime = DEFAULT_SYNC_TIME;
    private int globalStoreCapacity = DEFAULT_GLOBAL_STORE_CAPACITY;
    private int maxUnackedSize = DEFAULT_MAX_UNACKED_SIZE;
    private boolean useJMSEngine = DEFAULT_USE_JMS_ENGINE;
    private int queueWindowSize = DEFAULT_QUEUE_WINDOW_SIZE;
    private int autoAckCount = DEFAULT_AUTO_ACK_COUNT;
    private boolean enableSharedDurable = DEFAULT_ENABLE_SHARED_DURABLE;
    private boolean randomiseRNames = DEFAULT_RANDOMISE_R_NAMES;
    private int muleMqMaxRedelivery = DEFAULT_MAX_REDELIVERY;
    private int messageThreadPoolSize = DEFAULT_MESSAGE_THREAD_POOL_SIZE;
    private boolean discOnClusterFailure = DEFAULT_DISC_ON_CLUSTER_FAILURE;
    private int initialRetryCount = DEFAULT_INITIAL_RETRY_COUNT;
    private boolean retryCommit = DEFAULT_RETRY_COMMIT;
    private boolean enableMultiplexedConnections = DEFAULT_ENABLE_MULTIPLEXED_CONNECTIONS;

    // property names
    protected static final String BUFFER_OUTPUT = "BufferOutput";
    protected static final String SYNC_WRITES = "nirvana.syncWrites";
    protected static final String SYNC_BATCH_SIZE = "nirvana.syncBatchSize";
    protected static final String SYNC_TIME = "nirvana.syncTime";
    protected static final String GLOBAL_STORE_CAPACITY = "nirvana.globalStoreCapacity";
    protected static final String MAX_UNACKED_SIZE = "nirvana.maxUnackedSize";
    protected static final String USE_JMS_ENGINE = "nirvana.useJMSEngine";
    protected static final String QUEUE_WINDOW_SIZE = "nirvana.queueWindowSize";
    protected static final String AUTO_ACK_COUNT = "nirvana.autoAckCount";
    protected static final String ENABLE_SHARED_DURABLE = "nirvana.enableSharedDurable";
    protected static final String RANDOMISE_R_NAMES = "nirvana.randomiseRNames";
    protected static final String MAX_REDELIVERY = "nirvana.maxRedelivery";
    protected static final String MESSAGE_THREAD_POOL_SIZE = "nirvana.messageThreadPoolSize";
    protected static final String DISC_ON_CLUSTER_FAILURE = "nirvana.discOnClusterFailure";
    protected static final String INITIAL_RETRY_COUNT = "nirvana.initialRetryCount";
    protected static final String RETRY_COMMIT = "nirvana.retryCommit";
    protected static final String ENABLE_MULTIPLEXED_CONNECTIONS = "nirvana.enableMultiplexedConnections";

    public boolean supportJms102bSpec = false;

    private boolean inCluster = false;
   
    public MuleMQJmsConnector(MuleContext context)
    {
        super(context);
        super.setSpecification(JmsConstants.JMS_SPECIFICATION_11);
    }

    public boolean isSupportJms102bSpec()
    {
        return supportJms102bSpec;
    }

    public void setSupportJms102bSpec(boolean supportJms102bSpec)
    {
        this.supportJms102bSpec = supportJms102bSpec;
    }

    /*
     * We need to default the specification to 1.1, the xsd defaults to 1.0.2b, we
     * wouldn't have to do this here if the default was set in JmsConnector only, In
     * that case setting the default in the constructor would have been sufficient.
     */
    @Override
    public void setSpecification(String specification)
    {
        if (!isSupportJms102bSpec() && specification.equals(JmsConstants.JMS_SPECIFICATION_102B))
        {
            logger.warn(JmsMessages.errorMuleMqJmsSpecification());
            specification = JmsConstants.JMS_SPECIFICATION_11;
        }
        super.setSpecification(specification);
    }

    @Override
    protected void doInitialise() throws InitialisationException
    {
        if (!isSupportJms102bSpec() && getSpecification().equals(JmsConstants.JMS_SPECIFICATION_102B))
        {
            throw new InitialisationException(JmsMessages.errorMuleMqJmsSpecification(), this);
        }
        super.doInitialise();
    }

    @Override
    protected ConnectionFactory getDefaultConnectionFactory() throws Exception
    {
        ConnectionFactory connectionFactory = (ConnectionFactory) ClassUtils.instanciateClass(
            getMuleMQFactoryClass(), getRealmURL());
        applyVendorSpecificConnectionFactoryProperties(connectionFactory);
        return connectionFactory;
    }

    private void applyVendorSpecificConnectionFactoryProperties(ConnectionFactory connectionFactory)
    {
        // set the properties first on the prop hash table
        Hashtable<String, Object> props = new Hashtable<String, Object>();
        props.put(BUFFER_OUTPUT, bufferOutput);
        props.put(SYNC_WRITES, Boolean.toString(syncWrites));
        props.put(SYNC_BATCH_SIZE, Integer.toString(syncBatchSize));
        props.put(SYNC_TIME, Integer.toString(syncTime));
        props.put(GLOBAL_STORE_CAPACITY, Integer.toString(globalStoreCapacity));
        props.put(MAX_UNACKED_SIZE, Integer.toString(maxUnackedSize));
        props.put(USE_JMS_ENGINE, Boolean.toString(useJMSEngine));
        props.put(QUEUE_WINDOW_SIZE, Integer.toString(queueWindowSize));
        props.put(AUTO_ACK_COUNT, Integer.toString(autoAckCount));
        props.put(ENABLE_SHARED_DURABLE, Boolean.toString(enableSharedDurable));
        props.put(RANDOMISE_R_NAMES, Boolean.toString(randomiseRNames));
        props.put(MAX_REDELIVERY, Integer.toString(muleMqMaxRedelivery));
        props.put(MESSAGE_THREAD_POOL_SIZE, Integer.toString(messageThreadPoolSize));
        props.put(DISC_ON_CLUSTER_FAILURE, Boolean.toString(discOnClusterFailure));
        props.put(INITIAL_RETRY_COUNT, Integer.toString(initialRetryCount));
        props.put(RETRY_COMMIT, Boolean.toString(retryCommit));
        props.put(ENABLE_MULTIPLEXED_CONNECTIONS, Boolean.toString(enableMultiplexedConnections));

        // if the user used the connectionFactoryProperties map, these will override
        // the properties on the connector
        Map<String, Object> connectionFactoryProperties = getConnectionFactoryProperties();
        if (connectionFactoryProperties != null)
        {
            props.putAll(connectionFactoryProperties);
        }

        try
        {
            // use reflection to set the properties on the connection factory
            Method setPropertiesMethod = connectionFactory.getClass().getMethod("setProperties",
                Hashtable.class);
            setPropertiesMethod.invoke(connectionFactory, props);
        }
        catch (Exception e)
        {
            logger.error("Can not set properties on the MuleMQ connection factory " + e);
        }
    }

    // returns the connection factory class name as a string. This method will be
    // used by getDefaultConnectionFactory() to acquire the appropriate class to
    // initialise
    protected String getMuleMQFactoryClass()
    {
        return MULEMQ_CONNECTION_FACTORY_CLASS;
    }

    public String getRealmURL()
    {
        return realmURL;
    }

    public void setRealmURL(String realmURL)
    {
        this.realmURL = realmURL;
        if (realmURL != null)
        {
            String[] realms = realmURL.split(",");
            if (realms != null && realms.length > 1)
            {
                this.setInCluster(true);
            }
        }
    }

    public String getBufferOutput()
    {
        return bufferOutput;
    }

    public void setBufferOutput(String bufferOutput)
    {
        this.bufferOutput = bufferOutput;
    }

    public boolean isSyncWrites()
    {
        return syncWrites;
    }

    public void setSyncWrites(boolean syncWrites)
    {
        this.syncWrites = syncWrites;
    }

    public int getSyncBatchSize()
    {
        return syncBatchSize;
    }

    public void setSyncBatchSize(int syncBatchSize)
    {
        this.syncBatchSize = syncBatchSize;
    }

    public int getSyncTime()
    {
        return syncTime;
    }

    public void setSyncTime(int syncTime)
    {
        this.syncTime = syncTime;
    }

    public int getGlobalStoreCapacity()
    {
        return globalStoreCapacity;
    }

    public void setGlobalStoreCapacity(int globalStoreCapacity)
    {
        this.globalStoreCapacity = globalStoreCapacity;
    }

    public int getMaxUnackedSize()
    {
        return maxUnackedSize;
    }

    public void setMaxUnackedSize(int maxUnackedSize)
    {
        this.maxUnackedSize = maxUnackedSize;
    }

    public boolean isUseJMSEngine()
    {
        return useJMSEngine;
    }

    public void setUseJMSEngine(boolean useJMSEngine)
    {
        this.useJMSEngine = useJMSEngine;
    }

    public int getQueueWindowSize()
    {
        return queueWindowSize;
    }

    public void setQueueWindowSize(int queueWindowSize)
    {
        this.queueWindowSize = queueWindowSize;
    }

    public int getAutoAckCount()
    {
        return autoAckCount;
    }

    public void setAutoAckCount(int autoAckCount)
    {
        this.autoAckCount = autoAckCount;
    }

    public boolean isEnableSharedDurable()
    {
        return enableSharedDurable;
    }

    public void setEnableSharedDurable(boolean enableSharedDurable)
    {
        this.enableSharedDurable = enableSharedDurable;
    }

    public boolean isRandomiseRNames()
    {
        return randomiseRNames;
    }

    public void setRandomiseRNames(boolean randomiseRNames)
    {
        this.randomiseRNames = randomiseRNames;
    }

    public int getMessageThreadPoolSize()
    {
        return messageThreadPoolSize;
    }

    public void setMessageThreadPoolSize(int messageThreadPoolSize)
    {
        this.messageThreadPoolSize = messageThreadPoolSize;
    }

    public boolean isDiscOnClusterFailure()
    {
        return discOnClusterFailure;
    }

    public void setDiscOnClusterFailure(boolean discOnClusterFailure)
    {
        this.discOnClusterFailure = discOnClusterFailure;
    }

    public int getInitialRetryCount()
    {
        return initialRetryCount;
    }

    public void setInitialRetryCount(int initialRetryCount)
    {
        this.initialRetryCount = initialRetryCount;
    }

    public int getMuleMqMaxRedelivery()
    {
        return muleMqMaxRedelivery;
    }

    public void setMuleMqMaxRedelivery(int mulqMqMaxRedelivery)
    {
        this.muleMqMaxRedelivery = mulqMqMaxRedelivery;
    }

    public void setRetryCommit(boolean retryCommit)
    {
        this.retryCommit = retryCommit;
    }

    public boolean isRetryCommit()
    {
        return retryCommit;
    }

    public boolean isEnableMultiplexedConnections()
    {
        return enableMultiplexedConnections;
    }

    public void setEnableMultiplexedConnections(boolean enableMultiplexedConnections)
    {
        this.enableMultiplexedConnections = enableMultiplexedConnections;
    }

    public boolean isInCluster()
    {
        return inCluster;
    }

    public void setInCluster(boolean inCluster)
    {
        this.inCluster = inCluster;
    }

    public void onException(JMSException jmsException)
    {
        Throwable th = ExceptionHelper.getRootException(jmsException);
        if (th == null) th = jmsException;
        String errMsg = th.getMessage();

        if (errMsg.contains("Channel is full :"))
        {
            if(logger.isWarnEnabled())
            {
                // TODO : externalize strings
                StringBuffer msg = new StringBuffer("MuleMQJmsConnector.onException() received exception: ");
                msg.append(th.getMessage());
                msg.append("Older Messages will be discarded by MULE MQ.To prevent message loss use transacted outbound-endpoint");
                msg.append("Refer to 'Queue Capacity' at http://www.mulesoft.org/display/MQ/Configuring+Mule+MQ#ConfiguringMuleMQ-ConfiguringQueues");
                // This error does not mean that connection has been closed. Log Capacity
                // is full warn and return.
                logger.warn(msg.toString(),th);
            }
        }
        else if (this.isInCluster() && errMsg.contains("Disconnected from :"))
        {
            // TODO : externalize strings
            StringBuffer msg = new StringBuffer("MuleMQJmsConnector.onException() received exception: ");
            msg.append(th.getMessage());
            msg.append("If using Mule MQ in a cluster Mule ESB will reconnect automatically in a few seconds");
            // Nothing to do here, log error and return
            logger.warn(msg.toString(),th);
        }
        else if (this.isInCluster() && errMsg.contains("Reconnected to :"))
        {
            // TODO : externalize strings
            StringBuffer msg = new StringBuffer("MuleMQJmsConnector.onException() received exception: ");
            msg.append(th.getMessage());
            msg.append("If using Mule MQ in a cluster Mule ESB will reconnect automatically in a few seconds");
            // Nothing to do here, log message and return
            logger.warn(msg.toString(),th);
        }
        else
        {
            // This is connection error in a single node server. Follow regular
            // connection error logic
            super.onException(jmsException);
        }
    }
}
TOP

Related Classes of org.mule.transport.jms.mulemq.MuleMQJmsConnector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.