/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* (C) 2005-2007,
* @author David Fry <dfry@redhat.com>
* @author Kurt Stam <kurt.stam@jboss.com>
*
*/
package org.jboss.soa.esb.oracle.aq;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.XAConnectionFactory;
import javax.jms.XAQueueConnectionFactory;
import javax.jms.XATopicConnectionFactory;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import javax.sql.DataSource;
import javax.sql.XADataSource;
import oracle.jms.AQjmsFactory;
import oracle.jms.AQjmsSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mockejb.jndi.MockContextFactory;
public class AQInitialContextFactory implements InitialContextFactory {
/** The Oracle Queue connection factory name */
public static final String QUEUE_CONNECTION_FACTORY = "QueueConnectionFactory";
/** The Oracle XA Queue connection factory name */
public static final String XA_QUEUE_CONNECTION_FACTORY = "XAQueueConnectionFactory";
/** The Oracle Topic connection factory name */
public static final String TOPIC_CONNECTION_FACTORY = "TopicConnectionFactory";
/** The Oracle XA Topic connection factory name */
public static final String XA_TOPIC_CONNECTION_FACTORY = "XATopicConnectionFactory";
/** The Oracle Connection factory name */
public static final String CONNECTION_FACTORY = "ConnectionFactory";
/** The Oracle XA Connection factory name */
public static final String XA_CONNECTION_FACTORY = "XAConnectionFactory";
public static final String DB_DATASOURCE = "java.naming.oracle.aq.datasource";
public static final String DB_USER = "java.naming.oracle.aq.user";
public static final String DB_PASSWD = "java.naming.oracle.aq.password";
public static final String DB_SERVER = "java.naming.oracle.aq.server";
public static final String DB_INSTANCE = "java.naming.oracle.aq.instance";
public static final String DB_PORT = "java.naming.oracle.aq.port";
public static final String DB_SCHEMA = "java.naming.oracle.aq.schema";
public static final String DB_DRIVER = "java.naming.oracle.aq.driver";
public static final String DB_CONNECTION_URL = "java.naming.oracle.aq.url";
protected static Log log = LogFactory
.getLog(AQInitialContextFactory.class);
protected Hashtable props;
protected String dbuser;
protected String dbpass;
protected String aqServerName;
protected String aqServerDBInst;
protected String aqServerPort;
protected String aqDBDriver;
protected String aqSchemaName;
protected int aqServerPortNumber = 1521;
protected String aqConnectionUrl;
private void addAQDestinationContext(Context context) throws NamingException {
// lookup and cache the queues
QueueConnectionFactory queueFactory;
QueueConnection queueConnection = null;
TopicConnectionFactory topicFactory;
TopicConnection topicConnection = null;
AQjmsSession session = null;
try {
// create a datasource to use - datasources can keep the
// username/password for later use
DataSource ds = null;
XADataSource xaDs = null;
try {
if (aqConnectionUrl != null)
{
ds = AQUtil.getSQLDataSource(aqConnectionUrl, dbuser, dbpass);
xaDs = AQUtil.getXASQLDataSource(aqConnectionUrl, dbuser, dbpass);
}
else
{
ds = AQUtil.getSQLDataSource( aqServerName, aqServerDBInst, aqServerPortNumber, aqDBDriver, dbuser, dbpass);
xaDs = AQUtil.getXASQLDataSource(aqServerName, aqServerDBInst, aqServerPortNumber, aqDBDriver, dbuser, dbpass);
}
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}
XAConnectionFactory factory = AQjmsFactory.getXAConnectionFactory(xaDs);
context.rebind(XA_CONNECTION_FACTORY, factory);
context.rebind("KURTSTAM", new String("hello"));
// create the connection factory
ConnectionFactory connectionFactory = AQjmsFactory.getConnectionFactory(ds);
context.rebind(CONNECTION_FACTORY, connectionFactory);
// create the queue connection factory
queueFactory = AQjmsFactory.getQueueConnectionFactory(ds);
context.rebind(QUEUE_CONNECTION_FACTORY, queueFactory);
queueConnection = queueFactory.createQueueConnection();
session = (AQjmsSession) queueConnection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
// create the queue XA connection factory
XAQueueConnectionFactory xaQueueConnectionFactory = AQjmsFactory.getXAQueueConnectionFactory(xaDs);
context.rebind(XA_QUEUE_CONNECTION_FACTORY, xaQueueConnectionFactory);
// create the topic XA connection factory
XATopicConnectionFactory xaTopicConnectionFactory = AQjmsFactory.getXATopicConnectionFactory(xaDs);
context.rebind(XA_TOPIC_CONNECTION_FACTORY, xaTopicConnectionFactory);
// create the topic connection factory
topicFactory = AQjmsFactory.getTopicConnectionFactory(ds);
context.rebind(TOPIC_CONNECTION_FACTORY, topicFactory);
topicConnection = topicFactory.createTopicConnection();
session = (AQjmsSession) topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
List<DestinationInfo> list = AQUtil.getDestinationInfoList(ds, aqSchemaName);
// for each queue
Iterator<DestinationInfo> iter = list.iterator();
while (iter.hasNext()) {
DestinationInfo di = iter.next();
if(log.isDebugEnabled()) log.debug("Loading Destination: " + di);
// register normal queue
registerDestination(context, session, di);
}
} catch (JMSException e) {
log.error("JMSException exception", e);
throw new RuntimeException("JMSException exception", e);
} finally {
try {
if (session != null)
session.close();
if (queueConnection != null)
queueConnection.close();
if (topicConnection != null)
topicConnection.close();
} catch (JMSException e) {
log.error("JMSEx while cleaning up", e);
}
}
}
private void registerDestination(Context context, AQjmsSession session, DestinationInfo di) {
if (di == null) {
log.warn("Warning: registerDestination called with null DestinationInfo.");
return;
}
try {
if (di.isMultipleSubscribers()) {
Topic topic = session.getTopic(di.getOwner(), di.getQueueName());
context.rebind(topic.getTopicName(), topic);
} else {
Queue queue = session.getQueue(di.getOwner(), di.getQueueName());
context.rebind(queue.getQueueName(), queue);
}
} catch (Exception e) {
// we want to eat any exceptions associated with looking up
// the queues from the database
log.warn("Warning. Error while looking up destination: " + e);
}
}
public void init(Hashtable<?, ?> env) {
dbuser = (String) env.get(AQInitialContextFactory.DB_USER);
dbpass = (String) env.get(AQInitialContextFactory.DB_PASSWD);
aqConnectionUrl = (String) env.get(AQInitialContextFactory.DB_CONNECTION_URL);
if (aqConnectionUrl == null )
{
aqServerName = (String) env.get(AQInitialContextFactory.DB_SERVER);
aqServerDBInst = (String) env.get(AQInitialContextFactory.DB_INSTANCE);
aqDBDriver = (String) env.get(AQInitialContextFactory.DB_DRIVER);
aqSchemaName = (String) env.get(AQInitialContextFactory.DB_SCHEMA);
aqServerPort = (String) env.get(AQInitialContextFactory.DB_PORT);
if (aqServerPort != null)
{
try
{
aqServerPortNumber = Integer.parseInt(aqServerPort);
}
catch (NumberFormatException e)
{
log.error("caught exception converting port", e);
}
}
}
}
@SuppressWarnings("unused")
public Context getInitialContext(Hashtable<?,?> environment) throws NamingException {
init(environment);
Properties mockProperties = new Properties();
mockProperties.setProperty(Context.INITIAL_CONTEXT_FACTORY,MockContextFactory.class.getName());
mockProperties.setProperty(Context.URL_PKG_PREFIXES, "org.mockejb.jndi");
Context context = new InitialContext(mockProperties);
addAQDestinationContext(context);
return context;
}
public void setAqDBDriver(String aqDBDriver) {
this.aqDBDriver = aqDBDriver;
}
public void setAqSchemaName(String aqSchemaName) {
this.aqSchemaName = aqSchemaName;
}
public void setAqServerDBInst(String aqServerDBInst) {
this.aqServerDBInst = aqServerDBInst;
}
public void setAqServerName(String aqServerName) {
this.aqServerName = aqServerName;
}
public void setAqServerPort(String aqServerPort) {
this.aqServerPort = aqServerPort;
}
public void setAqServerPortNumber(int aqServerPortNumber) {
this.aqServerPortNumber = aqServerPortNumber;
}
public void setDbpass(String dbpass) {
this.dbpass = dbpass;
}
public void setDbuser(String dbuser) {
this.dbuser = dbuser;
}
public void setAqConnectionUrl(String url) {
aqConnectionUrl = url;
}
}