ghoward 2003/10/18 19:30:17
Modified: src/blocks/jms/java/org/apache/cocoon/components/jms
JMSConnectionImpl.java JMSConnection.java
JMSEventListener.java
src/blocks/jms/conf jmsconnection.xconf
Log:
- Make JNDI config generic enough for different providers.
- Allow startup of Cocoon if JNDI/JMS server is not found
- Remove sample defaults from code - only in demo config now
- fix some javadocs
- add comments to config
- had extra hot Thai food for dinner
Revision Changes Path
1.2 +107 -104
cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSConnectionImpl.java
Index: JMSConnectionImpl.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSConnectionImpl.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JMSConnectionImpl.java 14 Oct 2003 16:40:09 -0000 1.1
+++ JMSConnectionImpl.java 19 Oct 2003 02:30:17 -0000 1.2
@@ -68,45 +68,49 @@
import javax.naming.InitialContext;
import javax.naming.NamingException;
+import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.parameters.ParameterException;
-import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.thread.ThreadSafe;
/**
* JMSConnection properties container plus utilities.
*
- * <p>Parameters:</p>
+ * <p>Configuration:</p>
+ * <pre><jndi-info>
+ * <parameter name="" value=""/>
+ * <jndi-info></pre>
+ *
+ * <p>Other parameters:</p>
* <table>
* <tbody>
- * <tr><td>component </td><td>(required, null)</td></tr>
- * <tr><td>scheme </td><td>(rmi)</td></tr>
- * <tr><td>host </td><td>(localhost)</td></tr>
- * <tr><td>port </td><td>(for rmi 1099)</td></tr>
- * <tr><td>jndiname </td><td>("")</td></tr>
- *
<tr><td>context-factory</td><td>(org.exolab.jms.jndi.InitialContextFactory)</td></tr>
- * <tr><td>topic-factory </td><td>(JmsTopicConnectionFactory)</td></tr>
- * <tr><td>topic </td><td>(topic1)</td></tr>
- * <tr><td>ack-mode </td><td>(dups)</td></tr>
+ * <tr><td>topic-factory </td><td><i>(required, no default)</i></td></tr>
+ * <tr><td>topic </td><td><i>(required, no default)</i></td></tr>
+ * <tr><td>ack-mode </td><td>("dups")</td></tr>
+ * <tr><td>durable-subscription-id
</td><td><i>(optional)</i></td></tr>
* </tbody>
* </table>
*
* @version CVS $Id$
* @author <a href="mailto:[EMAIL PROTECTED]">haul</a>
*/
-public class JMSConnectionImpl implements Parameterizable, Disposable,
ThreadSafe, JMSConnection {
-
- // defaults to go with OpenJMS demo on localhost
- protected String contextFactoryName =
"org.exolab.jms.jndi.InitialContextFactory";
- protected String scheme = "rmi";
- protected String host = "localhost";
- protected String port = "";
- protected String jndiname = "";
- protected String topicFactoryName = "JmsTopicConnectionFactory";
- protected String topicName = "topic1";
+public class JMSConnectionImpl extends AbstractLogEnabled
+ implements Configurable,
+ Disposable,
+ ThreadSafe,
+ Initializable,
+ JMSConnection {
+
+ private boolean available = false;
+ protected String topicFactoryName;
+ protected String topicName;
protected String ackModeName = "dups";
- protected String durableSubscriptionID = null;
+ protected String durableSubscriptionID;
protected TopicConnection connection = null;
protected TopicSession session = null;
@@ -114,10 +118,10 @@
protected Topic topic = null;
protected int ackMode = Session.DUPS_OK_ACKNOWLEDGE;
protected Context context = null;
- protected TopicConnectionFactory topicConnectionFactory = null;
+ protected TopicConnectionFactory topicConnectionFactory;
-
- /**
+ private Parameters jndiParams;
+ /**
* Register a new TopicListener for this connection.
*
* @param listener
@@ -126,8 +130,13 @@
public synchronized void registerListener(
MessageListener listener,
String selector)
- throws JMSException, NamingException {
+ throws CascadingException, JMSException, NamingException {
+ if (!this.available) {
+ // Connection was not successfully initialized.
+ throw new CascadingException("Attempt to register Listener on
unavailable JMS Connection");
+ }
+
TopicSubscriber subscriber = null;
if (this.durableSubscriptionID != null) {
subscriber =
@@ -167,9 +176,6 @@
* @throws JMSException
*/
public synchronized TopicSession getSession() throws NamingException,
JMSException {
- if (this.session == null) {
- this.connect();
- }
return this.session;
}
@@ -179,20 +185,23 @@
* @return
* @throws NamingException
*/
- protected Context getContext() throws NamingException {
+ protected Context setupContext() throws NamingException {
- Hashtable properties = new Hashtable();
- properties.put(Context.INITIAL_CONTEXT_FACTORY,
this.contextFactoryName);
-
- String name = "";
- if (scheme.equals("rmi")) {
- name = this.jndiname;
+ String[] jndiKeys = jndiParams.getNames();
+ InitialContext ctx;
+ if (jndiKeys.length > 0) {
+ // Params specified in cocoon.xconf
+ Hashtable properties = null;
+ properties = new Hashtable();
+ for (int i = 0 ; i < jndiKeys.length ; i++) {
+
properties.put(jndiKeys[i],jndiParams.getParameter(jndiKeys[i],""));
+ }
+ ctx = new InitialContext(properties);
+ } else {
+ // Use jndi.properties from the classpath or container
+ ctx = new InitialContext();
}
-
- String url = scheme + "://" + host + ":" + port + "/" + name;
-
- properties.put(Context.PROVIDER_URL, url);
- return new InitialContext(properties);
+ return ctx;
}
@@ -204,11 +213,13 @@
*/
private void setupConnection() throws NamingException, JMSException {
// setup JMS connection
- this.context = this.getContext();
- this.topicConnectionFactory =
- (TopicConnectionFactory)
this.context.lookup(this.topicFactoryName);
- this.connection =
this.topicConnectionFactory.createTopicConnection();
- this.connection.start();
+ //this.context = this.getContext();
+ if (this.context != null) {
+ this.topicConnectionFactory =
+ (TopicConnectionFactory)
this.context.lookup(this.topicFactoryName);
+ this.connection =
this.topicConnectionFactory.createTopicConnection();
+ this.connection.start();
+ }
}
/**
@@ -217,21 +228,10 @@
* @throws JMSException
*/
private void setupSession() throws JMSException {
- this.session = connection.createTopicSession(false, this.ackMode);
- this.topic = session.createTopic(this.topicName);
- }
-
- /**
- * Setup connection and session for this connection.
- *
- * @throws NamingException
- * @throws JMSException
- */
- private void connect() throws NamingException, JMSException {
- if (this.connection == null)
- this.setupConnection();
- if (this.session == null)
- this.setupSession();
+ if (this.connection != null) {
+ this.session = connection.createTopicSession(false,
this.ackMode);
+ this.topic = session.createTopic(this.topicName);
+ }
}
/**
@@ -251,49 +251,32 @@
this.connection.close();
}
- /*
- * @see
org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
- */
- public void parameterize(Parameters parameters) throws
ParameterException {
-
- this.scheme = parameters.getParameter("scheme",
this.scheme).toLowerCase();
- if (scheme.equals("tcp") || scheme.equals("tcps")) {
- port = "3035";
- } else if (scheme.equals("http")) {
- port = "8080";
- } else if (scheme.equals("https")) {
- port = "8443";
- } else if (scheme.equals("rmi")) {
- port = "1099";
- }
- this.host = parameters.getParameter("host", this.host);
- this.port = parameters.getParameter("port", this.port);
- this.jndiname = parameters.getParameter("jndiname", this.jndiname);
- this.contextFactoryName =
- parameters.getParameter("context-factory",
this.contextFactoryName);
- this.topicFactoryName =
- parameters.getParameter("topic-factory", this.topicFactoryName);
- this.topicName = parameters.getParameter("topic", this.topicName);
- this.durableSubscriptionID =
- parameters.getParameter(
- "durable-subscription-id",
- this.durableSubscriptionID);
-
- this.ackModeName =
- parameters.getParameter("ack-mode",
this.ackModeName).toLowerCase();
- // see if an ack mode has been specified. If it hasn't
- // then assume CLIENT_ACKNOWLEDGE mode.
- this.ackMode = Session.CLIENT_ACKNOWLEDGE;
- if (this.ackModeName.equals("auto")) {
- this.ackMode = Session.AUTO_ACKNOWLEDGE;
- } else if (this.ackModeName.equals("dups")) {
- this.ackMode = Session.DUPS_OK_ACKNOWLEDGE;
- } else if (!this.ackModeName.equals("client")) {
- // ignore all ack modes, to test no acking
- this.ackMode = -1;
- }
+ public void configure(Configuration conf) throws ConfigurationException {
+ Parameters parameters =
Parameters.fromConfiguration(conf);
+ this.jndiParams =
Parameters.fromConfiguration(conf.getChild("jndi-info"));
+ this.topicFactoryName =
+ parameters.getParameter("topic-factory", null);
+ this.topicName = parameters.getParameter("topic", null);
+ this.durableSubscriptionID =
+ parameters.getParameter(
+ "durable-subscription-id",null);
+
+ this.ackModeName =
+ parameters.getParameter("ack-mode",
this.ackModeName).toLowerCase();
+ // see if an ack mode has been specified. If it hasn't
+ // then assume CLIENT_ACKNOWLEDGE mode.
+ this.ackMode = Session.CLIENT_ACKNOWLEDGE;
+ if (this.ackModeName.equals("auto")) {
+ this.ackMode = Session.AUTO_ACKNOWLEDGE;
+ } else if (this.ackModeName.equals("dups")) {
+ this.ackMode = Session.DUPS_OK_ACKNOWLEDGE;
+ } else if (!this.ackModeName.equals("client")) {
+ // ignore all ack modes, to test no acking
+ this.ackMode = -1;
+ }
}
+
/*
* @see org.apache.avalon.framework.activity.Disposable#dispose()
*/
@@ -304,5 +287,25 @@
} catch (NamingException e) {
}
}
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Initializable#initialize()
+ */
+ public void initialize() throws Exception {
+ try {
+ this.context = setupContext();
+ this.setupConnection();
+ this.setupSession();
+ this.available = true;
+ } catch (NamingException e) {
+ if (getLogger().isWarnEnabled()) {
+ getLogger().warn("Cannot get Initial Context. Is the JNDI
server reachable?",e);
+ }
+ } catch (JMSException e) {
+ if (getLogger().isWarnEnabled()) {
+ getLogger().warn("Failed to initialize JMS.",e);
+ }
+ }
+ }
}
1.2 +9 -2
cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSConnection.java
Index: JMSConnection.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSConnection.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JMSConnection.java 14 Oct 2003 16:40:09 -0000 1.1
+++ JMSConnection.java 19 Oct 2003 02:30:17 -0000 1.2
@@ -56,6 +56,8 @@
import javax.jms.TopicSession;
import javax.naming.NamingException;
+import org.apache.avalon.framework.CascadingException;
+
/**
* JMSConnection properties container plus utilities.
*
@@ -71,9 +73,14 @@
*
* @param listener
* @param string
+ *
+ * @throws CacadingException if the connection was not successfully
+ * initialized, JMSException or NamingException if errors occur during
+ * JMS methods. It is up to the MessageListener to determine how to
+ * handle this failure.
*/
void registerListener(MessageListener listener, String selector)
- throws JMSException, NamingException;
+ throws CascadingException, JMSException, NamingException;
/**
* Get a new TopicPublisher for this connection.
1.2 +40 -34
cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSEventListener.java
Index: JMSEventListener.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSEventListener.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JMSEventListener.java 14 Oct 2003 16:40:09 -0000 1.1
+++ JMSEventListener.java 19 Oct 2003 02:30:17 -0000 1.2
@@ -50,10 +50,14 @@
*/
package org.apache.cocoon.components.jms;
+import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
+import javax.naming.NamingException;
-import org.apache.avalon.framework.activity.Startable;
+import org.apache.avalon.framework.CascadingException;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.ParameterException;
import org.apache.avalon.framework.parameters.Parameterizable;
@@ -74,17 +78,9 @@
* <p>Parameters:</p>
* <table>
* <tbody>
- * <tr><td>connection </td><td>(required, no default)</td></tr>
- * <tr><td>component </td><td>(required, no default)</td></tr>
- * <tr><td>scheme </td><td>(rmi)</td></tr>
- * <tr><td>host </td><td>(localhost)</td></tr>
- * <tr><td>port </td><td>(for rmi 1099)</td></tr>
- * <tr><td>jndiname </td><td>("")</td></tr>
- *
<tr><td>context-factory</td><td>(org.exolab.jms.jndi.InitialContextFactory)</td></tr>
- * <tr><td>topic-factory </td><td>(JmsTopicConnectionFactory)</td></tr>
- * <tr><td>topic </td><td>(topic1)</td></tr>
- * <tr><td>ack-mode </td><td>(dups)</td></tr>
- * <tr><td>selector </td><td>("")</td></tr>
+ * <tr><td>connection </td><td>(required, no default)</td></tr>
+ * <tr><td>component </td><td>(required, no default)</td></tr>
+ * <tr><td>message-selector</td><td>("")</td></tr>
* </tbody>
* </table>
*
@@ -93,7 +89,7 @@
*/
public class JMSEventListener
extends AbstractLogEnabled
- implements Serviceable, Parameterizable, MessageListener, Startable,
ThreadSafe {
+ implements Serviceable, Parameterizable, MessageListener, Initializable,
Disposable, ThreadSafe {
protected String selector = "";
@@ -105,31 +101,31 @@
protected JMSConnection connection = null;
- /*
- * @see org.apache.avalon.framework.activity.Startable#start()
- */
- public void start() throws Exception {
-
- this.connection = (JMSConnection)
this.manager.lookup(JMSConnection.ROLE+"/"+this.connectionName);
- this.connection.registerListener(this, this.selector);
- }
+ public void initialize() {
- /*
- * @see org.apache.avalon.framework.activity.Startable#stop()
- */
- public void stop() throws Exception {
- if (this.manager != null){
- if (this.connection != null){
- this.manager.release(connection);
+ try {
+ this.connection = (JMSConnection)
this.manager.lookup(JMSConnection.ROLE+"/"+this.connectionName);
+ this.connection.registerListener(this, this.selector);
+ } catch (ServiceException e) {
+ if (getLogger().isWarnEnabled()) {
+ getLogger().warn("Could not obtain JMSConnection");
+ }
+ } catch (JMSException e) {
+ if (getLogger().isWarnEnabled()) {
+ getLogger().warn("Could not obtain JMSConnection");
}
-
- if (this.service != null) {
- this.manager.release(this.service);
+ } catch (NamingException e) {
+ if (getLogger().isWarnEnabled()) {
+ getLogger().warn("Could not obtain JMSConnection");
}
- }
+ } catch (CascadingException e) {
+ if (getLogger().isWarnEnabled()) {
+ getLogger().warn("Could not obtain JMSConnection");
+ }
+ }
}
- /*
+ /*
* @see
org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
*/
public void parameterize(Parameters parameters) throws
ParameterException {
@@ -189,5 +185,15 @@
public void service(ServiceManager manager) throws ServiceException {
this.manager = manager;
}
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ */
+ public void dispose() {
+ if (this.manager != null){
+ this.manager.release(connection);
+ this.manager.release(service);
+ }
+ }
}
1.2 +15 -6 cocoon-2.1/src/blocks/jms/conf/jmsconnection.xconf
Index: jmsconnection.xconf
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/jms/conf/jmsconnection.xconf,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- jmsconnection.xconf 14 Oct 2003 16:40:09 -0000 1.1
+++ jmsconnection.xconf 19 Oct 2003 02:30:17 -0000 1.2
@@ -2,14 +2,23 @@
<xconf xpath="/cocoon" unless="[EMAIL
PROTECTED]'org.apache.cocoon.components.jms.JMSConnectionImpl']">
<component class="org.apache.cocoon.components.jms.JMSConnectionImpl"
role="org.apache.cocoon.components.jms.JMSConnection/OpenJMS-demo"
logger="core">
- <!-- parameters to go with OpenJMS.sf.net demo on localhost -->
- <parameter name="scheme" value="rmi"/>
- <parameter name="host" value="localhost"/>
- <parameter name="port" value="1099"/>
- <parameter name="jndiname" value=""/>
- <parameter name="context-factory"
value="org.exolab.jms.jndi.InitialContextFactory"/>
+
+ <!--
+ JNDI Parameters must be specified with their literal values
here.
+ For example, javax.naming.Context.INITIAL_CONTEXT_FACTORY is
+ equivalent to "java.naming.factory.initial". If a
jndi.properties
+ file is on the classpath, jndi-info can be left empty to use
those
+ properties instead.
+ -->
+ <jndi-info>
+ <!-- Context.INITIAL_CONTEXT_FACTORY -->
+ <parameter name="java.naming.factory.initial"
value="org.exolab.jms.jndi.InitialContextFactory"/>
+ <!-- Context.PROVIDER_URL -->
+ <parameter name="java.naming.provider.url"
value="rmi://localhost:1099/"/>
+ </jndi-info>
<parameter name="topic-factory" value="JmsTopicConnectionFactory"/>
<parameter name="topic" value="topic1"/>
<parameter name="ack-mode" value="dups"/>
+ <!--<parameter name="durable-subscription-id" value="durableid"/>-->
</component>
</xconf>