/* * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. 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 org.wso2.carbon.transport.jms.factory; import org.wso2.carbon.transport.jms.exception.JMSConnectorException; import java.util.Properties; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Session; /** * {@link JMSConnectionFactory} connector, session, consumer, producer caching implementation. This class can be used * if needed to cache connections. */ public class CachedJMSConnectionFactory extends JMSConnectionFactory { /** * Parameter for passing in cache level. */ public static final String PARAM_CACHE_LEVEL = "transport.jms.CacheLevel"; /** * Do not cache any JMS resources between tasks (when sending) or JMS CF's * (when sending) */ public static final int CACHE_NONE = 0; /** * Cache only the JMS connection between tasks (when receiving), or JMS CF's * (when sending) */ public static final int CACHE_CONNECTION = 1; /** * Cache only the JMS connection and Session between tasks (receiving), or * JMS CF's (sending) */ public static final int CACHE_SESSION = 2; /** * Cache the JMS connection, Session and Consumer between tasks when * receiving */ public static final int CACHE_CONSUMER = 3; /** * Cache the JMS connection, Session and Producer within a * JMSConnectionFactory when sending */ public static final int CACHE_PRODUCER = 4; /** * Indicates cache level given by the user. */ private int cacheLevel = 0; /** * {@link Connection} instance representing cached jms connection instance. */ private Connection cachedConnection = null; /** * {@link Session} instance representing cached jms session instance. */ private Session cachedSession = null; /** * {@link MessageConsumer} instance representing cached jms message consumer instance. */ private MessageConsumer cachedMessageConsumer = null; /** * {@link MessageProducer} instance representing cached jms message producer instance. */ private MessageProducer cachedMessageProducer = null; /** * Constructor to create CachedJMSConnectionFactory instance. * * @param properties Property values required to initialize the connection factory * @throws JMSConnectorException Thrown when initial context factory is not found. */ public CachedJMSConnectionFactory(Properties properties) throws JMSConnectorException { super(properties); setValues(properties); } private void setValues(Properties properties) { String cacheLevel = properties.getProperty(PARAM_CACHE_LEVEL); if (null != cacheLevel && !cacheLevel.isEmpty()) { this.cacheLevel = Integer.parseInt(cacheLevel); } else { this.cacheLevel = CACHE_NONE; } } /** * {@inheritDoc} */ @Override public ConnectionFactory getConnectionFactory() throws JMSConnectorException { return super.getConnectionFactory(); } /** * {@inheritDoc} */ @Override public Connection createConnection() throws JMSException { Connection connection; if (cacheLevel >= CACHE_CONNECTION) { if (cachedConnection == null) { connection = super.createConnection(); cachedConnection = connection; } else { connection = cachedConnection; } } else { connection = super.createConnection(); } return connection; } /** * {@inheritDoc} */ @Override public Connection createConnection(String userName, String password) throws JMSException { Connection connection; if (userName == null && password == null) { connection = createConnection(); } else { if (cachedConnection == null) { connection = super.createConnection(userName, password); cachedConnection = connection; } else { connection = cachedConnection; } try { connection.start(); } catch (JMSException e) { if (cachedConnection != null) { resetCache(); connection = createConnection(userName, password); } else { throw e; } } } return connection; } /** * {@inheritDoc} */ @Override public Session getSession(Connection connection) throws JMSConnectorException { if (cachedSession == null) { return createSession(connection); } else { return cachedSession; } } /** * {@inheritDoc} */ @Override public Session createSession(Connection connection) throws JMSConnectorException { Session session; if (cacheLevel >= CACHE_SESSION) { if (cachedSession == null) { session = super.createSession(connection); cachedSession = session; } else { session = cachedSession; } } else { session = super.createSession(connection); } return session; } @Override public MessageConsumer getMessageConsumer(Session session, Destination destination) throws JMSConnectorException { MessageConsumer messageConsumer; if (cachedMessageConsumer == null) { messageConsumer = createMessageConsumer(session, destination); } else { messageConsumer = cachedMessageConsumer; } return messageConsumer; } /** * {@inheritDoc} */ @Override public MessageConsumer createMessageConsumer(Session session, Destination destination) throws JMSConnectorException { MessageConsumer messageConsumer; if (cacheLevel >= CACHE_CONSUMER) { if (cachedMessageConsumer == null) { messageConsumer = super.createMessageConsumer(session, destination); cachedMessageConsumer = messageConsumer; } else { messageConsumer = cachedMessageConsumer; } } else { messageConsumer = super.createMessageConsumer(session, destination); } return messageConsumer; } /** * {@inheritDoc} */ @Override public MessageProducer getMessageProducer(Session session, Destination destination) throws JMSConnectorException { MessageProducer messageProducer; if (cachedMessageProducer == null) { messageProducer = createMessageProducer(session, destination); } else { messageProducer = cachedMessageProducer; } return messageProducer; } /** * {@inheritDoc} */ @Override public MessageProducer createMessageProducer(Session session, Destination destination) throws JMSConnectorException { MessageProducer messageProducer; if (this.cacheLevel >= CACHE_PRODUCER) { if (cachedMessageProducer == null) { messageProducer = super.createMessageProducer(session, destination); cachedMessageProducer = messageProducer; } else { messageProducer = cachedMessageProducer; } } else { messageProducer = super.createMessageProducer(session, destination); } return messageProducer; } public void closeConnection() throws JMSException { if (cachedConnection != null) { cachedConnection.close(); } } /** * {@inheritDoc} */ @Override public void closeConnection(Connection connection) throws JMSConnectorException { try { connection.close(); } catch (JMSException e) { throw new JMSConnectorException("JMS Exception while closing the connection.", e); } finally { if (cacheLevel >= CACHE_CONNECTION && cachedConnection != null && cachedConnection.equals(connection)) { cachedConnection = null; } } } /** * {@inheritDoc} */ @Override public void closeMessageConsumer(MessageConsumer messageConsumer) throws JMSConnectorException { try { messageConsumer.close(); } catch (JMSException e) { throw new JMSConnectorException("JMS Exception while closing the consumer.", e); } finally { if (cacheLevel >= CACHE_CONSUMER && cachedMessageConsumer != null && cachedMessageConsumer.equals(messageConsumer)) { cachedMessageConsumer = null; } } } /** * {@inheritDoc} */ @Override public void closeMessageProducer(MessageProducer messageProducer) throws JMSConnectorException { try { messageProducer.close(); } catch (JMSException e) { throw new JMSConnectorException("JMS Exception while closing the producer.", e); } finally { if (cacheLevel >= CACHE_PRODUCER && cachedMessageProducer != null && cachedMessageProducer.equals(messageProducer)) { cachedMessageProducer = null; } } } /** * {@inheritDoc} */ @Override public void closeSession(Session session) throws JMSConnectorException { try { session.close(); } catch (JMSException e) { throw new JMSConnectorException("JMS Exception while closing the session.", e); } finally { if (cacheLevel >= CACHE_SESSION && cachedSession != null && cachedSession.equals(session)) { cachedSession = null; } } } /** * Rests all elements in cache. * * @throws JMSException Thrown when closing jms connection, session, consumer and producer */ private void resetCache() throws JMSException { if (cachedMessageConsumer != null) { cachedMessageConsumer.close(); cachedMessageConsumer = null; } if (cachedMessageProducer != null) { cachedMessageProducer.close(); cachedMessageProducer = null; } if (cachedSession != null) { cachedSession.close(); cachedSession = null; } if (cachedConnection != null) { cachedConnection.close(); cachedConnection = null; } } }