All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kaleidofoundry.messaging.jms.AbstractJmsTransport Maven / Gradle / Ivy

/*  
 * Copyright 2008-2021 the original author or authors 
 *
 * Licensed 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.kaleidofoundry.messaging.jms;

import static org.kaleidofoundry.messaging.TransportContextBuilder.JMS_CONNECTION_FACTORY_PASSWORD;
import static org.kaleidofoundry.messaging.TransportContextBuilder.JMS_CONNECTION_FACTORY_URL;
import static org.kaleidofoundry.messaging.TransportContextBuilder.JMS_CONNECTION_FACTORY_USER;
import static org.kaleidofoundry.messaging.TransportContextBuilder.JMS_SESSION_ACKNOLEDGE_MODE;
import static org.kaleidofoundry.messaging.TransportContextBuilder.JMS_SESSION_TRANSACTED;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import javax.jms.TemporaryTopic;
import javax.jms.Topic;

import org.kaleidofoundry.core.context.RuntimeContext;
import org.kaleidofoundry.core.lang.annotation.NotNull;
import org.kaleidofoundry.core.util.StringHelper;
import org.kaleidofoundry.messaging.AbstractTransport;
import org.kaleidofoundry.messaging.Transport;
import org.kaleidofoundry.messaging.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Abstract Jms Transport
 * 
 * @author jraduget
 */
public abstract class AbstractJmsTransport extends AbstractTransport implements
	Transport {

   static final Logger LOGGER = LoggerFactory.getLogger(AbstractJmsTransport.class);

   final List sessions;
   final List connections;

   /**
    * @param context
    * @throws TransportException
    */
   public AbstractJmsTransport(final RuntimeContext context) throws TransportException {
	super(context);

	checkContext();

	// Memorize user session and connections
	sessions = Collections.synchronizedList(new ArrayList());
	connections = Collections.synchronizedList(new ArrayList());

   }

   /**
    * @return Current connection factory
    * @throws TransportException
    */
   protected abstract CF getConnectionFactory() throws TransportException;

   /**
    * @param session
    * @param name
    * @return Destination {@link Queue} / {@link Topic} / {@link TemporaryQueue} / {@link TemporaryTopic}
    * @throws TransportException
    */
   protected abstract D getDestination(Session session, String name) throws TransportException;

   /**
    * Consistency check
    * 
    * @throws TransportException
    */
   protected abstract void checkContext();

   /**
    * JMS connection creation
    * 
    * @return
    * @throws TransportException
    */
   @SuppressWarnings("unchecked")
   public C createConnection() throws TransportException {

	try {
	   final Connection connection;

	   // create connection with default jndi user information
	   if (StringHelper.isEmpty(getUser())) {
		connection = getConnectionFactory().createConnection();
	   }
	   // create connection with custom user / password configured
	   else {
		connection = getConnectionFactory().createConnection(getUser(), getPassword());
	   }
	   connections.add(connection);

	   return (C) connection;
	} catch (final JMSException jmse) {
	   throw new TransportException("messaging.transport.jms.connection.create", jmse);
	}
   }

   /**
    * Create a jms session with an existing connection
    * Regarding the transport configuration :
    * 
    *
  • This session could be transactional or not
  • *
  • This session could be shared between thread or not
  • *
  • The messages acknowledged policies could be set
  • *
  • The open session (which have not been closed) are memorized, and could be cleaned and closed when transport is closed
  • *
* * @return a new jms session * @throws TransportException */ public Session createSession(@NotNull Connection connection) throws TransportException { try { // User session for transactional use final Session session = connection.createSession(isSessionTransacted(), getAcknowledgeMode()); sessions.add(session); return session; } catch (final JMSException jmse) { throw new TransportException("messaging.transport.jms.session.create", jmse); } } /** * close the given connection * * @param conn * @throws TransportException */ public void closeConnection(final Connection conn) throws TransportException { if (conn == null) { return; } try { conn.close(); connections.remove(conn); } catch (final JMSException jmse) { throw new TransportException("messaging.transport.jms.connection.close", jmse); } } /** * close the given session * * @param session * @throws TransportException */ public void closeSession(final Session session) throws TransportException { if (session == null) { return; } try { session.close(); sessions.remove(session); } catch (final JMSException jmse) { throw new TransportException("messaging.transport.jms.session.close", jmse); } } /* * (non-Javadoc) * @see org.kaleidofoundry.messaging.TransportMessaging#close() */ public void close() throws TransportException { super.close(); Iterator connIterator = connections.iterator(); while (connIterator.hasNext()) { try { Connection conn = connIterator.next(); conn.close(); connIterator.remove(); } catch (final JMSException jmse) { throw new TransportException("messaging.transport.jms.connection.close", jmse); } } Iterator sessionIterator = sessions.iterator(); while (sessionIterator.hasNext()) { try { Session session = sessionIterator.next(); session.close(); sessionIterator.remove(); } catch (final JMSException jmse) { throw new TransportException("messaging.transport.jms.session.close", jmse); } } } /** * If not specified in context configuration, return false * * @return true if session is transacted, false otherwise * @see JmsMessagingConstants.PATH_KEY_SessionTransacted */ public boolean isSessionTransacted() { final String strSessionTransacted = context.getString(JMS_SESSION_TRANSACTED); return Boolean.parseBoolean(strSessionTransacted); } /** * You can't specify ACKNOWLEDGE value if session is transacted * * @return Session.AUTO_ACKNOWLEDGE (1) if not specified, and otherwise : *
    *
  • 1 is equivalent to Session.AUTO_ACKNOWLEDGE, automatic acknowledgment if method receive() in listener consumer don't * throws exception
  • *
  • 2 is equivalent to Session.CLIENT_ACKNOWLEDGE, client acknowledge by explicit calling Message.acknowledge(). use it with * care...
  • *
  • 3 is equivalent to Session.DUPS_OK_ACKNOWLEDGE, lazily acknowledge the delivery of messages (duplicate messages if the JMS * provider fails)
  • *
* @see JmsMessagingConstants.PATH_KEY_AcknowledgeMode * @see #isSessionTransacted() * @see javax.jms.Session.AUTO_ACKNOWLEDGE * @see javax.jms.Session.CLIENT_ACKNOWLEDGE * @see javax.jms.Session.DUPS_OK_ACKNOWLEDGE */ public int getAcknowledgeMode() { final String strAcknowledgeMode = context.getString(JMS_SESSION_ACKNOLEDGE_MODE); if (!StringHelper.isEmpty(strAcknowledgeMode)) { try { final int acknowledgeMode = Integer.valueOf(strAcknowledgeMode); return acknowledgeMode; } catch (final NumberFormatException nfe) { } } return Session.AUTO_ACKNOWLEDGE; } /** * @return ConnectionFactory url (for non jndi access) */ public String getURL() { return context.getString(JMS_CONNECTION_FACTORY_URL); } /** * @return ConnectionFactory user name */ public String getUser() { return context.getString(JMS_CONNECTION_FACTORY_USER); } /** * @return ConnectionFactory user password */ public String getPassword() { return context.getString(JMS_CONNECTION_FACTORY_PASSWORD); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy