[jboss-svn-commits] JBL Code SVN: r22452 - in labs/jbossesb/workspace/skeagh: runtime and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Sep 5 12:07:09 EDT 2008


Author: tfennelly
Date: 2008-09-05 12:07:09 -0400 (Fri, 05 Sep 2008)
New Revision: 22452

Added:
   labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/
   labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/AbstractMessageListener.java
   labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/package.html
Modified:
   labs/jbossesb/workspace/skeagh/jbossesb_checkstyle_checks.xml
   labs/jbossesb/workspace/skeagh/runtime/pom.xml
Log:
AbstractMessageListener - not sure if it works yet - for Daniel to have a look at and use if he can

Modified: labs/jbossesb/workspace/skeagh/jbossesb_checkstyle_checks.xml
===================================================================
--- labs/jbossesb/workspace/skeagh/jbossesb_checkstyle_checks.xml	2008-09-05 15:53:59 UTC (rev 22451)
+++ labs/jbossesb/workspace/skeagh/jbossesb_checkstyle_checks.xml	2008-09-05 16:07:09 UTC (rev 22452)
@@ -157,7 +157,7 @@
         </module>
         <module name="IllegalInstantiation"/>
         <module name="InnerAssignment"/>
-        <module name="MagicNumber"/>
+        <!-- module name="MagicNumber"/ -->
         <module name="MissingSwitchDefault"/>
         <!-- module name="RedundantThrows"/ -->
         <module name="SimplifyBooleanExpression"/>

Modified: labs/jbossesb/workspace/skeagh/runtime/pom.xml
===================================================================
--- labs/jbossesb/workspace/skeagh/runtime/pom.xml	2008-09-05 15:53:59 UTC (rev 22451)
+++ labs/jbossesb/workspace/skeagh/runtime/pom.xml	2008-09-05 16:07:09 UTC (rev 22452)
@@ -30,6 +30,11 @@
             <version>${jboss.esb.version}</version>
         </dependency>
         <dependency>
+            <groupId>jboss</groupId>
+            <artifactId>jboss-j2ee</artifactId>
+            <version>4.2.0.GA</version>
+        </dependency>
+        <dependency>
             <groupId>org.milyn</groupId>
             <artifactId>milyn-smooks-javabean</artifactId>
             <version>1.1-SNAPSHOT</version>

Added: labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/AbstractMessageListener.java
===================================================================
--- labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/AbstractMessageListener.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/AbstractMessageListener.java	2008-09-05 16:07:09 UTC (rev 22452)
@@ -0,0 +1,393 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright XXXX, Red Hat Middleware LLC, 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-2008, JBoss Inc.
+ */
+package org.jboss.esb.jms;
+
+import org.apache.log4j.Logger;
+import org.jboss.esb.deploy.DeploymentException;
+
+import javax.jms.*;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.util.Properties;
+
+/**
+ * Abstract JMS Destination Listener.
+ * <p/>
+ * Manages destination connection, close and cleanup.
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public abstract class AbstractMessageListener implements MessageListener
+{
+    /**
+     * Logger.
+     */
+    private Logger logger;
+    /**
+     * JMS destination name.
+     */
+    private String destinationName;
+    /**
+     * JNDI Properties.
+     */
+    private Properties jndiProperties;
+    /**
+     * JMS Connection.
+     */
+    private Connection conn = null;
+    /**
+     * JMS Session.
+     */
+    private Session session = null;
+    /**
+     * JMS Consumer.
+     */
+    private MessageConsumer messageConsumer;
+    /**
+     * JMS Destination.
+     */
+    private Destination destination = null;
+
+    /**
+     * Public constructor.
+     * <p/>
+     * Connects the listener to the destination.
+     * @param destinationName The destination name.
+     * @param jndiProperties The JNDI properties.
+     */
+    protected AbstractMessageListener(final String destinationName, final Properties jndiProperties)
+    {
+        logger = Logger.getLogger(getClass());
+        this.destinationName = destinationName;
+        this.jndiProperties = jndiProperties;
+        try
+        {
+            if (!connect())
+            {
+                logger.warn("Failed to connect JMS Listener '" + getClass().getName() + "' to JMS destination '" + destinationName + "'. Turn on debug logging for more info.");
+            }
+        } catch (Throwable t)
+        {
+            logger.warn("Unexpected error while trying to connect JMS Listener '" + getClass().getName() + "' to JMS destination '" + destinationName + "'. Turn on debug logging for more info.");
+            close();
+            return;
+        }
+    }
+
+    /**
+     * Get the JMS Connection factory.
+     * @return Connection Factory.
+     * @throws DeploymentException Error getting factory.
+     */
+    private ConnectionFactory getJmsConnectionFactory() throws DeploymentException
+    {
+        ConnectionFactory factory = null;
+        Context context;
+        String connectionFactoryRuntime = jndiProperties.getProperty(ConnectionFactory.class.getName(), "ConnectionFactory");
+
+        context = getNamingContext();
+        try
+        {
+            factory = (ConnectionFactory) context.lookup(connectionFactoryRuntime);
+        } catch (NamingException e)
+        {
+            throw new DeploymentException("JNDI lookup of JMS Connection Factory [" + connectionFactoryRuntime + "] failed.", e);
+        } catch (ClassCastException e)
+        {
+            throw new DeploymentException("JNDI lookup of JMS Connection Factory failed.  Class [" + connectionFactoryRuntime + "] is not an instance of [" + ConnectionFactory.class.getName() + "].", e);
+        } finally
+        {
+            if (context != null)
+            {
+                try
+                {
+                    context.close();
+                } catch (NamingException ne)
+                {
+                    logger.error("Failed to close Naming Context.", ne);
+                }
+            }
+        }
+
+        return factory;
+    }
+
+    /**
+     * Get the JNDI Context.
+     * @return The context.
+     * @throws DeploymentException Error getting context.
+     */
+    private Context getNamingContext() throws DeploymentException
+    {
+        Context context;
+
+        try
+        {
+            context = new InitialContext(jndiProperties);
+        } catch (NamingException e)
+        {
+            throw new DeploymentException("Failed to load InitialContext: " + jndiProperties);
+        }
+        if (context == null)
+        {
+            throw new DeploymentException("Failed to create JMS Server JNDI context.  Check that '" + Context.PROVIDER_URL + "', '" + Context.INITIAL_CONTEXT_FACTORY + "', '" + Context.URL_PKG_PREFIXES + "' are correctly configured in the supplied JNDI properties.");
+        }
+
+        return context;
+    }
+
+    /**
+     * Connect to the configured destination.
+     * @return True if the connect succedded, otherwise false.
+     */
+    private boolean connect()
+    {
+        ConnectionFactory connectionFactory;
+
+        logger.debug("Attempting to connect listener '" + getClass().getName() + "' to JMS Destination '" + destinationName + "'.");
+
+        // Get the Destination ConnectionFactory...
+        try
+        {
+            connectionFactory = getJmsConnectionFactory();
+        } catch (DeploymentException e)
+        {
+            logger.debug("Lookup of the JMS ConnectionFactory failed.", e);
+            return false;
+        } catch (ClassCastException e)
+        {
+            logger.debug("Invalid JMS ConnectionFactory config.  ConnectionFactory doesn't implement " + TopicConnectionFactory.class.getName() + ".", e);
+            return false;
+        }
+
+        // Create the destination connection...
+        try
+        {
+            if (connectionFactory instanceof TopicConnectionFactory)
+            {
+                conn = ((TopicConnectionFactory) connectionFactory).createTopicConnection();
+            } else
+            {
+                conn = ((QueueConnectionFactory) connectionFactory).createQueueConnection();
+            }
+        } catch (JMSException e)
+        {
+            logger.debug("Failed to open JMS Destination Connection.", e);
+            return false;
+        }
+
+        // Lookup the destination...
+        try
+        {
+            Context context = getNamingContext();
+
+            destination = (Destination) context.lookup(destinationName);
+            context.close();
+        } catch (DeploymentException e)
+        {
+            logger.debug("Destination lookup failed.  Destination name '" + destinationName + "'.", e);
+            close();
+            return false;
+        } catch (NamingException e)
+        {
+            logger.debug("Destination lookup failed.  Destination name '" + destinationName + "'.", e);
+            close();
+            return false;
+        }
+
+        // Create the Destination Session...
+        try
+        {
+            if (conn instanceof TopicConnection)
+            {
+                session = ((TopicConnection) conn).createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
+            } else
+            {
+                session = ((QueueConnection) conn).createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
+            }
+        } catch (JMSException e)
+        {
+            logger.debug("Destination Session creation failed.", e);
+            close();
+            return false;
+        }
+
+        // Start the connection...
+        try
+        {
+            conn.start();
+        } catch (JMSException e)
+        {
+            logger.debug("Failed to start JMS Destination Connection.", e);
+            close();
+            return false;
+        }
+
+        // Bind "this" listener to the destination...
+        try
+        {
+            if (session instanceof TopicSession)
+            {
+                messageConsumer = ((TopicSession) session).createSubscriber((Topic) destination);
+                messageConsumer.setMessageListener(this);
+            } else
+            {
+                messageConsumer = ((QueueSession) session).createReceiver((Queue) destination);
+                messageConsumer.setMessageListener(this);
+            }
+        } catch (JMSException e)
+        {
+            logger.debug("Failed to start JMS Destination Connection.", e);
+            close();
+            return false;
+        }
+
+        // Listen for exceptions on the connection...
+        try
+        {
+            conn.setExceptionListener(new ExceptionListener());
+        } catch (JMSException e)
+        {
+            logger.debug("Failed to attach an ExceptionListener.", e);
+            close();
+            return false;
+        }
+
+        logger.debug("Successfully connected listener '" + getClass().getName() + "' to JMS destination '" + destinationName + "'.");
+
+        return true;
+    }
+
+    /**
+     * Close out the listener and all it's resources.
+     */
+    private void close()
+    {
+        try
+        {
+            if (messageConsumer != null)
+            {
+                messageConsumer.close();
+                logger.debug("Closed JMS MessageConsumer for connected listener '" + getClass().getName() + "' on JMS destination '" + destinationName + "'.");
+            }
+        } catch (Throwable e)
+        {
+            logger.error("Failed to close JMS Consumer.", e);
+        }
+        try
+        {
+            if (conn != null)
+            {
+                conn.stop();
+                logger.debug("Stopping JMS Connection for connected listener '" + getClass().getName() + "' on JMS destination '" + destinationName + "'.");
+            }
+        } catch (Throwable e)
+        {
+            logger.error("Failed to stop JMS connection.", e);
+            conn = null;
+        }
+        try
+        {
+            if (session != null)
+            {
+                session.close();
+                logger.debug("Closing JMS Session for connected listener '" + getClass().getName() + "' on JMS destination '" + destinationName + "'.");
+            }
+        } catch (Throwable e)
+        {
+            logger.error("Failed to close JMS session.", e);
+        } finally
+        {
+            session = null;
+        }
+        try
+        {
+            if (conn != null)
+            {
+                conn.close();
+                logger.debug("Closing JMS Connection for connected listener '" + getClass().getName() + "' on JMS destination '" + destinationName + "'.");
+            }
+        } catch (Throwable e)
+        {
+            logger.error("Failed to close JMS connection.", e);
+        } finally
+        {
+            conn = null;
+        }
+        destination = null;
+        logger.debug("JMS listener '" + getClass().getName() + "' on JMS destination '" + destinationName + "' is now closed.");
+    }
+
+    /**
+     * Exception Listener.
+     *
+     * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+     */
+    private class ExceptionListener implements javax.jms.ExceptionListener
+    {
+
+        /**
+         * We want this listener to handle only one exception.
+         * It will close all existing resources and create a new instance
+         * once it successfully reconnects.
+         */
+        private boolean hasHandledOneException = false;
+
+        /**
+         * JMS Exception handler.
+         * @param e The exception.
+         */
+        public final void onException(final JMSException e)
+        {
+            synchronized (ExceptionListener.class)
+            {
+                if (!hasHandledOneException)
+                {
+                    if (!logger.isDebugEnabled())
+                    {
+                        logger.warn("JMS Exception on '" + getClass().getName() + "' on JMS destination '" + destinationName + "' is now closed (turn on debugging for more): " + e.getMessage());
+                    } else
+                    {
+                        logger.warn("JMS Exception on '" + getClass().getName() + "' on JMS destination '" + destinationName + "' is now closed.", e);
+                    }
+                    close();
+                    while (!connect())
+                    {
+                        try
+                        {
+                            Thread.sleep(5000);
+                        } catch (InterruptedException e1)
+                        {
+                            if (!logger.isDebugEnabled())
+                            {
+                                logger.warn("Interrupted during reconnect attempt.  Aborting reconnect!  Will need restart to reconnect (turn on debugging for more): " + e.getMessage());
+                            } else
+                            {
+                                logger.debug("Interrupted during reconnect attempt.  Aborting reconnect!  Will need restart to reconnect.", e);
+                            }
+                        }
+                    }
+                    hasHandledOneException = true;
+                }
+            }
+        }
+    }
+}


Property changes on: labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/AbstractMessageListener.java
___________________________________________________________________
Name: svn:eol-style
   + native

Copied: labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/package.html (from rev 22446, labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/deploy/package.html)
===================================================================
--- labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/package.html	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/package.html	2008-09-05 16:07:09 UTC (rev 22452)
@@ -0,0 +1,8 @@
+<html>
+<head></head>
+<body>
+JMS runtime utility code..
+
+<h2>Package Specification</h2>
+</body>
+</html>
\ No newline at end of file


Property changes on: labs/jbossesb/workspace/skeagh/runtime/src/main/java/org/jboss/esb/jms/package.html
___________________________________________________________________
Name: svn:mergeinfo
   + 




More information about the jboss-svn-commits mailing list