package org.jboss.internal.soa.esb.command;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.naming.Context;
import javax.naming.NamingException;
import org.apache.log4j.Logger;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.helpers.NamingContextException;
import org.jboss.soa.esb.helpers.NamingContextPool;
import org.jboss.soa.esb.util.Util;
/**
* JMS based Command Queue implementation. <p/> This code was simply pulled from
* the GpListener.
*
* @author <a href="mailto:tom.fennelly@jboss.com">tom.fennelly@jboss.com</a>
* @since Version 4.0
*/
public class JmsCommandQueue implements CommandQueue
{
private static Logger logger = Logger.getLogger(JmsCommandQueue.class);
public static final String COMMAND_CONN_FACTORY = "commandConnFactoryClass";
public static final String COMMAND_JNDI_URL = "commandJndiURL";
public static final String COMMAND_JNDI_CONTEXT_FACTORY = "commandJndiContextFactory";
public static final String COMMAND_JNDI_PKG_PREFIX = "commandJndiUrlPkgPrefix";
public static final String COMMAND_IS_TOPIC = "commandIsTopic";
public static final String COMMAND_JNDI_NAME = "commandJndiName";
public static final String COMMAND_MSG_SELECTOR = "messageSelector";
private MessageConsumer m_oCmdSrc;
private Session m_oJmsSess;
private Connection m_oJmsConn;
public void open (ConfigTree config) throws CommandQueueException
{
try
{
initialiseJMS(config);
}
catch (Exception e)
{
throw new CommandQueueException(
"Failed to initialise JMS Command Queue.", e);
}
}
public void close () throws CommandQueueException
{
if (null != m_oJmsSess)
{
try
{
m_oJmsSess.close();
}
catch (JMSException eS)
{/* Tried my best - Just continue */
}
}
if (null != m_oJmsConn)
{
try
{
m_oJmsConn.close();
}
catch (JMSException eC)
{/* Tried my best - Just continue */
}
}
}
public String receiveCommand (long timeout) throws CommandQueueException
{
try
{
Message jmsMessage = m_oCmdSrc.receive(timeout);
if (null == jmsMessage) return null;
if (jmsMessage instanceof TextMessage)
{
return ((TextMessage) jmsMessage).getText();
}
else
{
logger
.warn("Message in command queue IGNORED - should be instanceof TextMessage");
}
}
catch (Exception e)
{
throw new CommandQueueException(
"Exception receiving message from JMS Command Queue.", e);
}
return null;
}
private void initialiseJMS (ConfigTree p_oP) throws ConfigurationException, JMSException, NamingException, NamingContextException
{
// Only check for JMS attributes if a queue JNDI name was specified
String sJndiName = p_oP.getAttribute(COMMAND_JNDI_NAME);
if (!Util.isNullString(sJndiName))
{
Properties environment = new Properties();
Map<String, Object> oNewAtts = new HashMap<String, Object>();
oNewAtts.put(COMMAND_JNDI_NAME, sJndiName);
String sJndiURL = obtainAtt(p_oP, COMMAND_JNDI_URL,"");
environment.put(Context.PROVIDER_URL, sJndiURL);
oNewAtts.put(COMMAND_JNDI_URL, sJndiURL);
String sJndiContextFactory = obtainAtt(p_oP,
COMMAND_JNDI_CONTEXT_FACTORY,"");
environment.put(Context.OBJECT_FACTORIES, sJndiContextFactory);
oNewAtts.put(COMMAND_JNDI_CONTEXT_FACTORY, sJndiContextFactory);
String sJndiPkgPrefix = obtainAtt(p_oP, COMMAND_JNDI_PKG_PREFIX,"");
environment.put(Context.URL_PKG_PREFIXES, sJndiPkgPrefix);
oNewAtts.put(COMMAND_JNDI_PKG_PREFIX, sJndiPkgPrefix);
Context oJndiCtx = NamingContextPool.getNamingContext(environment);
try
{
String sFactClass = obtainAtt(p_oP, COMMAND_CONN_FACTORY,
"ConnectionFactory");
oNewAtts.put(COMMAND_CONN_FACTORY, sFactClass);
if (Util.isNullString(sFactClass))
sFactClass = "ConnectionFactory";
Object oFactCls = null;
try
{
oFactCls = oJndiCtx.lookup(sFactClass);
} catch (NamingException ne) {
oJndiCtx = NamingContextPool.replaceNamingContext(oJndiCtx, environment);
try {
oFactCls = oJndiCtx.lookup(sFactClass);
} catch (NamingException ex) {
throw new ConfigurationException(ex);
}
}
String sMsgSelector = p_oP.getAttribute(COMMAND_MSG_SELECTOR);
if (null != sMsgSelector)
oNewAtts.put(COMMAND_MSG_SELECTOR, sMsgSelector);
boolean bIsTopic = Boolean.parseBoolean(obtainAtt(p_oP,
COMMAND_IS_TOPIC, "false"));
if (bIsTopic)
{
TopicConnectionFactory tcf = (TopicConnectionFactory) oFactCls;
TopicConnection oTC = tcf.createTopicConnection();
TopicSession oSess = oTC.createTopicSession(false,
TopicSession.AUTO_ACKNOWLEDGE);
Topic oTopic = null;
try
{
oTopic = (Topic) oJndiCtx.lookup(sJndiName);
}
catch (NamingException ne)
{
oTopic = oSess.createTopic(sJndiName);
}
m_oJmsConn = oTC;
m_oJmsSess = oSess;
oTC.start();
m_oCmdSrc = oSess.createSubscriber(oTopic, sMsgSelector, true);
}
else
{
QueueConnectionFactory qcf = (QueueConnectionFactory) oFactCls;
QueueConnection oQC = qcf.createQueueConnection();
QueueSession oSess = oQC.createQueueSession(false,
TopicSession.AUTO_ACKNOWLEDGE);
javax.jms.Queue oQ = null;
try
{
oQ = (javax.jms.Queue) oJndiCtx.lookup(sJndiName);
}
catch (NamingException ne)
{
oQ = oSess.createQueue(sJndiName);
}
oQC.start();
m_oJmsConn = oQC;
m_oJmsSess = oSess;
m_oCmdSrc = oSess.createReceiver(oQ, sMsgSelector);
}
}
finally
{
NamingContextPool.releaseNamingContext(oJndiCtx) ;
}
}
}
/**
* Find an attribute in the tree (arg 0) or assign default value (arg 2)
*
* @param p_oP
* ConfigTree - look for attributes in this Element only
* @param p_sAtt
* String - Name of attribute to find
* @param p_sDefault
* String -default value if requested attribute is not there
* @return String - value of attribute, or default value (if null)
* @throws ConfigurationException -
* If requested attribute not found and no default value
* supplied by invoker
*/
private String obtainAtt (ConfigTree p_oP, String p_sAtt, String p_sDefault)
throws ConfigurationException
{
String sVal = p_oP.getAttribute(p_sAtt);
if ((null == sVal) && (null == p_sDefault))
throw new ConfigurationException(
"Missing or invalid <" + p_sAtt + "> attribute");
return (null != sVal) ? sVal : p_sDefault;
} // ________________________________
}