[jboss-svn-commits] JBL Code SVN: r6962 - in labs/jbossesb/workspace/eschifman/trunk/product/core/listeners: src/org/jboss/soa/esb/actions src/org/jboss/soa/esb/actions/routing src/org/jboss/soa/esb/listeners src/org/jboss/soa/esb/listeners/message src/org/jboss/soa/esb/listeners/old src/org/jboss/soa/esb/message tests/src/org/jboss/soa/esb/listeners tests/src/org/jboss/soa/esb/listeners/old tests/src/org/jboss/soa/esb/util
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Oct 20 12:27:32 EDT 2006
Author: estebanschifman
Date: 2006-10-20 12:27:02 -0400 (Fri, 20 Oct 2006)
New Revision: 6962
Added:
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/ListenerTagNames.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/EsbListenerController.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/JmsQueueListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/MockAction.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/easier2ReadExample.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/example.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/AbstractListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/AbstractPoller.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/DirectoryPoller.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/GpListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/JmsQueueListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/RemoteDirectoryPoller.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/SqlTablePoller.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/AbstractListenerUnitTest.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/AbstractListener_ActionConfig.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/DirectoryPollerUnitTest.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/GpListener-Config-01.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/GpListenerUnitTest.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/SqlTablePollerUnitTest.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/SqlTablePollerUnitTest.xml
Removed:
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractPoller.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/DirectoryPoller.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GatewayListenerController.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GpListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsGatewayListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsQueueListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/RemoteDirectoryPoller.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/SqlTablePoller.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/gatewayExample.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/EsbListenerController.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/JmsQueueListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ListenerTagNames.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/MockAction.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/easier2ReadExample.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/example.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListenerUnitTest.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListener_ActionConfig.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/DirectoryPollerUnitTest.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListener-Config-01.xml
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListenerUnitTest.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.xml
Modified:
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/AbstractSqlRowAction.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/FtpDownloader.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/FtpUploader.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/routing/FileCopier.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/AbstractMockListner.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/ListenersManagerExecThread.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/MockNonblockingListener.java
labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/MockPoller.java
Log:
Change package names for listener classes
Modified: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/AbstractSqlRowAction.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/AbstractSqlRowAction.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/AbstractSqlRowAction.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -10,7 +10,7 @@
/**
* Abstract SQL Row action.
* <p/>
- * Convienience class for processing messages from the {@link org.jboss.soa.esb.listeners.SqlTablePoller} listener.
+ * Convienience class for processing messages from the {@link org.jboss.soa.esb.listeners.old.SqlTablePoller} listener.
* Implementing classes receive a single row resultset through their implementation of the {@link #process(Map)}
* method.
*
Modified: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/FtpDownloader.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/FtpDownloader.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/FtpDownloader.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -30,8 +30,8 @@
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.helpers.DomElement;
import org.jboss.soa.esb.helpers.KeyValuePair;
-import org.jboss.soa.esb.listeners.GpListener;
-import org.jboss.soa.esb.listeners.RemoteDirectoryPoller;
+import org.jboss.soa.esb.listeners.old.GpListener;
+import org.jboss.soa.esb.listeners.old.RemoteDirectoryPoller;
import org.jboss.soa.esb.util.FtpClientUtil;
import org.jboss.soa.esb.message.Message;
Modified: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/FtpUploader.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/FtpUploader.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/FtpUploader.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -30,8 +30,8 @@
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.helpers.DomElement;
import org.jboss.soa.esb.helpers.KeyValuePair;
-import org.jboss.soa.esb.listeners.DirectoryPoller;
-import org.jboss.soa.esb.listeners.GpListener;
+import org.jboss.soa.esb.listeners.old.DirectoryPoller;
+import org.jboss.soa.esb.listeners.old.GpListener;
import org.jboss.soa.esb.util.FtpClientUtil;
import org.jboss.soa.esb.message.Message;
Modified: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/routing/FileCopier.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/routing/FileCopier.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/routing/FileCopier.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -36,7 +36,7 @@
import org.jboss.soa.esb.actions.AbstractFileAction;
import org.jboss.soa.esb.actions.ActionProcessingException;
import org.jboss.soa.esb.helpers.*;
-import org.jboss.soa.esb.listeners.DirectoryPoller.WorkingFile;
+import org.jboss.soa.esb.listeners.old.DirectoryPoller.WorkingFile;
import org.jboss.soa.esb.message.Message;
import org.jboss.soa.esb.actions.ActionUtils;
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractListener.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractListener.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,293 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.listeners;
-
-import java.util.Arrays;
-
-import org.apache.log4j.Logger;
-import org.jboss.soa.esb.actions.ActionDefinition;
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.actions.ActionProcessingException;
-import org.jboss.soa.esb.actions.ActionProcessor;
-import org.jboss.soa.esb.actions.ActionUtils;
-import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.format.MessageFactory;
-
-/**
- * Base abstract listener implementation.
- * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
- * @since Version 4.0
- */
-public abstract class AbstractListener implements Runnable {
-
- /**
- * Name constant def for the Message attachemnt carrying the list of actions to be applied to the
- * incomming message. This allows the configured processing pipeline to be overridden by the Message
- * producer.
- */
- public static final String MESSAGE_PROCESSING_ACTIONS_LIST = "MESSAGE_PROCESSING_ACTIONS_LIST";
-
- // You can override these values at constructor time of your
- // derived class after calling super(GpListener,DomElement)
- protected int m_iSleepForThreads = 3000; // default sleep if no threads available
- protected int m_iUpperThreadLimit = 10; // just in case - override if you wish
-
- protected int m_iQthr = 0, m_iMaxThr;
-
- protected ThreadGroup m_oThrGrp = null;
- protected Logger logger;
- protected GpListener m_oDad;
- protected DomElement listenerConfig;
- protected String[] m_oActions;
- protected ActionDefinitionFactory m_oActionDefinitionFactory;
- protected MessageFactory m_oMsgFactory;
-
- protected AbstractListener(GpListener p_oDad, DomElement p_oParms, ActionDefinitionFactory actionDefinitionFactory) throws Exception {
-
- logger = Logger.getLogger(this.getClass());
- m_oDad = p_oDad;
- listenerConfig = p_oParms.cloneObj();
- m_oActionDefinitionFactory = actionDefinitionFactory;
- m_oMsgFactory = MessageFactory.getInstance();
- m_oThrGrp = new ThreadGroup(listenerConfig.getName());
-
- String sAtt = GpListener.obtainAtt(listenerConfig, GpListener.PARM_ACTIONS, "");
- if(!sAtt.trim().equals("")) {
- m_oActions = sAtt.split(",");
- }
-
- sAtt = GpListener.obtainAtt(listenerConfig, GpListener.PARM_MAX_THREADS, "1");
- int iMax = Integer.parseInt(sAtt);
- m_iMaxThr = Math.min(iMax, m_iUpperThreadLimit);
- } // __________________________________
-
- /**
- * Implement run method for this Runnable <p/> Will continue to run until
- * controlling class (ref in m_oDad) indicates no more looping allowed for
- * all child classes <p/> This condition will not prevent child processes to
- * finish normally
- */
- public void run() {
- while (m_oDad.continueLooping()) {
- Object[] processList = receive();
- if (null==processList) {
- try { Thread.sleep(500); }
- catch(InterruptedException e) {/* ok do nothing */}
- } else {
- for (Object currentObj : processList) {
- if (m_iQthr >= m_iMaxThr) {
- logger.info("Waiting for available threads...(max=" + m_iMaxThr + ")");
- try {
- Thread.sleep(m_iSleepForThreads);
- } catch (InterruptedException e) {
- return;
- }
- break;
- }
-
- // Spawn a thread and push the message message through the pipeline...
- ActionProcessingPipeline runner = new ActionProcessingPipeline(currentObj);
- new Thread(runner).start();
- incThreads();
- }
- }
- }
-
- // Wait for all the processing pipelines to complete before closing the listener and existing...
- while(m_iQthr > 0) {
- logger.info("Waiting for all processing pipelines to complete.");
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- logger.warn("Thread interrupted while waiting for all processing pipelines to complete.", e);
- }
- }
-
- logger.info("All processing pipelines complete. Closing listener now.");
-
- close();
- }
-
- /**
- * Receive message from underlying channel implementation.
- * <p/>
- * Implementations must perform a blocking receive.
- * @return An array of Objects received on the channel.
- */
- protected abstract Object[] receive();
-
- /**
- * Called on the listener implementation when pipeline processing error has occured.
- * @param initialMsg The message that was initialy supplied to the pipeline.
- * @param processor The processor that raised the error. Can be null where the error was raised before
- * pipeline processing of the message.
- * @param error The error. Can be null.
- */
- protected abstract void processingError(Object initialMsg, ActionProcessor processor, Throwable error);
-
- /**
- * Called on the listener implementation when pipeline processing of a message is complete.
- * @param initialMsg The message that was initialy supplied to the pipeline.
- */
- protected abstract void processingComplete(Object initialMsg);
-
- /**
- * Close the listener implemenation.
- * <p/>
- * Allows the listener to perform relevant close/cleanup tasks.
- */
- protected abstract void close();
-
- /**
- * Increment the active thread count.
- */
- private void incThreads() {
- m_iQthr++;
- }
-
- /**
- * Decrement the active thread count.
- */
- private void decThreads() {
- m_iQthr--;
- }
-
- /**
- * Action Processing Pipeline.
- * <p/>
- * Runs the actions in a listeners "actions" config on a message payload message received
- * by the listener implementation.
- *
- * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
- * @since Version 4.0
- */
- private class ActionProcessingPipeline implements Runnable {
-
- private Object initialObject;
-
- /**
- * Private constructor.
- * @param pMessage The inital processing target message.
- */
- private ActionProcessingPipeline(Object obj) {
- initialObject = obj;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Runnable#run()
- */
- public void run() {
- String currentAction = null;
- ActionProcessor currentProcessor = null;
-
- try {
- Message message;
- String[] actions;
-
- if(initialObject instanceof Message) {
- message = (Message)initialObject;
- } else {
- message = m_oMsgFactory.getMessage();
- ActionUtils.setTaskObject(message,initialObject);
- }
-
- actions = getActions(message);
-
- // Run the message through each ActionProcessor...
- for(String action : actions) {
- ActionDefinition actionDefinition;
-
- currentAction = action.trim();
- actionDefinition = m_oActionDefinitionFactory.getInstance(currentAction);
- if(actionDefinition == null) {
- throw new java.lang.IllegalStateException("Bad Listener Configuration. No 'Actions/Action' definition for action [" + currentAction + "].");
- }
-
- // The processing result of each action feeds into the processing of the next action...
- currentProcessor = actionDefinition.getProcessor();
- try {
- ActionUtils.copyCurrentToPrevious(message);
- message = currentProcessor.process(message);
- } catch (Exception e) {
- GpListener.notifyError(listenerConfig, e, currentProcessor.getErrorNotification(message));
- throw e;
- }
-
- if(message == null && action != m_oActions[m_oActions.length - 1]) {
- String exceptionMessage = "Premature termination of action processing pipeline [" + Arrays.asList(m_oActions) + "]. ActionProcessor [" + currentProcessor.getClass().getName() + "] returned a null message result on processing of action [" + currentAction + "].";
- processingError(initialObject, currentProcessor, new ActionProcessingException(exceptionMessage));
- logger.warn(exceptionMessage);
- return;
- }
- // Notify on all processors. May want to do this differently in the future i.e. more selectively ...
- GpListener.notifyOK(listenerConfig, currentProcessor.getOkNotification(message));
-
- // Setup the message for processing by the next processor...
- if(message != null) {
- message.getBody().remove(ActionUtils.BEFORE_ACTION);
- }
- }
-
- processingComplete(initialObject);
- } catch(Throwable thrown) {
- processingError(initialObject, currentProcessor, thrown);
- logger.error("Premature termination of action processing pipeline [" + (m_oActions != null?Arrays.asList(m_oActions):"") + "]. Action [" + currentAction + "] threw an exception.", thrown);
- } finally {
- // Decrement the active thread count for the listener on completion...
- decThreads();
- }
- }
-
- /**
- * Get the list of actions to be applied to the supplied message.
- * @param message The message to be processed.
- * @return The set of processing actions to be performed on the message.
- * @throws ActionProcessingException Invalid actions list attachment setting.
- */
- private String[] getActions(Message message) throws ActionProcessingException {
- // Check is there an attachment specifying an override pipeline config...
- Object overrideActionsAttachment = message.getAttachment().get(MESSAGE_PROCESSING_ACTIONS_LIST);
- if(overrideActionsAttachment != null) {
- if(overrideActionsAttachment instanceof String) {
- String overrideActions = (String)overrideActionsAttachment;
-
- if(overrideActions.trim().equals("")) {
- throw new ActionProcessingException("Message attachement [" + MESSAGE_PROCESSING_ACTIONS_LIST + "] was specified but with an empty value. Aborting message processing.");
- }
-
- return overrideActions.split(",");
- } else {
- throw new ActionProcessingException("Message attachement [" + MESSAGE_PROCESSING_ACTIONS_LIST + "] must be of type java.lang.String. Received [" + overrideActionsAttachment.getClass().getName() + "]. Aborting message processing.");
- }
- } else {
- // Otherwise use the actions configured on the listener...
- if(m_oActions == null || m_oActions.length == 0) {
- throw new ActionProcessingException("No actions configuration specified either on the listener or as a Message attachement [" + MESSAGE_PROCESSING_ACTIONS_LIST + "]. Aborting message processing.");
- }
- return m_oActions;
- }
- }
- }
-
-} // ____________________________________________________________________________
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractPoller.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractPoller.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractPoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,111 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.listeners;
-
-import java.util.List;
-
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.helpers.DomElement;
-
-/**
- * Abstract Polling Listener.
- * <p/>
- * Polling listeners are listener implementations that periodically poll for message objects
- * that require processing. This type of listener implementation is required where the underlying
- * message channel doesn't support a blocking receive operation.
- *
- * @author Esteban
- */
-public abstract class AbstractPoller extends AbstractListener {
-
- // You can override these values at constructor time of your
- // derived class after calling super(GpListener,DomElement)
- protected int m_iMinPollMillis = 3000 // minimum polling interval
- , m_iDfltPollMillis = 20000 // default polling interval
- ;
-
- public static final String PARM_POLL_LTCY = "pollLatencySecs";
-
- protected int m_iPollMillis;
-
- /**
- * Construct an abstract polling listener.
- * @param commandListener The command listener.
- * @param listenerConfig The configuration for this polling listener.
- * @param actionDefinitionFactory The action definition factory for the bus.
- * @throws Exception
- */
- protected AbstractPoller(GpListener commandListener, DomElement listenerConfig, ActionDefinitionFactory actionDefinitionFactory) throws Exception {
- super(commandListener, listenerConfig, actionDefinitionFactory);
-
- String sAtt = listenerConfig.getAttr(PARM_POLL_LTCY);
- m_iPollMillis = (null == sAtt) ? m_iDfltPollMillis : 1000 * Integer.parseInt(sAtt);
- if (m_iPollMillis < m_iMinPollMillis) {
- m_iPollMillis = m_iMinPollMillis;
- }
- }
-
- /**
- * Polling listener receive implementation.
- * @return An array of objects polled from the concrete Poller implementation.
- */
- protected Object[] receive() {
- while (m_oDad.continueLooping()) {
- List<Object> olPending = pollForCandidates();
-
- if (olPending == null || olPending.isEmpty()) {
- try {
- Thread.sleep(m_iPollMillis);
- } catch (InterruptedException e) {
- logger.error("Unexpected thread interupt exception. Not terminating blocking receive!!", e);
- }
- continue;
- } else {
- Object[] objForProcessing = new Object[olPending.size()];
-
- // Preprocess all the message objects.
- // TODO: I really think this is no longer required or a good idea!!
- for(int i = 0; i < olPending.size(); i++) {
- objForProcessing[i] = preProcess(olPending.get(i));
- }
- return objForProcessing;
- }
- }
-
- return null;
- }
-
- /**
- * Poll for message objects.
- * @return A list of message objects, or an empty list if there are no message objects.
- */
- protected abstract List<Object> pollForCandidates();
-
- /**
- * Preprocess the message object before returning for pipeline processing.
- * @param message Message object for preprocessing.
- * @return The preprocessed message object, or the supplied message unmodified.
- */
- protected abstract Object preProcess(Object message);
- // TODO: Is this "preprocessing" step needed now that we have processing pipelines on listeners???
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/DirectoryPoller.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/DirectoryPoller.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/DirectoryPoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,263 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY 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 along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-
-
-package org.jboss.soa.esb.listeners;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.List;
-
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.actions.ActionProcessor;
-import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.util.Util;
-
-public class DirectoryPoller extends AbstractPoller
-{
- public static final String FILE_INPUT_DIR = "inputDirURI";
- public static final String FILE_INPUT_SFX = "inputSuffix";
- public static final String FILE_WORK_SFX = "workSuffix";
- public static final String FILE_ERROR_DIR = "errorDirURI";
- public static final String FILE_ERROR_SFX = "errorSuffix";
- public static final String FILE_POST_DIR = "postDirURI";
- public static final String FILE_POST_SFX = "postSuffix";
- public static final String FILE_POST_DEL = "postDelete";
-
- public DirectoryPoller(GpListener p_oDad, DomElement p_oParms, ActionDefinitionFactory actionDefinitionFactory) throws Exception
- {
- super(p_oDad, p_oParms, actionDefinitionFactory);
- checkMyParms();
- } //__________________________________
-
-
- protected File m_oInpDir ,m_oErrorDir ,m_oPostDir;
- protected FileFilter m_oFFilt;
- protected String m_sInpSfx ,m_sWrkSfx ,m_sErrSfx ,m_sPostSfx;
- protected boolean m_bPostDel;
-
- /**
- *
- * @param inputObject Object - Must be a File representing the file that has to be processed
- * @return Object - an array of 3 Files containing:
- * <p/>[0] renamed file (workSuffix appended to input file name)
- * <p/>[1] target file name in case actionClass is unable to complete successfuly
- * <p/>[2] target file name in case actionClass finishes successfuly
- */
- @Override
- public Object preProcess(Object inputObject)
- {
- if (!(inputObject instanceof File)) {
- return null;
- }
-
- File inputFile = (File)inputObject;
- WorkingFile workingFile = new WorkingFile(inputFile.getParentFile(), inputFile.getName() + m_sWrkSfx);
-
- if (!inputFile.renameTo(workingFile)) {
- return null;
- }
-
- workingFile.postDelete = m_bPostDel;
- workingFile.inputFile = inputFile;
- workingFile.errorFile = new File (m_oErrorDir ,inputFile.getName()+m_sErrSfx);
- workingFile.outputFile = new File (m_oPostDir ,inputFile.getName()+m_sPostSfx);
-
- return workingFile;
- } //________________________________
-
- @Override
- protected List<Object> pollForCandidates()
- {
- File[] oaF = m_oInpDir.listFiles(m_oFFilt);
- return Arrays.asList((Object[])oaF);
- } //________________________________
-
- private void checkMyParms() throws Exception
- {
- // INPUT directory and suffix (used for FileFilter)
- String sInpDir = GpListener.obtainAtt(listenerConfig,FILE_INPUT_DIR,null);
- m_oInpDir = getFile(sInpDir);
- seeIfOkToWorkOnDir(m_oInpDir);
-
- m_sInpSfx = GpListener.obtainAtt(listenerConfig,FILE_INPUT_SFX,null);
- m_sInpSfx = m_sInpSfx.trim();
- if (m_sInpSfx.length()<1)
- throw new Exception ("Invalid "+FILE_INPUT_SFX+" attribute");
- m_oFFilt = new FileEndsWith(m_sInpSfx);
-
- // WORK suffix (will rename in input directory)
- m_sWrkSfx = GpListener.obtainAtt(listenerConfig,FILE_WORK_SFX,".esbWork").trim();
- if (m_sWrkSfx.length()<1)
- throw new Exception ("Invalid "+FILE_WORK_SFX+" attribute");
- if (m_sInpSfx.equals(m_sWrkSfx))
- throw new Exception("Work suffix must differ from input suffix <"+m_sWrkSfx+">");
-
- // ERROR directory and suffix (defaults to input dir and ".esbError" suffix)
- String sErrDir = GpListener.obtainAtt(listenerConfig,FILE_ERROR_DIR,sInpDir);
- m_oErrorDir = getFile(sErrDir);
- seeIfOkToWorkOnDir(m_oErrorDir);
-
- m_sErrSfx = GpListener.obtainAtt(listenerConfig,FILE_ERROR_SFX,".esbError").trim();
- if (m_sErrSfx.length()<1)
- throw new Exception ("Invalid "+FILE_ERROR_SFX+" attribute");
- if (m_oErrorDir.equals(m_oInpDir) && m_sInpSfx.equals(m_sErrSfx))
- throw new Exception("Error suffix must differ from input suffix <"+m_sErrSfx+">");
-
-
- // Do users wish to delete files that were processed OK ?
- String sPostDel = GpListener.obtainAtt(listenerConfig,FILE_POST_DEL,"false").trim();
- m_bPostDel = Boolean.parseBoolean(sPostDel);
- if (m_bPostDel)
- return;
-
- // POST (done) directory and suffix (defaults to input dir and ".esbDone" suffix)
- String sPostDir = GpListener.obtainAtt(listenerConfig,FILE_POST_DIR,sInpDir);
- m_oPostDir = getFile(sPostDir);
- seeIfOkToWorkOnDir(m_oPostDir);
- m_sPostSfx = GpListener.obtainAtt(listenerConfig,FILE_POST_SFX,".esbDone").trim();
- if (m_oPostDir.equals(m_oInpDir))
- { if (m_sPostSfx.length()<1)
- throw new Exception ("Invalid "+FILE_POST_SFX+" attribute");
- if (m_sPostSfx.equals(m_sInpSfx))
- throw new Exception("Post process suffix must differ from input suffix <"+m_sPostSfx+">");
- }
-
- } //________________________________
-
- private File getFile(String file) {
- try {
- return new File(new URI(file));
- } catch(Exception e) {
- return new File(file);
- }
- }
-
- protected void seeIfOkToWorkOnDir (File p_oDir) throws Exception
- {
- if (! p_oDir.exists())
- throw new Exception ("Directory "+p_oDir.toString()+" not found");
- if (!p_oDir.isDirectory())
- throw new Exception(p_oDir.toString()+" is not a directory");
- if (!p_oDir.canRead())
- throw new Exception("Can't read directory "+p_oDir.toString());
- if (! p_oDir.canWrite())
- throw new Exception ("Can't write/rename in directory "+p_oDir.toString());
- } //________________________________
-
-
- private class FileEndsWith implements FileFilter
- {
- String m_sSuffix;
- FileEndsWith(String p_sEnd) throws Exception
- {
- m_sSuffix = p_sEnd;
- if (Util.isNullString(m_sSuffix))
- throw new Exception("Must specify file extension");
- } //______________________________
-
- public boolean accept(File p_f)
- { return (p_f.isFile())
- ? p_f.toString().endsWith(m_sSuffix)
- : false;
- } //______________________________
- } //____________________________________________________
-
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#close()
- */
- @Override
- protected void close() {
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#processingError(java.lang.Object, org.jboss.soa.esb.actions.ActionProcessor, java.lang.Throwable)
- */
- @Override
- protected void processingError(Object currentObject, ActionProcessor processor, Throwable error) {
-
- if (null!=currentObject)
- { WorkingFile workingFile = (WorkingFile) currentObject;
- workingFile.renameToError();
- }
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#processingComplete(java.lang.Object)
- */
- @Override
- protected void processingComplete(Object currentObject) {
- WorkingFile workingFile = (WorkingFile) currentObject;
-
- // Delete or rename the file...
- if (workingFile.postDelete) {
- workingFile.delete();
- } else {
- workingFile.renameToOutputFile();
- }
- }
-
- /**
- * Working file.
- * <p/>
- * Once the directory poller picks up on an input file, it immediately renames it to a working file
- * in order to avoid a situation where the file gets processed again.
- *
- * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
- * @since Version 4.0
- */
- public static class WorkingFile extends File {
- private static final long serialVersionUID = 1L;
-
- private boolean postDelete;
- public boolean isPostDelete() { return postDelete; }
-
- private File inputFile, errorFile, outputFile;
-
- public WorkingFile(String filename) {
- super(filename);
- }
-
- public WorkingFile(File parentFile, String filename) {
- super(parentFile, filename);
- }
-
- public boolean renameToError() {
- return renameTo(errorFile);
- }
-
- public boolean renameToOutputFile() {
- return renameTo(outputFile);
- }
-
- /**
- * Get the File instance representing the original input file.
- * @return Original input file.
- */
- public File getInputFile() {
- return inputFile;
- }
- }
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GatewayListenerController.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GatewayListenerController.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GatewayListenerController.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,550 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.listeners;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-import org.jboss.internal.soa.esb.command.CommandQueue;
-import org.jboss.internal.soa.esb.command.CommandQueueException;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.addressing.EPR;
-import org.jboss.soa.esb.addressing.util.EPRManager;
-import org.jboss.soa.esb.common.Environment;
-import org.jboss.soa.esb.common.ModulePropertyManager;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.parameters.ParamRepositoryException;
-import org.jboss.soa.esb.parameters.ParamRepositoryFactory;
-import org.jboss.soa.esb.util.Util;
-import org.xml.sax.SAXException;
-
-import com.arjuna.common.util.propertyservice.PropertyManager;
-
-public class GatewayListenerController implements Runnable
-{
-
- public static void main(String[] args) throws Exception
- {
- GatewayListenerController oProc = new GatewayListenerController(args[0]);
- oProc.run();
- GatewayListenerController.State oS = oProc.getState();
-
- if (null != oS.getException()) {
- _logger.error("GatewayListener <" + args[0] + "> FAILED\n", oS
- .getException());
- }
- System.exit(oS.getCompletionCode());
- } // ________________________________
-
- public static final String RELOAD_SECONDS_TAG = "parameterReloadSecs";
- public static final String END_TIME_TAG = "endTime";
-
- // Attribute name that denotes listener class to be instantiated in a child thread
- // This attribute is not in the root node but in first level child ConfigTrees
- public static final String GATEWAY_CLASS_TAG = "gatewayClass";
-
- /**
- * Obtain a shallow copy of needed atributes in this object's last loaded
- * parameter tree <p/>The local bject is cloned so child threads can use it
- * as they choose to without interfering with the environment
- * <p />
- * Listener processes controlled by this object should keep a reference to
- * this object at construction time, and not call this method again unless
- * they specifically need updated values. Parameter reload could have
- * happened since last call
- *
- * @return Map - a shallow copy of the attributes Map
- */
- @SuppressWarnings("unchecked")
- public Map<String, Object> getControllerAttributes()
- {
- return (Map<String, Object>) _attributes.clone();
- }
-
- public State getState() { return _status; }
-
- public static enum State
- {
- Loading_parameters, Running, Shutting_down, Done_OK, Exception_thrown;
- int m_iCompletionCode = 0;
-
- Exception m_oException = null;
-
- public int getCompletionCode() {
- return m_iCompletionCode;
- };
-
- public Exception getException() {
- return m_oException;
- }
- };
-
- private ActionDefinitionFactory actionDefinitionFactory;
-
- /**
- * Package pivate default constructor.
- */
- protected GatewayListenerController() { }
-
- /**
- * Construct a Listener Manager from the named repository based
- * configuration.
- *
- * @param p_sParameterName
- * Name of the Repository entry containing the configuration.
- * @throws Exception
- * Unable to load/use the named configuration.
- */
- public GatewayListenerController(String p_sParameterName) throws Exception {
- this(GatewayListenerController.getListenerConfig(p_sParameterName));
- _sParametersName = p_sParameterName;
- }
-
- /**
- * Construct a Listener Manager using the specified listener configuration.
- *
- * @param config
- * The configuration.
- * @throws Exception
- * Unable to load/use the supplied configuration.
- */
- public GatewayListenerController(ConfigTree config) throws Exception {
- _config = config;
- _status = State.Loading_parameters;
-
- try { checkParms(_config); }
- catch (Exception e)
- {
- String configSource = config.getAttribute("configSource");
- _status = State.Exception_thrown;
- _status.m_oException = e;
- _logger.fatal("Listener configuration and startup error. Config Source: "
- + (configSource != null ? configSource
- : "unknown"), e);
- throw e;
- }
- }
-
- /**
- * Load the named listener configuration from the configured parameter
- * repository.
- *
- * @param reposParam
- * The name of the repository entry containing the Listener
- * configuration.
- * @return Listener Configuration as {@link ConfigTree}.
- * @throws IOException
- * Unable to access the repository.
- * @throws ParamRepositoryException
- * Unable to access the configuration in the repository.
- * @throws SAXException
- * Unable to parse the configuration.
- */
- private static ConfigTree getListenerConfig(String reposParam)
- throws IOException, ParamRepositoryException, SAXException {
- String sXml = ParamRepositoryFactory.getInstance().get(reposParam);
- ConfigTree config = ConfigTree.fromXml(sXml);
-
- config.setAttribute("configSource", "param-repository:" + reposParam);
-
- return config;
- }
-
- /**
- * Check to see if all needed parameters are there, and assign default
- * values to some of them
- *
- * @param p_oP
- * ConfigTree - Where to look for the mandatory/optional
- * configuration attributes
- * @throws Exception -
- * If attributes are wrong or not enough for a proper runtime
- * configuration
- */
- public void checkParms(ConfigTree p_oP) throws Exception {
- // We've just loaded - set to false until next reload requested
- _reloadRequested = false;
- _commandQueue = createCommandQueue(p_oP);
-
- // Open the command queue...
- if (null!=_commandQueue)
- _commandQueue.open(DomElement.fromConfigTree(p_oP));
-
- // if RELOAD_SECONDS_TAG not set, and no command queue
- // then reload every 10 minutes
- // If there is a command queue, run until command is received
- String sRldSecs = p_oP.getAttribute(RELOAD_SECONDS_TAG);
- _nextReload = (null != sRldSecs)
- ? System.currentTimeMillis() + 1000 * Long.parseLong(sRldSecs)
- : (null == _commandQueue)
- ? Long.MAX_VALUE
- : System.currentTimeMillis() + _defaultReloadMillis;
-
- // if END_TIME_TAG not set try to run forever
- // not a good practice if command queue is not set
- // Expected date format is "yyyyMMdd hh:mm:ss"
- String sEndT = p_oP.getAttribute(END_TIME_TAG);
- _endTime = (null == sEndT) ? Long.MAX_VALUE : _dateFormat.parse(
- sEndT).getTime();
-
- // Read and initialise the action definitions...
- ConfigTree actionConfig = p_oP.getFirstChild("Actions");
- if(actionConfig == null) {
- throw new ConfigurationException("No 'Actions' configuration.");
- }
- actionDefinitionFactory = new ActionDefinitionFactory(DomElement.fromConfigTree(actionConfig));
-
- } // ________________________________
-
- /**
- * Factory method for creating the command queue.
- * @param config GatewayListener config.
- * @return GatewayListener CommandQueue instance.
- */
- private CommandQueue createCommandQueue(ConfigTree config) {
- String commandQueueClass = config.getAttribute("command-queue-class");
-
- if(commandQueueClass != null) {
- try {
- return (CommandQueue) Class.forName(commandQueueClass).newInstance();
- } catch (Exception e) {
- _logger.error("Failed to instantiate CommandQueue ["+ commandQueueClass + "]. Defaulting to no Command Queue", e);
- }
- }
-
- return _defaultCommandQueue;
- }
-
- /**
- * Allows a default command queue to be set statically for all GatewayListener instances.
- * @param defaultCommandQueue The defaultCommandQueue to set.
- */
- public static void setDefaultCommandQueue(CommandQueue defaultCommandQueue) {
- GatewayListenerController._defaultCommandQueue = defaultCommandQueue;
- }
-
- /**
- * Main execution loop <p/> Will continue to run until either <p/>a) run
- * time is expired <p/>b) quiesce command is received in command queue
- * <p/>For every child element that contains a PARM_LISTENER_CLASS
- * attribute, this method will try to launch a child thread instantiating an
- * object of that class, and will call it's run() method <p/>Once all child
- * processes are trigered, the main thread will either <p/>1) wait for a
- * message in the command queue (if one was configured) until next reload or
- * end of run period expired <p/>or 2) Just sleep if there's no command
- * queue to listen on
- */
- public void run()
- {
- while (endNotRequested())
- {
- _status = State.Running;
- for (ConfigTree oCurr : _config.getAllChildren()) {
- String sClass = oCurr.getAttribute(GATEWAY_CLASS_TAG);
- if (Util.isNullString(sClass))
- continue;
- tryToLaunchGateway(oCurr, sClass);
- }
-
- waitForCmdOrSleep();
-
- if (endRequested()) {
- break;
- }
- if (_sParametersName != null && timeToReload())
- {
- try
- {
- _status = State.Loading_parameters;
- _logger
- .info("Reloading parameters _____________________________________________________");
- ConfigTree oNew = GatewayListenerController.getListenerConfig(_sParametersName);
- checkParms(oNew);
- _config = oNew;
- } catch (Exception e) {
- _logger.error("Failed to reload parameters"
- + " - Continuing with cached version", e);
- }
- }
- }
- // _status = State.Shutting_down;
-
- _status = State.Done_OK;
- _status.m_iCompletionCode = 0;
- _logger
- .info("Finishing_____________________________________________________");
-
- // Close the command queue...
- try {
- _commandQueue.close();
- } catch (CommandQueueException e) {
- _logger.error("Error closing Command Queue.", e);
- }
- } // ________________________________
-
- private void tryToLaunchGateway(ConfigTree p_oP, String p_sClassName)
- {
- try {
- Class oListener = Class.forName(p_sClassName);
- Constructor oConst = oListener.getConstructor(new Class[] {
- this.getClass(), ConfigTree.class, ActionDefinitionFactory.class });
- Runnable oRun = (Runnable) oConst.newInstance(new Object[] { this,
- p_oP, actionDefinitionFactory });
- new Thread(oRun).start();
- } catch (Exception e) {
- _logger.error("Cannot launch <" + p_sClassName + ">\n", e);
- }
- } // ________________________________
-
- long millisToWait() {
- return Math.min(_nextReload, _endTime) - System.currentTimeMillis();
- } // ________________________________
-
- private void waitForCmdOrSleep() {
- long lToGo = millisToWait();
-
- if (null == _commandQueue) {
- _logger.debug("About to sleep " + lToGo);
- // No command queue nor topic - Just sleep until time
- // exhausted, or thread interrupted
- try {
- if (lToGo > 0)
- Thread.sleep(lToGo);
- } catch (InterruptedException e) {
- _endTime = 0; // mark as end requested and return
- }
- return;
- }
-
- // Wait for commands until time exhausted or command received
- // Note that received commands might change time variables (reload/end)
- // that's why time to go is recalculated on each cycle
- while ((lToGo = millisToWait()) > 0) {
- try {
- _logger.info("Waiting for command ... timeout=" + lToGo + " millis");
-
- String oM = _commandQueue.receiveCommand(lToGo);
- if (null == oM) {
- return;
- }
- processCommand(oM);
- if (endRequested() || timeToReload()) {
- break;
- }
- } catch (CommandQueueException eJ) {
- _logger.info("receive on command queue failed", eJ);
- }
- }
- } // ________________________________
-
- /**
- * Processes the command that has been received in the command queue (or
- * topic) <p/>_endRequested, _reloadRequested, and _endTime could be
- * changed
- *
- * <p/> <p/><TABLE border="1"> <COLGROUP> <COL width="200"/> <COL
- * width="400"/> </COLGROUP>
- * <TR>
- * <TD align="center">message text</TD>
- * <TD align="center">effect</TD>
- * </TR>
- * <TR>
- * <TD>shutdown*</TD>
- * <TD>End time will be immediately set to 'now' - quiesce process will
- * start - Child threads will be allowed to finish normally</TD>
- * </TR>
- * <TR>
- * <TD>reload param*</TD>
- * <TD>Parameters will be immediately reloaded, and listener reconfigured
- * with new values</TD>
- * </TR>
- * <TR>
- * <TD>endTime yyyyMMdd hh:mm:ss</TD>
- * <TD>End time will be set to new value. If hh:mm:ss is not supplied =>
- * end of day assumed (23:59:59)</TD>
- * </TR>
- * </TABLE> * startsWith() <p/>
- *
- * @param p_oMsg
- * Message received from the command queue.
- *
- */
- private void processCommand(String sTxt) {
- if (null == sTxt)
- return;
-
- String sLow = sTxt.trim().toLowerCase();
- if (sLow.startsWith("shutdown")) {
- _endRequested = true;
- _logger.info("Shutdown has been requested");
- return;
- }
- if (sLow.startsWith("reload param")) {
- _reloadRequested = true;
- _logger
- .info("Request for parameter reload has been received");
- return;
- }
- String[] sa = sLow.split("\\s+");
- if (sa.length > 1 && "endtime".equals(sa[0])) {
- try {
- String sDate = sa[1];
- String sTime = (sa.length < 3 || null == sa[2]) ? "23:59:59"
- : sa[2];
- Date oEnd = _dateFormat.parse(sDate + " " + sTime);
- _logger.info("New end date set to : " + oEnd);
- _endTime = oEnd.getTime();
- } catch (Exception eDat) {
- _logger.info("Problems with endTime command", eDat);
- }
- }
- } // ________________________________
-
- /**
- * Accessor to determine if execution time is expired or shutdown requested
- *
- * @return boolean if processing has to stop (all child threads will be
- * allowed to finish)
- */
- public boolean endRequested() {
- return _endRequested || System.currentTimeMillis() >= _endTime;
- }
-
- /**
- * Accessor to determine if execution time is not expired, and no shutdown
- * request received
- *
- * @return boolean - true if run time has not expired and quiesce has not
- * been requested
- */
- public boolean endNotRequested() {
- return !endRequested();
- }
-
- /**
- * Provide a common accessor to determine if parameters have to be reloaded
- * <p/> For child threads this means thread execution has to end
- * </p>
- * Child processes should only call this method when they are idle (as
- * opposed to in the middle of executing a unit of work)
- *
- * @return boolean - true if it's time to reload parameters
- */
- public boolean timeToReload() {
- return _reloadRequested
- || System.currentTimeMillis() >= _nextReload;
- }
-
- /**
- * Helper accessor for child processes that provides info to determine if
- * they can continue with yet another execution cycle
- *
- * @return boolean - true if runtime is not expired and not time yet to
- * reload parameters
- */
- public boolean continueLooping() {
- return (endNotRequested() && !timeToReload());
- } // ________________________________
-
- /**
- * 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 Exception -
- * If requested attribute not found and no default value
- * supplied by invoker
- */
- public 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;
- } // ________________________________
-
- private static EPRManager getEprManager()
- {
- PropertyManager manager = ModulePropertyManager.getPropertyManager(ModulePropertyManager.CORE_MODULE);
- String sDir = manager.getProperty(Environment.REGISTRY_FILE_HELPER_DIR,".");
- return EPRManager.getInstance(sDir);
- }
-
- public EPR getEprByName (String serviceName) throws IOException
- {
- return getEprManager().loadEPR(serviceName);
- } // ________________________________
-
- public void register (String serviceName, EPR address)
- {
- try { getEprManager().saveEPR(serviceName,address); }
- catch (IOException e)
- {
- _logger.fatal("Cannot register service",e);
- }
- } // ________________________________
-
- public void unRegister (String serviceName, EPR address)
- {
- try { getEprManager().removeEPR(serviceName); }
- catch (IOException e)
- {
- _logger.fatal("Cannot un-register service",e);
- }
- } // ________________________________
-
-
- private CommandQueue _commandQueue;
- private static CommandQueue _defaultCommandQueue = null;
-
- private static Logger _logger = Logger.getLogger(GatewayListenerController.class);
- private String _sParametersName;
- private ConfigTree _config;
- private boolean _reloadRequested;
- private boolean _endRequested;
- private long _nextReload = Long.MAX_VALUE;
- private long _endTime = Long.MAX_VALUE;
- protected int _defaultReloadMillis = 180000; // default interval between parameter reloads
-
-
- public static final SimpleDateFormat _dateFormat
- = new SimpleDateFormat("yyyyMMdd hh:mm:ss");
-
- private State _status = null;
-
-
- private HashMap<String, Object> _attributes;
-} // ____________________________________________________________________________
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GpListener.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GpListener.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GpListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,660 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.listeners;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-import org.jboss.internal.soa.esb.command.CommandQueue;
-import org.jboss.internal.soa.esb.command.CommandQueueException;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.common.Configuration;
-import org.jboss.soa.esb.common.Environment;
-import org.jboss.soa.esb.common.ModulePropertyManager;
-import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.notification.NotificationList;
-import org.jboss.soa.esb.parameters.ParamRepositoryException;
-import org.jboss.soa.esb.parameters.ParamRepositoryFactory;
-import org.jboss.soa.esb.services.NotificationHandlerFactory;
-import org.jboss.soa.esb.services.NotificationManager;
-import org.jboss.soa.esb.util.Util;
-import org.xml.sax.SAXException;
-
-/**
- * Controlling class that will launch listener child threads for supported
- * transport listener classes, as indicated in the configuration XML tree
- * pointed by arg[0]
- *
- * <p />
- * Can be launched as uppermost controller (it has a main(args) method)
- * <p />
- * Also implements Runnable, and can thus be launched in a child thread from an
- * upper controlling process
- * <p />
- * Listens on a JMS queue (with an optional message selector) for commands (e.g.
- * Quiesce, Reload Parameters, Set End Time, etc.)
- * <p />
- * Parameter reloading can also be set using the PARM_RELOAD_SECS attribute
- * <p />
- * End time for this instance can also be set using the PARM_END_TIME attribute
- * <p />
- *
- * @author Esteban
- *
- */
-public class GpListener implements Runnable {
-
- private static Logger m_oLogger = Logger.getLogger(GpListener.class);
-
- public static void main(String[] args) throws Exception {
- GpListener oProc = new GpListener(args[0]);
- oProc.run();
- GpListener.State oS = oProc.getState();
-
- if (null != oS.getException()) {
- m_oLogger.error("GpListener <" + args[0] + "> FAILED\n", oS
- .getException());
- }
- System.exit(oS.getCompletionCode());
- } // ________________________________
-
- protected int m_iDfltReloadMillis = 180000 // default interval between
- // parameter reloads
- ;
-
- public static final String PARM_RELOAD_SECS = "parameterReloadSecs";
- public static final String PARM_END_TIME = "endTime";
-
- // Attribute name that denotes listener class to be instantiated in a child
- // thread
- // This attribute is not in the root node but in first level child
- // DomElements
- public static final String PARM_LISTENER_CLASS = "listenerClass";
- public static final String PARM_ACTIONS = "actions";
- public static final String PARM_MAX_THREADS = "maxThreads";
- public static final String CHLD_EMAIL_PARMS = "EmailProperties";
-
- private String m_sParmsName;
- private DomElement m_oParms;
-
- private HashMap<String, Object> m_oAtts;
-
- /**
- * Obtain a shallow copy of needed atributes in this object's last loaded
- * parameter tree <p/>The local bject is cloned so child threads can use it
- * as they choose to without interfering with the environment
- * <p />
- * Listener processes controlled by this object should keep a reference to
- * this object at construction time, and not call this method again unless
- * they specifically need updated values. Parameter reload could have
- * happened since last call
- *
- * @return Map - a shallow copy of the attributes Map
- */
- @SuppressWarnings("unchecked")
- public Map<String, Object> getControllerAttributes() {
- return (Map<String, Object>) m_oAtts.clone();
- }
-
- private boolean m_bReloadRequested, m_bEndRequested;
-
- private long m_lNextReload = Long.MAX_VALUE;
-
- private long m_lEndTime = Long.MAX_VALUE;
-
- public static final SimpleDateFormat s_oDateParse = new SimpleDateFormat(
- "yyyyMMdd hh:mm:ss");
-
- private State m_oState = null;
-
- public State getState() {
- return m_oState;
- }
-
- public static enum State {
- Loading_parameters, Running, Shutting_down, Done_OK, Exception_thrown;
- int m_iCompletionCode = 0;
-
- Exception m_oException = null;
-
- public int getCompletionCode() {
- return m_iCompletionCode;
- };
-
- public Exception getException() {
- return m_oException;
- }
- };
-
- private CommandQueue commandQueue;
-
- private ActionDefinitionFactory actionDefinitionFactory;
-
- private static CommandQueue defaultCommandQueue = null;
-
- /**
- * Package pivate default constructor.
- */
- protected GpListener() {
- }
-
- /**
- * Construct a Listener Manager from the named repository based
- * configuration.
- *
- * @param p_sParameterName
- * Name of the Repository entry containing the configuration.
- * @throws Exception
- * Unable to load/use the named configuration.
- */
- public GpListener(String p_sParameterName) throws Exception {
- this(GpListener.getListenerConfig(p_sParameterName));
- m_sParmsName = p_sParameterName;
- }
-
- /**
- * Construct a Listener Manager using the specified listener configuration.
- *
- * @param config
- * The configuration.
- * @throws Exception
- * Unable to load/use the supplied configuration.
- */
- public GpListener(DomElement config) throws Exception {
- m_oParms = config;
- m_oState = State.Loading_parameters;
-
- try {
- checkParms(m_oParms);
- setEmailSystemProperties();
- } catch (Exception e) {
- String configSource = config.getAttr("configSource");
-
- m_oState = State.Exception_thrown;
- m_oState.m_oException = e;
- m_oLogger.fatal("Listener configuration and startup error. Config Source: "
- + (configSource != null ? configSource
- : "unknown"), e);
-
- throw e;
- }
- }
-
- /**
- * Load the named listener configuration from the configured parameter
- * repository.
- *
- * @param reposParam
- * The name of the repository entry containing the Listener
- * configuration.
- * @return Listener Configuration as {@link DomElement}.
- * @throws IOException
- * Unable to access the repository.
- * @throws ParamRepositoryException
- * Unable to access the configuration in the repository.
- * @throws SAXException
- * Unable to parse the configuration.
- */
- private static DomElement getListenerConfig(String reposParam)
- throws IOException, ParamRepositoryException, SAXException {
- String sXml = ParamRepositoryFactory.getInstance().get(reposParam);
- DomElement config = DomElement.fromXml(sXml);
-
- config.setAttr("configSource", "param-repository:" + reposParam);
-
- return config;
- }
-
- /**
- * Check to see if all needed parameters are there, and assign default
- * values to some of them
- *
- * @param p_oP
- * DomElement - Where to look for the mandatory/optional
- * configuration attributes
- * @throws Exception -
- * If attributes are wrong or not enough for a proper runtime
- * configuration
- */
- public void checkParms(DomElement p_oP) throws Exception {
- // We've just loaded - set to false until next reload requested
- m_bReloadRequested = false;
- commandQueue = createCommandQueue(p_oP);
-
- // Open the command queue...
- if (null!=commandQueue)
- commandQueue.open(p_oP);
-
- // if PARM_RELOAD_SECS not set, and no command queue
- // then reload every 10 minutes
- // If there is a command queue, run until command is received
- String sRldSecs = p_oP.getAttr(PARM_RELOAD_SECS);
- m_lNextReload = (null != sRldSecs)
- ? System.currentTimeMillis() + 1000 * Long.parseLong(sRldSecs)
- : (null == commandQueue)
- ? Long.MAX_VALUE
- : System.currentTimeMillis() + m_iDfltReloadMillis;
-
- // if PARM_END_TIME not set try to run forever
- // not a good practice if command queue is not set
- // Expected date format is "yyyyMMdd hh:mm:ss"
- String sEndT = p_oP.getAttr(PARM_END_TIME);
- m_lEndTime = (null == sEndT) ? Long.MAX_VALUE : s_oDateParse.parse(
- sEndT).getTime();
-
- // Read and initialise the action definitions...
- DomElement actionConfig = p_oP.getFirstElementChild("Actions");
- if(actionConfig == null) {
- throw new ConfigurationException("No 'Actions' configuration.");
- }
- actionDefinitionFactory = new ActionDefinitionFactory(actionConfig);
-
- } // ________________________________
-
- /**
- * Factory method for creating the command queue.
- * @param config GpListener config.
- * @return GpListener CommandQueue instance.
- */
- private CommandQueue createCommandQueue(DomElement config) {
- String commandQueueClass = config.getAttr("command-queue-class");
-
- if(commandQueueClass != null) {
- try {
- return (CommandQueue) Class.forName(commandQueueClass).newInstance();
- } catch (Exception e) {
- m_oLogger.error("Failed to instantiate CommandQueue ["+ commandQueueClass + "]. Defaulting to no Command Queue", e);
- }
- }
-
- return defaultCommandQueue;
- }
-
- /**
- * Allows a default command queue to be set statically for all GpListener instances.
- * @param defaultCommandQueue The defaultCommandQueue to set.
- */
- public static void setDefaultCommandQueue(CommandQueue defaultCommandQueue) {
- GpListener.defaultCommandQueue = defaultCommandQueue;
- }
-
- /**
- * Main execution loop <p/> Will continue to run until either <p/>a) run
- * time is expired <p/>b) quiesce command is received in command queue
- * <p/>For every child element that contains a PARM_LISTENER_CLASS
- * attribute, this method will try to launch a child thread instantiating an
- * object of that class, and will call it's run() method <p/>Once all child
- * processes are trigered, the main thread will either <p/>1) wait for a
- * message in the command queue (if one was configured) until next reload or
- * end of run period expired <p/>or 2) Just sleep if there's no command
- * queue to listen on
- */
- public void run() {
- while (endNotRequested()) {
- m_oState = State.Running;
- for (DomElement oCurr : m_oParms.getAllElemChildren()) {
- String sClass = oCurr.getAttr(PARM_LISTENER_CLASS);
- if (Util.isNullString(sClass))
- continue;
- tryToLaunchChildListener(oCurr, sClass);
- }
-
- waitForCmdOrSleep();
-
- if (endRequested()) {
- break;
- }
- if (m_sParmsName != null && timeToReload()) {
- try {
- m_oState = State.Loading_parameters;
- m_oLogger
- .info("Reloading parameters _____________________________________________________");
- DomElement oNew = GpListener.getListenerConfig(m_sParmsName);
- checkParms(oNew);
- m_oParms = oNew;
- setEmailSystemProperties();
- } catch (Exception e) {
- m_oLogger.error("Failed to reload parameters"
- + " - Continuing with cached version", e);
- }
- }
- }
- // m_oState = State.Shutting_down;
-
- m_oState = State.Done_OK;
- m_oState.m_iCompletionCode = 0;
- m_oLogger
- .info("Finishing_____________________________________________________");
-
- // Close the command queue...
- try {
- commandQueue.close();
- } catch (CommandQueueException e) {
- m_oLogger.error("Error closing Command Queue.", e);
- }
- } // ________________________________
-
- private void tryToLaunchChildListener(DomElement p_oP, String p_sClassName) {
- try {
- Class oListener = Class.forName(p_sClassName);
- Constructor oConst = oListener.getConstructor(new Class[] {
- this.getClass(), DomElement.class, ActionDefinitionFactory.class });
- Runnable oRun = (Runnable) oConst.newInstance(new Object[] { this,
- p_oP, actionDefinitionFactory });
- new Thread(oRun).start();
- } catch (Exception e) {
- m_oLogger.error("Cannot launch <" + p_sClassName + ">\n", e);
- }
- } // ________________________________
-
- long millisToWait() {
- return Math.min(m_lNextReload, m_lEndTime) - System.currentTimeMillis();
- } // ________________________________
-
- private void waitForCmdOrSleep() {
- long lToGo = millisToWait();
-
- if (null == commandQueue) {
- m_oLogger.debug("About to sleep " + lToGo);
- // No command queue nor topic - Just sleep until time
- // exhausted, or thread interrupted
- try {
- if (lToGo > 0)
- Thread.sleep(lToGo);
- } catch (InterruptedException e) {
- m_lEndTime = 0; // mark as end requested and return
- }
- return;
- }
-
- // Wait for commands until time exhausted or command received
- // Note that received commands might change time variables (reload/end)
- // that's why time to go is recalculated on each cycle
- while ((lToGo = millisToWait()) > 0) {
- try {
- m_oLogger.info("Waiting for command ... timeout=" + lToGo + " millis");
-
- String oM = commandQueue.receiveCommand(lToGo);
- if (null == oM) {
- return;
- }
- processCommand(oM);
- if (endRequested() || timeToReload()) {
- break;
- }
- } catch (CommandQueueException eJ) {
- m_oLogger.info("receive on command queue failed", eJ);
- }
- }
- } // ________________________________
-
- /**
- * Processes the command that has been received in the command queue (or
- * topic) <p/>m_bEndRequested, m_bReloadRequested, and m_lEndTime could be
- * changed
- *
- * <p/> <p/><TABLE border="1"> <COLGROUP> <COL width="200"/> <COL
- * width="400"/> </COLGROUP>
- * <TR>
- * <TD align="center">message text</TD>
- * <TD align="center">effect</TD>
- * </TR>
- * <TR>
- * <TD>shutdown*</TD>
- * <TD>End time will be immediately set to 'now' - quiesce process will
- * start - Child threads will be allowed to finish normally</TD>
- * </TR>
- * <TR>
- * <TD>reload param*</TD>
- * <TD>Parameters will be immediately reloaded, and listener reconfigured
- * with new values</TD>
- * </TR>
- * <TR>
- * <TD>endTime yyyyMMdd hh:mm:ss</TD>
- * <TD>End time will be set to new value. If hh:mm:ss is not supplied =>
- * end of day assumed (23:59:59)</TD>
- * </TR>
- * </TABLE> * startsWith() <p/>
- *
- * @param p_oMsg
- * Message received from the command queue.
- *
- */
- private void processCommand(String sTxt) {
- if (null == sTxt)
- return;
-
- String sLow = sTxt.trim().toLowerCase();
- if (sLow.startsWith("shutdown")) {
- m_bEndRequested = true;
- m_oLogger.info("Shutdown has been requested");
- return;
- }
- if (sLow.startsWith("reload param")) {
- m_bReloadRequested = true;
- m_oLogger
- .info("Request for parameter reload has been received");
- return;
- }
- String[] sa = sLow.split("\\s+");
- if (sa.length > 1 && "endtime".equals(sa[0])) {
- try {
- String sDate = sa[1];
- String sTime = (sa.length < 3 || null == sa[2]) ? "23:59:59"
- : sa[2];
- Date oEnd = s_oDateParse.parse(sDate + " " + sTime);
- m_oLogger.info("New end date set to : " + oEnd);
- m_lEndTime = oEnd.getTime();
- } catch (Exception eDat) {
- m_oLogger.info("Problems with endTime command", eDat);
- }
- }
- } // ________________________________
-
- /**
- * Accessor to determine if execution time is expired or shutdown requested
- *
- * @return boolean if processing has to stop (all child threads will be
- * allowed to finish)
- */
- public boolean endRequested() {
- return m_bEndRequested || System.currentTimeMillis() >= m_lEndTime;
- }
-
- /**
- * Accessor to determine if execution time is not expired, and no shutdown
- * request received
- *
- * @return boolean - true if run time has not expired and quiesce has not
- * been requested
- */
- public boolean endNotRequested() {
- return !endRequested();
- }
-
- /**
- * Provide a common accessor to determine if parameters have to be reloaded
- * <p/> For child threads this means thread execution has to end
- * </p>
- * Child processes should only call this method when they are idle (as
- * opposed to in the middle of executing a unit of work)
- *
- * @return boolean - true if it's time to reload parameters
- */
- public boolean timeToReload() {
- return m_bReloadRequested
- || System.currentTimeMillis() >= m_lNextReload;
- }
-
- /**
- * Helper accessor for child processes that provides info to determine if
- * they can continue with yet another execution cycle
- *
- * @return boolean - true if runtime is not expired and not time yet to
- * reload parameters
- */
- public boolean continueLooping() {
- return (endNotRequested() && !timeToReload());
- } // ________________________________
-
- private static final String[] s_saMailProps = { Environment.SMTP_HOST,
- Environment.SMTP_USERNAME, Environment.SMTP_PASSWORD,
- Environment.SMTP_PORT, Environment.SMTP_FROM,
- Environment.SMTP_AUTH };
-
- private void setEmailSystemProperties() {
- DomElement oEmail = m_oParms.getFirstElementChild(CHLD_EMAIL_PARMS);
- if (null != oEmail)
- for (String sCurr : s_saMailProps) {
- String sProp = oEmail.getAttr(sCurr);
- if (null != sProp)
- ModulePropertyManager.getPropertyManager(ModulePropertyManager.TRANSPORTS_MODULE).setProperty(sCurr, sProp);
- }
- } // ________________________________
-
- /**
- * Find an attribute in the tree (arg 0) or assign default value (arg 2)
- *
- * @param p_oP
- * DomElement - 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 Exception -
- * If requested attribute not found and no default value
- * supplied by invoker
- */
- public static String obtainAtt(DomElement p_oP, String p_sAtt, String p_sDefault)
- throws ConfigurationException {
- String sVal = p_oP.getAttr(p_sAtt);
- if ((null == sVal) && (null == p_sDefault))
- throw new ConfigurationException("Missing or invalid <" + p_sAtt + "> attribute");
-
- return (null != sVal) ? sVal : p_sDefault;
- } // ________________________________
-
- /**
- * Find child nodes named "NotificationList" that contain an attribute
- * 'type' that starts with "ok" (case insensitive)
- *
- * @param p_oP -
- * DomElement to search for "NotificationList" child Elements
- * @param p_oSer
- * Serializable - Will constitute the body of the notification
- */
- public static void notifyOK(DomElement p_oP, Serializable p_oSer) {
- if(p_oSer == null) {
- return;
- }
-
- try {
- Serializable oNotif = p_oSer;
- for (DomElement oCurr : p_oP
- .getElementChildren(NotificationList.ELEMENT)) {
- NotificationList oNL = new NotificationList(oCurr);
- if (!oNL.isOK())
- continue;
- getNotifHandler().sendNotifications(oCurr, oNotif);
- }
- } catch (Exception e) {
- }
- } // __________________________________
-
- /**
- * Find child nodes named "NotificationList" that contain an attribute
- * 'type' that starts with "err" (case insensitive) or no 'type' attribute
- * set
- *
- * @param p_oP -
- * DomElement to search for "NotificationList" child Elements
- * @param p_e -
- * Exception if not null, will be appended to the body
- * @param p_oSer
- * Serializable - Will be included at the beginning of the body
- * of the notification
- */
- public static void notifyError(DomElement p_oP, Exception p_e, Serializable p_oSer) {
- if(p_oSer == null) {
- return;
- }
-
- Serializable oNotif = p_oSer;
- ByteArrayOutputStream oBO = new ByteArrayOutputStream();
- PrintStream oPS = new PrintStream(oBO);
- try {
- oPS.println(oNotif.toString());
- if (null != p_e)
- p_e.printStackTrace(oPS);
- oPS.close();
-
- String sMsg = oBO.toString();
- for (DomElement oCurr : p_oP
- .getElementChildren(NotificationList.ELEMENT)) {
- NotificationList oNL = new NotificationList(oCurr);
- if (!oNL.isErr())
- continue;
- getNotifHandler().sendNotifications(oNL, sMsg);
- }
- } catch (Exception e) {
- }
- } // ________________________________
-
- private static NotificationManager s_oNH;
-
- private static final Object s_oSync = new Integer(0);
-
- /**
- * Lazy instantiator of a InotificationHandler
- *
- * @return - a reference to an implementation of the interface or null if it
- * can't be instantiated
- */
- protected static NotificationManager getNotifHandler() {
- if (null != s_oNH)
- return s_oNH;
- synchronized (s_oSync) {
- if (null == s_oNH)
- try {
- s_oNH = NotificationHandlerFactory.getNotifHandler(
- "remote", Configuration.getJndiServerType(),
- Configuration.getJndiServerURL());
- } catch (Exception e) {
- Logger.getLogger(GpListener.class).error(
- "Notification FAILED", e);
- }
- }
- return s_oNH;
- } // ______________________________
-
-} // ____________________________________________________________________________
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsGatewayListener.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsGatewayListener.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsGatewayListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,243 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.listeners;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javax.enterprise.deploy.spi.exceptions.ConfigurationException;
-import javax.jms.JMSException;
-import javax.jms.MessageConsumer;
-import javax.jms.Queue;
-import javax.jms.QueueConnection;
-import javax.jms.QueueConnectionFactory;
-import javax.jms.QueueSession;
-import javax.naming.Context;
-
-import org.apache.log4j.*;
-
-import org.jboss.internal.soa.esb.couriers.*;
-import org.jboss.soa.esb.addressing.EPR;
-import org.jboss.soa.esb.addressing.helpers.JMSEpr;
-import org.jboss.soa.esb.couriers.Courier;
-import org.jboss.soa.esb.couriers.CourierException;
-import org.jboss.soa.esb.couriers.CourierFactory;
-import org.jboss.soa.esb.helpers.AppServerContext;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.listeners.ListenerTagNames;
-
-public class JmsGatewayListener implements Runnable
-{
-
- public JmsGatewayListener(GatewayListenerController commandListener, ConfigTree listenerConfig)
- throws Exception
- {
- _config = listenerConfig;
- _controller = commandListener;
- _sleepForRetries = 3000; // milliseconds
- checkMyParms();
- } // __________________________________
-
- public void run()
- {
- if (null!=_serviceName)
- _controller.register(_serviceName,_myEpr);
-
- while (_controller.continueLooping())
- {
- javax.jms.Message msgIn = receiveOne();
- if (null!=msgIn)
- try
- {
- Object obj = _processMethod.invoke(_composer,new Object[] {msgIn} );
- if (null==obj)
- {
- _logger.warn("Action class method <"+_processMethod.getName()+"> returned a null object");
- continue;
- }
- // try to deliver the composed message, using the appropriate courier
- // to the target service
- try
- {
- _courier.deliver((org.jboss.soa.esb.message.Message)obj);
- }
- catch (ClassCastException e)
- {
- _logger.error("Action class method <"+_processMethod.getName()+"> returned a non Message object");
- continue;
- }
- catch (CourierException e)
- {
- _logger.error("Courier <"+_courier.getClass().getName()+".deliver(Message) FAILED");
- continue;
- }
- continue;
- }
- catch (InvocationTargetException e)
- {
- _logger.error("Problems invoking method <"+_processMethod.getName()+">",e);
- }
- catch (IllegalAccessException e)
- {
- _logger.error("Problems invoking method <"+_processMethod.getName()+">",e);
- }
- catch (Exception e)
- {
- _logger.error("Unexpected problem",e);
- }
- }
-
- if (null!=_serviceName)
- _controller.unRegister(_serviceName,_myEpr);
-
- if (null != _queueSession)
- try { _queueSession.close(); }
- catch (Exception e1) {/* Tried my best - Just continue */ }
- if (null != _queueConnection)
- try { _queueConnection.close(); }
- catch (Exception e2) {/* Tried my best - Just continue */ }
- } // ________________________________
-
- /**
- * Check for mandatory and optional attributes in parameter tree
- *
- * @throws Exception -
- * if mandatory atts are not right or actionClass not in
- * classpath
- */
- protected void checkMyParms() throws Exception
- {
- // Third arg is null - Exception will be thrown if attribute is not found
- _targetServiceName = _controller.obtainAtt(_config, ListenerTagNames.TARGET_SERVICE_NAME_TAG, null);
- _targetEpr = _controller.getEprByName(_targetServiceName);
- if (null==_targetEpr)
- throw new ConfigurationException("EPR <"+_targetServiceName+"> not found in registry");
-
- _queueName = _controller.obtainAtt(_config, JMSEpr.DESTINATION_NAME_TAG, null);
-
- // Look for first "action" element - only first one will be used
- String tagName = ListenerTagNames.ACTION_ELEMENT_TAG;
- ConfigTree actionElement = _config.getFirstChild(tagName);
- if (null==actionElement)
- throw new ConfigurationException("Missing <"+tagName+"> element");
- // class attribute
- _composerName = _controller.obtainAtt(actionElement,ListenerTagNames.ACTION_CLASS_TAG,null);
- _composerClass = Class.forName(_composerName);
- Constructor oConst = _composerClass.getConstructor(new Class[] {ConfigTree.class});
- _composer= oConst.newInstance(_config);
-
- // From here onwards, all attributes have a default value
- // process attribute
- tagName = ListenerTagNames.PROCESS_METHOD_TAG;
- String sProcessMethod = _controller.obtainAtt(_config,tagName,tagName);
- _processMethod = _composerClass.getMethod(sProcessMethod,new Class[] {Message.class});
-
- // No problem if selector is null - everything in queue will be returned
- _messageSelector = _config.getAttribute(JMSEpr.MESSAGE_SELECTOR_TAG);
-
- _courier = CourierFactory.getCourier(_targetEpr);
-
- prepareMessageReceiver();
- } // ________________________________
-
- private void prepareMessageReceiver() throws Exception
- {
- _queueConnection = null;
- _queueSession = null;
- _queue = null;
-
- String sJndiType = _controller.obtainAtt(_config, JMSEpr.JNDI_TYPE_TAG,"jboss");
- String sJndiURL = _controller.obtainAtt(_config, JMSEpr.JNDI_URL_TAG,"localhost");
- Context oJndiCtx = AppServerContext.getServerContext(sJndiType,sJndiURL);
-
- String sFactClass = _controller.obtainAtt(_config,JMSEpr.CONNECTION_FACTORY_TAG, "ConnectionFactory");
- _serviceName = _config.getAttribute(ListenerTagNames.SERVICE_NAME_TAG);
- _myEpr = (null==_serviceName) ? null
- : new JMSEpr(JMSEpr.QUEUE_TYPE,_queueName,sFactClass,sJndiType,sJndiURL,_messageSelector);
-
- Object tmp = oJndiCtx.lookup(sFactClass);
- QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
-
- _queueConnection = qcf.createQueueConnection();
- _queue = (Queue) oJndiCtx.lookup(_queueName);
- _queueSession = _queueConnection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
- _queueConnection.start();
-
- _messageReceiver = _queueSession.createReceiver(_queue, _messageSelector);
-
- } // ________________________________
-
- /**
- * Receive one message and retry if connection
- * @return javax.jms.Message - One input message, or null
- */
- protected javax.jms.Message receiveOne()
- {
- while (_controller.endRequested())
- try
- {
- return _messageReceiver.receive(_controller.millisToWait());
- }
- catch (JMSException oJ)
- {
- _logger.error("JMS error on receive. Attempting JMS Destination reconnect.", oJ);
- try { prepareMessageReceiver(); }
- // try to reconnect to the queue
- catch (Exception e)
- {
- _logger.error("Reconnecting to Queue", e);
- try { Thread.sleep(_sleepForRetries); }
- catch (InterruptedException e1)
- { // Just return
- _logger.error("Unexpected thread interupt exception.", e);
- return null;
- }
- }
- }
- return null;
- } //________________________________
-
- protected final static Logger _logger = Logger.getLogger(JmsGatewayListener.class);
-
- protected String _queueName;
- protected QueueConnection _queueConnection;
- protected QueueSession _queueSession;
- protected Queue _queue;
- protected MessageConsumer _messageReceiver;
- protected String _messageSelector;
- protected ConfigTree _config;
- protected GatewayListenerController _controller;
- protected final long _sleepForRetries; // milliseconds
-
- protected String _serviceName,_targetServiceName;
- protected EPR _myEpr ,_targetEpr;
-
- protected String _composerName;
- protected Class _composerClass;
- protected Object _composer;
- protected Method _processMethod;
-
- protected Courier _courier;
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsQueueListener.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsQueueListener.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsQueueListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,187 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.listeners;
-
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.ObjectMessage;
-import javax.jms.Queue;
-import javax.jms.QueueConnection;
-import javax.jms.QueueConnectionFactory;
-import javax.jms.QueueSession;
-import javax.jms.TextMessage;
-import javax.jms.TopicSession;
-import javax.naming.Context;
-
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.actions.ActionProcessor;
-import org.jboss.soa.esb.helpers.AppServerContext;
-import org.jboss.soa.esb.helpers.DomElement;
-
-public class JmsQueueListener extends AbstractListener {
-
- public static final String LISTEN_QUEUE_CONN_FACT = "queueConnFactoryClass";
- public static final String LISTEN_JNDI_TYPE = "listenJndiType";
- public static final String LISTEN_JNDI_URL = "listenJndiURL";
- public static final String LISTEN_QUEUE = "listenQueue";
- public static final String LISTEN_MSG_SELECTOR = "listenMsgSelector";
-
- protected boolean m_bError = false;
- protected QueueConnection m_oQconn;
- protected QueueSession m_oQsess;
- protected Queue m_oQueue;
- protected String m_sSelector;
-
- protected MessageConsumer jmsMessageReceiver;
-
-
- public JmsQueueListener(GpListener commandListener, DomElement listenerConfig, ActionDefinitionFactory actionDefinitionFactory) throws Exception {
- super(commandListener, listenerConfig, actionDefinitionFactory);
- checkMyParms();
- } // __________________________________
-
- /**
- * Check for mandatory and optional attributes in parameter tree
- *
- * @throws Exception -
- * if mandatory atts are not right or actionClass not in
- * classpath
- */
- protected void checkMyParms() throws Exception {
- // Third arg is null - Exception will br thrown if listenQueue is not
- // found
- String sQueue = GpListener.obtainAtt(listenerConfig, LISTEN_QUEUE, null);
-
- // No problem if selector is null - everything in queue will be returned
- m_sSelector = listenerConfig.getAttr(LISTEN_MSG_SELECTOR);
-
- m_oQconn = null;
- m_oQsess = null;
- m_oQueue = null;
-
- String sJndiType = GpListener.obtainAtt(listenerConfig, LISTEN_JNDI_TYPE,
- "jboss");
- String sJndiURL = GpListener.obtainAtt(listenerConfig, LISTEN_JNDI_URL,
- "localhost");
- Context oJndiCtx = AppServerContext.getServerContext(sJndiType,
- sJndiURL);
-
- String sFactClass = GpListener.obtainAtt(listenerConfig,
- LISTEN_QUEUE_CONN_FACT, "ConnectionFactory");
- Object tmp = oJndiCtx.lookup(sFactClass);
- QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
-
- m_oQconn = qcf.createQueueConnection();
- m_oQueue = (Queue) oJndiCtx.lookup(sQueue);
- m_oQsess = m_oQconn.createQueueSession(false,
- TopicSession.AUTO_ACKNOWLEDGE);
- m_oQconn.start();
- jmsMessageReceiver = m_oQsess.createReceiver(m_oQueue, m_sSelector);
-
- } // ________________________________
-
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#receive()
- */
- @Override
- protected Object[] receive() {
- while (m_oDad.continueLooping()) {
- Message jmsMessage = null;
- try {
- jmsMessage = jmsMessageReceiver.receive(m_oDad.millisToWait());
- } catch (JMSException oJ) {
- logger.error("JMS error on receive. Attempting JMS Destination reconnect.", oJ);
- for (int i1 = 0; i1 < 3; i1++)
- try {
- checkMyParms();
- } // try to reconnect to the queue
- catch (Exception e) {
- logger.error("Reconnecting to Queue", e);
- try {
- Thread.sleep(m_iSleepForThreads);
- } catch (InterruptedException e1) { // Just return
- logger.error("Unexpected thread interupt exception.", e);
- return null;
- }
- }
- }
- if (null == jmsMessage) {
- // REVIEW: Can this really happen i.e. the JMS
- continue;
- }
-
- if (jmsMessage instanceof ObjectMessage) {
- try {
- return new Object[] {((ObjectMessage)jmsMessage).getObject()};
- } catch (JMSException e) {
- logger.error("Failed to read Serialized Object from JMS message.", e);
- }
- } else if (jmsMessage instanceof TextMessage) {
- try {
- return new Object[] {((TextMessage)jmsMessage).getText()};
- } catch (JMSException e) {
- logger.error("Failed to read Serialized Object from JMS message.", e);
- }
- } else {
- logger.error("Unsupported JMS message type: " + jmsMessage.getClass().getName());
- }
- }
-
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#close()
- */
- @Override
- protected void close() {
- if (null != m_oQsess) {
- try {
- m_oQsess.close();
- } catch (Exception e1) {/* Tried my best - Just continue */
- }
- }
- if (null != m_oQconn) {
- try {
- m_oQconn.close();
- } catch (Exception e2) {/* Tried my best - Just continue */
- }
- }
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#processingError(java.lang.Object, org.jboss.soa.esb.actions.ActionProcessor, java.lang.Throwable)
- */
- @Override
- protected void processingError(Object initialMessage, ActionProcessor processor, Throwable error) {
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#processingComplete(java.lang.Object)
- */
- @Override
- protected void processingComplete(Object initialMessage) {
- }
-}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/ListenerTagNames.java (from rev 6944, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/ListenerTagNames.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/ListenerTagNames.java 2006-10-20 10:53:36 UTC (rev 6944)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/ListenerTagNames.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,13 @@
+package org.jboss.soa.esb.listeners;
+
+public class ListenerTagNames
+{
+ public static final String SERVICE_NAME_TAG = "service-name";
+ public static final String TARGET_SERVICE_NAME_TAG = "target-service-name";
+
+ public static final String ACTION_ELEMENT_TAG = "action";
+ public static final String ACTION_CLASS_TAG = "class";
+ public static final String PROCESS_METHOD_TAG = "process";
+ public static final String NORMAL_COMPLETION_METHOD_TAG = "okMethod";
+ public static final String EXCEPTION_METHOD_TAG = "exceptionMethod";
+}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/RemoteDirectoryPoller.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/RemoteDirectoryPoller.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/RemoteDirectoryPoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,284 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY 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 along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-
-
-package org.jboss.soa.esb.listeners;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.actions.ActionProcessor;
-import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.helpers.KeyValuePair;
-import org.jboss.soa.esb.util.FtpClientUtil;
-import org.jboss.soa.esb.util.Util;
-
-public class RemoteDirectoryPoller extends AbstractPoller
-{
- public static final String FILE_INPUT_DIR = "inputDir";
- public static final String FILE_INPUT_SFX = "inputSuffix";
- public static final String FILE_WORK_SFX = "workSuffix";
- public static final String FILE_ERROR_DIR = "errorDir";
- public static final String FILE_ERROR_SFX = "errorSuffix";
- public static final String FILE_POST_DIR = "postDir";
- public static final String FILE_POST_SFX = "postSuffix";
- public static final String FILE_POST_DEL = "postDelete";
-
- private DomElement _params;
- private Logger _logger = Logger.getLogger(this.getClass());
- FtpClientUtil _ftpClient;
-
- public RemoteDirectoryPoller(GpListener p_oDad, DomElement p_oParms,ActionDefinitionFactory actionDF)
- throws Exception
- {
- super(p_oDad,p_oParms,actionDF);
- _params = p_oParms;
- checkMyParms();
- } //__________________________________
-
-
- protected File m_oInpDir ,m_oErrorDir ,m_oPostDir;
- protected String m_sInpSfx ,m_sWrkSfx ,m_sErrSfx ,m_sPostSfx;
- protected boolean m_bPostDel;
- private List <KeyValuePair> m_ftpProps = new ArrayList<KeyValuePair>();
-
- /**
- *
- * @param p_o Object - Must be a File representing the file that has to be processed
- * @return Object - an instance of the internal WorkingFile class
- */
- @Override
- public Object preProcess(Object p_o)
- {
- if (!(p_o instanceof File))
- return null;
- File oF = (File)p_o;
- WorkingFile oCurr = new WorkingFile(oF,m_sWrkSfx,m_bPostDel);
- oCurr.errorFile = new File (m_oErrorDir ,oF.getName()+m_sErrSfx);
- oCurr.outputFile = new File (m_oPostDir ,oF.getName()+m_sPostSfx);
- oCurr.setFtpProps(m_ftpProps);
-
- try
- {
- _ftpClient = new FtpClientUtil(_params,true);
- _ftpClient.remoteRename(oF,oCurr);
- }
- catch (Exception e)
- {
- _logger.error("Can't FTP rename",e);
- return null;
- }
- finally
- {
- if (null!=_ftpClient)
- _ftpClient.quit();
- _ftpClient = null;
- }
-
- return oCurr;
- } //________________________________
-
- @Override
- protected List<Object> pollForCandidates()
- {
- List<Object> oRet = new ArrayList<Object>();
- FtpClientUtil _ftpClient = null;
- try
- {
- _ftpClient = new FtpClientUtil(_params,true);
- _ftpClient.setRemoteDir(FtpClientUtil.fileToFtpString(m_oInpDir));
- String[] sa = _ftpClient.getFileListFromRemoteDir(m_sInpSfx);
- if (null!=sa)
- for (String sCurr : sa)
- oRet.add(new File(m_oInpDir,sCurr));
- }
- catch (Exception e)
- {
- _logger.error("Problems with FTP",e);
- }
- finally
- {
- if (null!=_ftpClient)
- _ftpClient.quit();
- _ftpClient = null;
- }
- return oRet;
-
- } //________________________________
-
- protected void checkMyParms() throws Exception
- {
- // INPUT directory and suffix (used for FileFilter)
- String sInpDir = GpListener.obtainAtt(_params,FILE_INPUT_DIR,null);
- m_oInpDir = new File(sInpDir);
-
- m_sInpSfx = GpListener.obtainAtt(_params,FILE_INPUT_SFX,null);
- m_sInpSfx = m_sInpSfx.trim();
- if (m_sInpSfx.length()<1)
- throw new Exception ("Invalid "+FILE_INPUT_SFX+" attribute");
-
- // WORK suffix (will rename in input directory)
- m_sWrkSfx = GpListener.obtainAtt(_params,FILE_WORK_SFX,".esbWork").trim();
- if (m_sWrkSfx.length()<1)
- throw new Exception ("Invalid "+FILE_WORK_SFX+" attribute");
- if (m_sInpSfx.equals(m_sWrkSfx))
- throw new Exception("Work suffix must differ from input suffix <"+m_sWrkSfx+">");
-
- // ERROR directory and suffix (defaults to input dir and ".esbError" suffix)
- String sErrDir = GpListener.obtainAtt(_params,FILE_ERROR_DIR,sInpDir);
- m_oErrorDir = new File(sErrDir);
-
- m_sErrSfx = GpListener.obtainAtt(_params,FILE_ERROR_SFX,".esbError").trim();
- if (m_sErrSfx.length()<1)
- throw new Exception ("Invalid "+FILE_ERROR_SFX+" attribute");
- if (m_oErrorDir.equals(m_oInpDir) && m_sInpSfx.equals(m_sErrSfx))
- throw new Exception("Error suffix must differ from input suffix <"+m_sErrSfx+">");
-
-
- // Do users wish to delete files that were processed OK ?
- String sPostDel = GpListener.obtainAtt(_params,FILE_POST_DEL,"false").trim();
- m_bPostDel = Boolean.parseBoolean(sPostDel);
- if (m_bPostDel)
- return;
-
- // POST (done) directory and suffix (defaults to input dir and ".esbDone" suffix)
- String sPostDir = GpListener.obtainAtt(_params,FILE_POST_DIR,sInpDir);
- m_oPostDir = new File(sPostDir);
- m_sPostSfx = GpListener.obtainAtt(_params,FILE_POST_SFX,".esbDone").trim();
- if (m_oPostDir.equals(m_oInpDir))
- { if (m_sPostSfx.length()<1)
- throw new Exception ("Invalid "+FILE_POST_SFX+" attribute");
- if (m_sPostSfx.equals(m_sInpSfx))
- throw new Exception("Post process suffix must differ from input suffix <"+m_sPostSfx+">");
- }
-
-
- FtpClientUtil _ftpClient = new FtpClientUtil(_params,false);
- _ftpClient.quit();
-
- // Copy FTP parameters to be passed to the action class (inside the WorkingFile class)
- // This is a kludge - we have to get back to this (ES)
- String[] sa = new String[]
- {FtpClientUtil.PARMS_FTP_SERVER
- ,FtpClientUtil.PARMS_USER
- ,FtpClientUtil.PARMS_PASSWD
- ,FtpClientUtil.PARMS_PASSIVE
- ,FtpClientUtil.PARMS_PORT
- };
- for (String sProp : sa)
- {
- String sVal = _params.getAttr(sProp);
- if (!Util.isNullString(sVal))
- m_ftpProps.add(new KeyValuePair(sProp,sVal));
- }
-
- } //________________________________
-
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#close()
- */
- @Override
- protected void close() { }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#processingError(java.lang.Object, org.jboss.soa.esb.actions.ActionProcessor, java.lang.Throwable)
- */
- @Override
- protected void processingError(Object initialMessage, ActionProcessor processor, Throwable error)
- {
- @SuppressWarnings("unused")
- WorkingFile workingFile = (WorkingFile) initialMessage;
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#processingComplete(java.lang.Object)
- */
- @Override
- protected void processingComplete(Object initialMessage)
- {
- @SuppressWarnings("unused")
- WorkingFile workingFile = (WorkingFile) initialMessage;
- }
-
- /**
- * Working file.
- * <p/>
- * Once the remote directory poller picks up on an input file, it immediately tries to rename
- * it to a working file in order to avoid a situation where the file gets processed again.
- *
- * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
- * @since Version 4.0
- */
- public static class WorkingFile extends File
- {
- private static final long serialVersionUID = 1L;
-
- private boolean postDelete;
- private File inputFile, errorFile, outputFile;
- private List <KeyValuePair> ftpProps;
- public void setFtpProps(List <KeyValuePair>props) {ftpProps = props; }
- public List <KeyValuePair >getFtpProps() {return ftpProps; }
-
- private WorkingFile(File pFile,String pWrkSfx, boolean pPostDelete)
- {
- super(pFile.getParentFile(), pFile.getName() + pWrkSfx);
- inputFile = pFile;
- }
- /**
- * Get the File instance representing the original input file.
- * @return Original input file.
- */
- public File getInputFile() { return inputFile; }
- /**
- * is this working file to be deleted after successful processing ?
- * @return boolean - true if this file can be deleted
- */
- public boolean isPostDelete() { return postDelete; }
-
- public boolean localRenameToInput() { return super.renameTo(inputFile); }
- public void remoteRenameToInput(FtpClientUtil util) throws Exception
- {
- util.remoteRename(this,inputFile);
- }
-
- public boolean localRenameToError() { return super.renameTo(errorFile); }
- public void remoteRenameToError(FtpClientUtil util) throws Exception
- {
- util.remoteRename(this,errorFile);
- }
-
- public boolean localRenameToOutput() { return renameTo(outputFile); }
- public void remoteRenameToOutput(FtpClientUtil util) throws Exception
- {
- util.remoteRename(this,outputFile);
- }
-
- public boolean localDelete() {return delete(); }
- public void remoteDelete(FtpClientUtil util) throws Exception
- {util.deleteRemoteFile(this.toString()); }
-
- }
-} //____________________________________________________________________________
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/SqlTablePoller.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/SqlTablePoller.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/SqlTablePoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,505 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY 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 along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-
-
-package org.jboss.soa.esb.listeners;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import javax.sql.DataSource;
-
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.actions.ActionProcessor;
-import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.helpers.persist.JdbcCleanConn;
-import org.jboss.soa.esb.helpers.persist.SimpleDataSource;
-import org.jboss.soa.esb.util.Util;
-
-/**
- * SqlTablePoller class
- *
- * The SQL table that is polled should have
- * 1) a unique key (see "keyFields" parameter) that will be used to update status
- * 2) a column to indicate the "processing status" of this trigger row (see ROW_STATE enum)
- *
- * Each retrieved row (see OPTIONAL_ATT.whereCondition) should be considered as a trigger
- * that is intended to instantiate an object of "actionClass". The new instance will
- * receive the full DomElement (level 1 for each child group)
- *
- * @author Esteban Schifman
- */
-public class SqlTablePoller extends AbstractPoller
-{
-/* ___________________ Example XML configuration file for a SqlTablePoller_______________
- *
-<DocumentElementName>
- <ExampleListenChapter
- maxThreads="2"
- listenerClass="org.jboss.soa.esb.listeners.SqlTablePoller"
- actionClass="org.jboss.soa.esb.actions.templates.MockSqlRowAction"
-
- driver-class="org.postgresql.Driver"
- connection-url="jdbc:postgresql://myhost:5432/myDB"
- user-name="postgres"
- password=""
-
- tableName="test_notif_table"
- selectFields="oid,ref,msg"
- keyFields="oid,ref"
- inProcessField="statusCol"
- whereCondition="src='pepe'"
- orderBy="oid desc"
- >
- <NotificationList type="OK">
- <target class="NotifyFiles">
- <file URI="file:///tmp/jbossEsb/notifyDir/ListenOnNotifTable.notifOK"
- append="true"
- />
- </target>
- </NotificationList>
-
- <NotificationList type="err">
- <target class="NotifyFiles">
- <file URI="file:///tmp/jbossEsb/notifyDir/ListenOnNotifTable.notifErr"
- append="true"
- />
- </target>
- </NotificationList>
- </ExampleListenChapter>
-</DocumentElementName>
- *
- */
-
- /**
- * Mandatory attributes needed for SqlTablePoller
- * 1) Table name
- * 2) Comma separated list of fields needed in the ResultSet
- * 3) Comma separated list of fields that constitute a unique ID of the working row
- * all fields in this list MUST also be in the "selectFields" list
- * these fields will be used in the "where" clause of update statements
- * 4) Name of table field used as indicator/semaphore to avoid concurrent update
- *
- */
- public static enum TABLE_ATT
- {
- tableName
- ,selectFields
- ,keyFields
- ,inProcessField
- };
-
- /**
- * Optional fields that can be included in your parameter tree as attributes in the
- * upper Element
- * 1) 4 character long String that indicate status of each row for this poller
- * 1st: Character that indicates "Pending" state = available for processing
- * 2nd: "Working" : some poller is working on the row (or ab-ended while working)
- * 3rd: "Error" : some poller tried to process, and found an error during processing
- * 4th: "Done" : this row has already been processed successfully
- * 2) if you wish to further filter your ResultSet, you can add an optional list of
- * conditions that will be included in the "scan" SQL statement (without "where")
- * 3) Comma separated list of fields to order ResultSet (without "order by")
- *
- */
- public static enum OPTIONAL_ATT
- {
- inProcessVals
- ,whereCondition
- ,orderBy
- };
-
- /**
- * First character of these values are the default states of a table row trigger
- * the "inProcessVals" parameter can override these (if that were ever necessary)
- * this is why the default value for that parameter is "PWED" (see below)
- * The poller will only process rows that have the "inProcessField" first character
- * equal to the first character of whatever the "Pending" state is (typically "P")
- *
- */
- public static enum ROW_STATE
- {Pending
- ,Working
- ,Error
- ,Done
- };
- public static final String DEFAULT_STATES = "PWED";
-
- protected Map<String,String> m_oVals = new HashMap<String,String>();
- protected String[] m_saCols ,m_saKeys;
- protected String m_sUpdStates;
-
- /**
- * In this constructor you can override default values for the following protected base class values:
- * <br/>
- * <p/>m_iMinPollMillis : minimum polling interval (default 3000)
- * <br/>m_iDfltPollMillis : default polling interval (default 20000)
- * <br/>m_iSleepForThreads : how long to sleep if all configured threads are in use (default 3000)
- * <br/>m_iUpperThreadLimit : max number of threads allowed (default 10)
- * @param p_oDad GpListener - The controlling process
- * @param p_oParms DomElement - Sub tree that corresponds to this instance
- * @throws Exception
- */
- public SqlTablePoller(GpListener p_oDad, DomElement p_oParms, ActionDefinitionFactory actionDefinitionFactory) throws Exception
- {
- super(p_oDad, p_oParms, actionDefinitionFactory);
- try { checkMyParms(); }
- catch (Exception e)
- {
- logger.error("checkMyParms() FAILED",e);
- throw e;
- }
- } //__________________________________
-
- private void checkAndStoreAtt(DomElement p_oP, String p_sName, String p_sDflt)
- throws Exception
- {
- m_oVals.put(p_sName,GpListener.obtainAtt(p_oP,p_sName,p_sDflt));
- } //________________________________
-
- protected void checkMyParms() throws Exception
- {
- checkAndStoreAtt(listenerConfig,SimpleDataSource.DRIVER ,null);
- checkAndStoreAtt(listenerConfig,SimpleDataSource.URL ,null);
- checkAndStoreAtt(listenerConfig,SimpleDataSource.USER ,"");
- checkAndStoreAtt(listenerConfig,SimpleDataSource.PASSWORD ,"");
-
- for (TABLE_ATT oCurr : TABLE_ATT.values())
- checkAndStoreAtt(listenerConfig,oCurr.toString(),null);
-
- checkAndStoreAtt(listenerConfig,OPTIONAL_ATT.whereCondition.toString(),"");
- checkAndStoreAtt(listenerConfig,OPTIONAL_ATT.orderBy.toString(),"");
-
- String sAtt = OPTIONAL_ATT.inProcessVals.toString();
- checkAndStoreAtt(listenerConfig,sAtt,DEFAULT_STATES);
- m_sUpdStates = m_oVals.get(sAtt);
- if (m_sUpdStates.length()<4)
- throw new Exception("Parameter <"+sAtt+"> must be at least 4 characters long (PWED)");
-
- StringTokenizer ST = new StringTokenizer
- (m_oVals.get(TABLE_ATT.selectFields.toString()),",");
- m_saCols = new String[ST.countTokens()];
- Set<String> oSelFlds = new HashSet<String>();
- int iCurr = 0;
- while (ST.hasMoreElements())
- {
- String sColName = ST.nextToken().trim();
- m_saCols[iCurr++] = sColName;
- oSelFlds.add(sColName);
- }
-
- ST = new StringTokenizer
- (m_oVals.get(TABLE_ATT.keyFields.toString()),",");
- m_saKeys = new String[ST.countTokens()];
- if (m_saKeys.length < 1)
- throw new Exception("Empty list of keyFields");
-
- for (iCurr = 0; ST.hasMoreTokens(); iCurr++)
- { String sKeyCol = ST.nextToken().trim();
- if (! oSelFlds.contains(sKeyCol))
- throw new Exception("Key field <"+ sKeyCol + "> must also be in select list");
- m_saKeys[iCurr] = sKeyCol;
- }
-
- } //________________________________
-
- @Override
- protected Object preProcess(Object p_o)
- {
- return p_o;
- } //________________________________
-
- @SuppressWarnings("unchecked")
- @Override
- protected List<Object> pollForCandidates()
- {
- String sSel4U = selectForUpdStatement();
- String sUpdStmt = updateStatement();
- JdbcCleanConn oConn = null;
- List<Object> oResults = new ArrayList<Object>();
- try
- {
- oConn = newDbConn();
- String sScan = scanStatement();
-
- PreparedStatement PS = oConn.prepareStatement(sScan);
- ResultSet RS = oConn.execQueryWait(PS,1);
- while (RS.next()) {
- SQLPollResult rowParams = new SQLPollResult(sSel4U, sUpdStmt);
- int iCurr = 0;
-
- for (String sColName : m_saCols) {
- rowParams.put(sColName,RS.getObject(++iCurr));
- }
-
- // Set up the parameter object for the SqlRowAction
- rowParams.sUpdStates = m_sUpdStates;
- rowParams.saKeys = m_saKeys;
- rowParams.sSel4Upd = sSel4U;
- rowParams.sUpdate = sUpdStmt;
-
- // Mark the row as "working"...
- rowParams.changeStatusToWorking();
-
- oResults.add(rowParams);
- }
- }
- catch (Exception e)
- {
- logger.warn("Some triggers might not have been returned",e);
- }
- finally
- {
- if (null!=oConn)
- oConn.release();
- }
-
- logger.info("Returning " + oResults.size() + " rows.");
- return oResults;
- } //________________________________
-
- /**
- * Obtain a new database connection with parameter info
- * @return A new connection
- * @throws Exception - if problems are encountered
- */
- protected JdbcCleanConn newDbConn() throws Exception
- { DataSource oDS = new SimpleDataSource
- (m_oVals.get(SimpleDataSource.DRIVER)
- ,m_oVals.get(SimpleDataSource.URL)
- ,m_oVals.get(SimpleDataSource.USER)
- ,m_oVals.get(SimpleDataSource.PASSWORD)
- );
- return new JdbcCleanConn(oDS);
- } //________________________________
-
- /**
- * Assemble the SQL statement to scan (poll) the table
- * @return - The resulting SQL statement
- */
- protected String scanStatement()
- {
- StringBuilder sb = new StringBuilder ()
- .append("select ").append(m_oVals.get(TABLE_ATT.selectFields.toString()))
- .append(" from ") .append(m_oVals.get(TABLE_ATT.tableName.toString()));
-
- String sAux = m_oVals.get(OPTIONAL_ATT.whereCondition.toString());
- boolean bWhere = ! Util.isNullString(sAux);
- if (bWhere)
- sb.append(" where ").append(sAux);
- sb.append((bWhere) ? " and " : " where ");
-
- String sLike = m_oVals.get(OPTIONAL_ATT.inProcessVals.toString())
- .substring(0,1).toUpperCase();
- sb.append(" upper(").append(m_oVals.get(TABLE_ATT.inProcessField.toString()))
- .append(") like '").append(sLike).append("%'");
-
-
- sAux = m_oVals.get(OPTIONAL_ATT.orderBy);
- if (! Util.isNullString(sAux))
- sb.append(" order by ").append(sAux);
- return sb.toString();
- } //________________________________
-
- /**
- * Assemble the SQL statement to update the field
- * in the "inProcessField" parameter
- *
- * in the table row uniquely identified by the list of fields
- * in the "keyFields" parameter
- *
- * @return - The resulting SQL statement
- */
- protected String updateStatement()
- {
- StringBuilder sb = new StringBuilder ()
- .append("update ").append(m_oVals.get(TABLE_ATT.tableName.toString()))
- .append(" set ") .append(m_oVals.get(TABLE_ATT.inProcessField.toString()))
- .append(" = ? where ")
- ;
- int iCurr = 0;
- for(String sCurr : m_saKeys)
- { if (iCurr++ > 0)
- sb.append(" and ");
- sb.append(sCurr).append(" = ?");
- }
- return sb.toString();
- } //________________________________
-
- /**
- * Assemble the SQL "select for update" statement
- * for the "inProcessField" parameter
- *
- * in the table row uniquely identified by the list of fields
- * in the "keyFields" parameter
- *
- * @return - The resulting SQL statement
- */
- protected String selectForUpdStatement()
- {
- StringBuilder sb = new StringBuilder ()
- .append("select ").append(m_oVals.get(TABLE_ATT.inProcessField.toString()))
- .append(" from ") .append(m_oVals.get(TABLE_ATT.tableName.toString()))
- .append(" where ")
- ;
- int iCurr = 0;
- for(String sCurr : m_saKeys)
- { if (iCurr++ > 0)
- sb.append(" and ");
- sb.append(sCurr).append(" = ?");
- }
- return sb.append(" for update").toString();
- } //________________________________
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#close()
- */
- @Override
- protected void close() {
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#processingError(java.lang.Object, org.jboss.soa.esb.actions.ActionProcessor, java.lang.Throwable)
- */
- @Override
- protected void processingError(Object initialMessage, ActionProcessor processor, Throwable error) {
- // Mark the row as "error"...
- ((SQLPollResult)initialMessage).changeStatusToError();
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#processingComplete(java.lang.Object)
- */
- @Override
- protected void processingComplete(Object initialMessage) {
- // Mark the row as "working"...
- ((SQLPollResult)initialMessage).changeStatusToDone();
- }
-
- private class SQLPollResult extends LinkedHashMap implements Serializable {
- private static final long serialVersionUID = 1L;
-
- private String sUpdStates;
-
- private String[] saKeys;
-
- private String sSel4Upd, sUpdate;
-
- private SQLPollResult(String sSel4Upd, String sUpdate) throws Exception {
- this.sSel4Upd = sSel4Upd;
- this.sUpdate = sUpdate;
- }
-
- private String getStatus(ROW_STATE p_oState) {
- int iPos = p_oState.ordinal();
- return sUpdStates.substring(iPos, ++iPos);
- }
-
- private boolean changeStatusToWorking() {
- return changeStatus(ROW_STATE.Pending, ROW_STATE.Working);
- }
-
- private boolean changeStatusToDone() {
- return changeStatus(ROW_STATE.Working, ROW_STATE.Done);
- }
-
- private boolean changeStatusToError() {
- return changeStatus(ROW_STATE.Working, ROW_STATE.Error);
- }
-
- private boolean changeStatus(ROW_STATE fromState, ROW_STATE toState) {
- JdbcCleanConn dbConnection = null;
-
- try {
- // This is expensive at the moment but will be OK once we get proper connection pooling enabled!
- dbConnection = newDbConn();
- } catch (Exception e) {
- logger.error("Unable to get DB connection.", e);
- throw new IllegalStateException("Unable to get DB connection.", e);
- }
-
- try {
- PreparedStatement m_PSsel4U;
- PreparedStatement m_PSupd;
-
- m_PSsel4U = dbConnection.prepareStatement(sSel4Upd);
- m_PSupd = dbConnection.prepareStatement(sUpdate);
-
- int iParm=1;
- for (String sColName : saKeys) {
- Object oVal = get(sColName);
- m_PSsel4U.setObject (iParm ,oVal);
- // parameters are +1 in update statement
- // autoincrement leaves things ready for next SQL parameter
- m_PSupd.setObject (++iParm,oVal);
- }
-
- try {
- ResultSet resultSet = dbConnection.execQueryWait(m_PSsel4U, 5);
-
- if (resultSet.next()) {
- String sOldStatus = resultSet.getString(1).substring(0, 1);
-
- if (sOldStatus.equalsIgnoreCase(getStatus(fromState))) {
- m_PSupd.setString(1, getStatus(toState));
- dbConnection.execUpdWait(m_PSupd, 5);
- dbConnection.commit();
-
- if(logger.isDebugEnabled()) {
- logger.debug("Successfully changed row state from " + fromState + " to " + toState + ".");
- }
-
- return true;
- } else {
- logger.warn("Cannot change row state from " + fromState + " to " + toState + ". Row not in state " + fromState);
- return false;
- }
- }
- logger.error("Row status change to " + toState + " has failed. Rolling back!!");
- } catch(Exception e) {
- logger.error("Row status change to " + toState + " has failed. Rolling back!!", e);
- }
-
- try {
- dbConnection.rollback();
- } catch (Exception e) {
- logger.error("Unable to rollback row status change to " + fromState.name(), e);
- }
- } catch (Exception e) {
- logger.error("Unexpected exception.", e);
- } finally {
- dbConnection.release();
- }
-
- return false;
- }
- }
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/gatewayExample.xml
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/gatewayExample.xml 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/gatewayExample.xml 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,18 +0,0 @@
-<GatewayListenerControllerExample
- parameterReloadSecs="180"
->
- <JmsGatewayExample
- target-service-name="your target service name"
- service-name="JmsGatewayService"
- listenerClass="org.jboss.soa.esb.listeners.JmsGatewayListener"
- connection-factory="ConnectionFactory"
- destination-type="queue"
- destination-name="queue/A"
- jndi-type="jboss"
- jndi-URL="localhost"
- message-selector="service='composeExampleService'"
- >
- <action class="org.jboss.soa.esb.message.listeners.MockComposer" process="composeEmptyMessage" />
- </JmsGatewayExample>
-
-</GatewayListenerControllerExample>
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners)
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/ActionProcessingPipeline.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,198 +0,0 @@
-package org.jboss.soa.esb.message.listeners;
-
-import java.lang.reflect.*;
-
-import org.apache.log4j.Logger;
-
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.actions.ActionUtils;
-import org.jboss.soa.esb.helpers.ConfigTree;
-
-
-/**
- * Action Processing Pipeline.
- * <p/>
- * Runs a list of action classes on a message
- *
- * @author <a href="mailto:schifest at heuristica.com.ar">schifest at heuristica.com.ar</a>
- * @since Version 4.0
- */
-class ActionProcessingPipeline implements Runnable
-{
-
- /**
- * public constructor
- * @param message Message - The initial message to be run through the whole action
- * class chain
- */
- public ActionProcessingPipeline(Message message)
- throws ConfigurationException
- {
- if (null==_message)
- throw new IllegalArgumentException("Message must be not null");
- _message = message;
- _config = ActionUtils.getConfigTree(_message);
- if (null==_config)
- throw new IllegalArgumentException("Configuration needed for action classes");
- _actionList = _config.getChildren(ListenerTagNames.ACTION_ELEMENT);
- if (null==_actionList || _actionList.length<1)
- throw new ConfigurationException("No actions in list");
- }
-
- /**
- *
- * @return Message - current Message of this action chain processor
- */
- public Message getMessage() { return _message; }
-
- /**
- * Implement Runnable Interface
- * <p/>Uses reflection to instantiate action classes that must have a public constructor
- * that takes a single ConfigTree as argument
- * <p/>Requires each action class to have a public method that takes a Message and returns a Message
- * <br/>Default name for it is 'process' but can optionally be defined in the 'process' attribute
- * of the corresponding <action> element of the ConfigTree
- * <p/>Each <action> element can optionally define a method (taking a Message argument) to be
- * called upon successful completion of the action class (that step of the chain)
- * <br/>Default name for it is 'process' but can optionally be defined in the 'process' attribute
- * <p/>See actionClassException and actionClassFinishedOk
- * */
- public void run()
- {
- try
- {
- // Run the message through each ActionProcessor...
- _currentIndex = -1;
- for(ConfigTree oCurr : _actionList)
- {
- _currentIndex++;
- String attrName = ListenerTagNames.ACTION_CLASS_ATTRIBUTE;
- _currentAction = oCurr.getAttribute(attrName);
-
- attrName = ListenerTagNames.ACTION_PROCESS_METHOD;
- String sProcessMethod = obtainAttribute(oCurr,attrName,attrName);
-
- _currentClass = Class.forName(_currentAction);
- Constructor oConst = _currentClass.getConstructor(new Class[] {ConfigTree.class});
- _currentProcessor = oConst.newInstance(_config);
- Method method = _currentClass.getMethod(sProcessMethod,new Class[] {Message.class});
-
- // The processing result of each action feeds into the processing of the next action...
- try
- {
- // copy currentObject in Message body to 'previous' currentObject
- ActionUtils.copyCurrentToPrevious(_message);
- Message next = (Message)method.invoke(_currentProcessor,new Object[] {_message} );
-
- actionClassFinishedOk(oCurr);
- if(next==null)
- {
- _logger.error(prematureTermination("returned <null> - Cannot continue"));
- return;
- }
- }
- catch (ClassCastException eCast)
- {
- // If action class returns non Message, log and abort chain
- _logger.error(prematureTermination("returned a non Message Object)"));
- return;
- }
- catch (Exception e)
- {
- // If action class threw exception, log and abort chain
- actionClassException(oCurr,e);
- return;
- }
- }
- // notification of action chain end can be done with a no-operation action class
- // with a proper ListenerPropertyNames.ACTION_NORMAL_COMPLETION_CALLBACK method
- // Same idea when some interaction needed with the 'esb unaware' world
- }
- catch(ClassNotFoundException e)
- { _logger.error(prematureTermination("action class is not in path"),e); }
- catch(NoSuchMethodException e)
- { _logger.error(prematureTermination("method not found"),e); }
- catch(InstantiationException e)
- { _logger.error(prematureTermination("cannot instantiate action class"),e); }
- catch(InvocationTargetException e)
- { _logger.error(prematureTermination("method not found"),e); }
- catch(IllegalAccessException e)
- { _logger.error(prematureTermination("unable to access method"),e); }
- catch (IllegalArgumentException e) {}
- }
-
- protected String prematureTermination(String s)
- {
- return new StringBuilder("Premature termination of action processing pipeline ")
- .append(getActionNames())
- .append("]. ActionProcessor [").append(_currentAction)
- .append("] ").append(s)
- .toString()
- ;
- }
-
- /**
- * If 'current' action step was configured with a 'exceptionMethod' attribute
- * that method will be called with a single argument of type Exception
- * @param tree ConfigTree - where to look for the exceptionMetod attribute
- * @param thr Exception - to be used in invocation to method (if found)
- */
- protected void actionClassException(ConfigTree tree, Exception thr)
- {
- thr.printStackTrace();
- String sMethod = obtainAttribute(tree,ListenerTagNames.ACTION_EXCEPTION_CALLBACK,null);
- if (null!=sMethod)
- try
- {
- Method method = _currentClass.getMethod(sMethod,new Class[] {Exception.class});
- method.invoke(_currentProcessor,new Object[] {thr} );
- }
- catch (NoSuchMethodException e) {_logger.error(e); }
- catch (InvocationTargetException e) {_logger.error(e); }
- catch (IllegalAccessException e) {_logger.error(e); }
- }
-
- /**
- * If 'current' action step was configured with an 'okMethod' attribute
- * that method will be called with no arguments
- * @param tree ConfigTree - where to look for the okMetod attribute
- */
- protected void actionClassFinishedOk(ConfigTree tree)
- {
- String sMethod = obtainAttribute(tree,ListenerTagNames.ACTION_NORMAL_COMPLETION_CALLBACK,null);
- if (null!=sMethod)
- try
- {
- Method method = _currentClass.getMethod(sMethod,new Class[] {});
- method.invoke(_currentProcessor,new Object[] {} );
- }
- catch (NoSuchMethodException e) {_logger.error(e); }
- catch (InvocationTargetException e) {_logger.error(e); }
- catch (IllegalAccessException e) {_logger.error(e); }
- }
-
- protected String[] getActionNames()
- {
- String[] sa = new String[_actionList.length];
- int i1=0;
- for (ConfigTree oCurr : _actionList)
- sa[i1++]=obtainAttribute(oCurr,ListenerTagNames.ACTION_CLASS_ATTRIBUTE,"NO_CLASSNAME");
- return sa;
- }
-
- private static String obtainAttribute(ConfigTree tree,String p_sAtt, String p_sDefault)
- {
- String sVal = tree.getAttribute(p_sAtt);
- return (null != sVal) ? sVal : p_sDefault;
- } // ________________________________
-
- protected ConfigTree[] _actionList;
- protected int _currentIndex;
- protected String _currentAction;
- protected Class _currentClass;
- protected Object _currentProcessor;
- protected Message _message;
- protected ConfigTree _config;
- protected Logger _logger = Logger.getLogger(this.getClass());
-}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java (from rev 6961, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/ActionProcessingPipeline.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/ActionProcessingPipeline.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,199 @@
+package org.jboss.soa.esb.listeners.message;
+
+import java.lang.reflect.*;
+
+import org.apache.log4j.Logger;
+
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.actions.ActionUtils;
+import org.jboss.soa.esb.helpers.ConfigTree;
+
+
+/**
+ * Action Processing Pipeline.
+ * <p/>
+ * Runs a list of action classes on a message
+ *
+ * @author <a href="mailto:schifest at heuristica.com.ar">schifest at heuristica.com.ar</a>
+ * @since Version 4.0
+ */
+class ActionProcessingPipeline implements Runnable
+{
+
+ /**
+ * public constructor
+ * @param message Message - The initial message to be run through the whole action
+ * class chain
+ */
+ public ActionProcessingPipeline(Message message)
+ throws ConfigurationException
+ {
+ if (null==_message)
+ throw new IllegalArgumentException("Message must be not null");
+ _message = message;
+ _config = ActionUtils.getConfigTree(_message);
+ if (null==_config)
+ throw new IllegalArgumentException("Configuration needed for action classes");
+ _actionList = _config.getChildren(ListenerTagNames.ACTION_ELEMENT_TAG);
+ if (null==_actionList || _actionList.length<1)
+ throw new ConfigurationException("No actions in list");
+ }
+
+ /**
+ *
+ * @return Message - current Message of this action chain processor
+ */
+ public Message getMessage() { return _message; }
+
+ /**
+ * Implement Runnable Interface
+ * <p/>Uses reflection to instantiate action classes that must have a public constructor
+ * that takes a single ConfigTree as argument
+ * <p/>Requires each action class to have a public method that takes a Message and returns a Message
+ * <br/>Default name for it is 'process' but can optionally be defined in the 'process' attribute
+ * of the corresponding <action> element of the ConfigTree
+ * <p/>Each <action> element can optionally define a method (taking a Message argument) to be
+ * called upon successful completion of the action class (that step of the chain)
+ * <br/>Default name for it is 'process' but can optionally be defined in the 'process' attribute
+ * <p/>See actionClassException and actionClassFinishedOk
+ * */
+ public void run()
+ {
+ try
+ {
+ // Run the message through each ActionProcessor...
+ _currentIndex = -1;
+ for(ConfigTree oCurr : _actionList)
+ {
+ _currentIndex++;
+ String attrName = ListenerTagNames.ACTION_CLASS_TAG;
+ _currentAction = oCurr.getAttribute(attrName);
+
+ attrName = ListenerTagNames.PROCESS_METHOD_TAG;
+ String sProcessMethod = obtainAttribute(oCurr,attrName,attrName);
+
+ _currentClass = Class.forName(_currentAction);
+ Constructor oConst = _currentClass.getConstructor(new Class[] {ConfigTree.class});
+ _currentProcessor = oConst.newInstance(_config);
+ Method method = _currentClass.getMethod(sProcessMethod,new Class[] {Message.class});
+
+ // The processing result of each action feeds into the processing of the next action...
+ try
+ {
+ // copy currentObject in Message body to 'previous' currentObject
+ ActionUtils.copyCurrentToPrevious(_message);
+ Message next = (Message)method.invoke(_currentProcessor,new Object[] {_message} );
+
+ actionClassFinishedOk(oCurr);
+ if(next==null)
+ {
+ _logger.error(prematureTermination("returned <null> - Cannot continue"));
+ return;
+ }
+ }
+ catch (ClassCastException eCast)
+ {
+ // If action class returns non Message, log and abort chain
+ _logger.error(prematureTermination("returned a non Message Object)"));
+ return;
+ }
+ catch (Exception e)
+ {
+ // If action class threw exception, log and abort chain
+ actionClassException(oCurr,e);
+ return;
+ }
+ }
+ // notification of action chain end can be done with a no-operation action class
+ // with a proper ListenerPropertyNames.ACTION_NORMAL_COMPLETION_CALLBACK method
+ // Same idea when some interaction needed with the 'esb unaware' world
+ }
+ catch(ClassNotFoundException e)
+ { _logger.error(prematureTermination("action class is not in path"),e); }
+ catch(NoSuchMethodException e)
+ { _logger.error(prematureTermination("method not found"),e); }
+ catch(InstantiationException e)
+ { _logger.error(prematureTermination("cannot instantiate action class"),e); }
+ catch(InvocationTargetException e)
+ { _logger.error(prematureTermination("method not found"),e); }
+ catch(IllegalAccessException e)
+ { _logger.error(prematureTermination("unable to access method"),e); }
+ catch (IllegalArgumentException e) {}
+ }
+
+ protected String prematureTermination(String s)
+ {
+ return new StringBuilder("Premature termination of action processing pipeline ")
+ .append(getActionNames())
+ .append("]. ActionProcessor [").append(_currentAction)
+ .append("] ").append(s)
+ .toString()
+ ;
+ }
+
+ /**
+ * If 'current' action step was configured with a 'exceptionMethod' attribute
+ * that method will be called with a single argument of type Exception
+ * @param tree ConfigTree - where to look for the exceptionMetod attribute
+ * @param thr Exception - to be used in invocation to method (if found)
+ */
+ protected void actionClassException(ConfigTree tree, Exception thr)
+ {
+ thr.printStackTrace();
+ String sMethod = obtainAttribute(tree,ListenerTagNames.EXCEPTION_METHOD_TAG,null);
+ if (null!=sMethod)
+ try
+ {
+ Method method = _currentClass.getMethod(sMethod,new Class[] {Exception.class});
+ method.invoke(_currentProcessor,new Object[] {thr} );
+ }
+ catch (NoSuchMethodException e) {_logger.error(e); }
+ catch (InvocationTargetException e) {_logger.error(e); }
+ catch (IllegalAccessException e) {_logger.error(e); }
+ }
+
+ /**
+ * If 'current' action step was configured with an 'okMethod' attribute
+ * that method will be called with no arguments
+ * @param tree ConfigTree - where to look for the okMetod attribute
+ */
+ protected void actionClassFinishedOk(ConfigTree tree)
+ {
+ String sMethod = obtainAttribute(tree,ListenerTagNames.NORMAL_COMPLETION_METHOD_TAG,null);
+ if (null!=sMethod)
+ try
+ {
+ Method method = _currentClass.getMethod(sMethod,new Class[] {});
+ method.invoke(_currentProcessor,new Object[] {} );
+ }
+ catch (NoSuchMethodException e) {_logger.error(e); }
+ catch (InvocationTargetException e) {_logger.error(e); }
+ catch (IllegalAccessException e) {_logger.error(e); }
+ }
+
+ protected String[] getActionNames()
+ {
+ String[] sa = new String[_actionList.length];
+ int i1=0;
+ for (ConfigTree oCurr : _actionList)
+ sa[i1++]=obtainAttribute(oCurr,ListenerTagNames.ACTION_CLASS_TAG,"NO_CLASSNAME");
+ return sa;
+ }
+
+ private static String obtainAttribute(ConfigTree tree,String p_sAtt, String p_sDefault)
+ {
+ String sVal = tree.getAttribute(p_sAtt);
+ return (null != sVal) ? sVal : p_sDefault;
+ } // ________________________________
+
+ protected ConfigTree[] _actionList;
+ protected int _currentIndex;
+ protected String _currentAction;
+ protected Class _currentClass;
+ protected Object _currentProcessor;
+ protected Message _message;
+ protected ConfigTree _config;
+ protected Logger _logger = Logger.getLogger(this.getClass());
+}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/EsbListenerController.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/EsbListenerController.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/EsbListenerController.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,540 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.message.listeners;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-import org.jboss.internal.soa.esb.command.CommandQueue;
-import org.jboss.internal.soa.esb.command.CommandQueueException;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.addressing.util.EPRManager;
-import org.jboss.soa.esb.addressing.EPR;
-import org.jboss.soa.esb.common.Environment;
-import org.jboss.soa.esb.common.ModulePropertyManager;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.parameters.ParamRepositoryException;
-import org.jboss.soa.esb.parameters.ParamRepositoryFactory;
-import org.jboss.soa.esb.util.Util;
-import org.xml.sax.SAXException;
-
-import com.arjuna.common.util.propertyservice.PropertyManager;
-
-/**
- * Controlling class that will launch 'message aware' listener child threads for supported
- * transport listener classes, as indicated in the configuration XML tree used in the constructor
- * If you use the 'main' method, configuration file is expected in arg[0]
- *
- * <p />
- * Can be launched as uppermost controller (it has a main(args) method)
- * <p />
- * Also implements Runnable, and can thus be launched in a child thread from an
- * upper controlling process
- * <p />
- * Listens on a JMS queue (with an optional message selector) for commands (e.g.
- * Quiesce, Reload Parameters, Set End Time, etc.)
- * <p />
- * Parameter reloading can also be set using the PARM_RELOAD_SECS attribute
- * <p />
- * End time for this instance can also be set using the PARM_END_TIME attribute
- * <p />
- *
- * @author <a href="mailto:schifest at heuristica.com.ar">schifest at heuristica.com.ar</a>
- * @since Version 4.0
- */
-public class EsbListenerController implements Runnable {
-
- private static Logger _logger = Logger.getLogger(EsbListenerController.class);
-
- public static void main(String[] args) throws Exception {
- EsbListenerController oProc = new EsbListenerController(args[0]);
- oProc.run();
- EsbListenerController.State oS = oProc.getState();
-
- if (null != oS.getException()) {
- _logger.error("EsbListenerController <" + args[0] + "> FAILED\n", oS
- .getException());
- }
- System.exit(oS.getCompletionCode());
- } // ________________________________
-
- protected int m_iDfltReloadMillis = 180000 // default interval between
- // parameter reloads
- ;
-
- public static final String PARM_RELOAD_SECS = "parameterReloadSecs";
- public static final String PARM_END_TIME = "endTime";
-
- // Attribute name that denotes listener class to be instantiated in a child
- // thread
- // This attribute is not in the root node but in first level child
- // ConfigTrees
- public static final String PARM_LISTENER_CLASS = "listenerClass";
-
- private String m_sParmsName;
- private ConfigTree m_oParms;
-
- private HashMap<String, Object> m_oAtts;
-
- /**
- * Obtain a shallow copy of needed atributes in this object's last loaded
- * parameter tree <p/>The local bject is cloned so child threads can use it
- * as they choose to without interfering with the environment
- * <p />
- * Listener processes controlled by this object should keep a reference to
- * this object at construction time, and not call this method again unless
- * they specifically need updated values. Parameter reload could have
- * happened since last call
- *
- * @return Map - a shallow copy of the attributes Map
- */
- @SuppressWarnings("unchecked")
- public Map<String, Object> getControllerAttributes() {
- return (Map<String, Object>) m_oAtts.clone();
- }
-
- private boolean m_bReloadRequested, m_bEndRequested;
-
- private long m_lNextReload = Long.MAX_VALUE;
-
- private long m_lEndTime = Long.MAX_VALUE;
-
- public static final SimpleDateFormat s_oDateParse = new SimpleDateFormat(
- "yyyyMMdd hh:mm:ss");
-
- private State m_oState = null;
-
- public State getState() {
- return m_oState;
- }
-
- public static enum State {
- Loading_parameters, Running, Shutting_down, Done_OK, Exception_thrown;
- int m_iCompletionCode = 0;
-
- Exception m_oException = null;
-
- public int getCompletionCode() {
- return m_iCompletionCode;
- };
-
- public Exception getException() {
- return m_oException;
- }
- };
-
- private CommandQueue commandQueue;
- private static CommandQueue defaultCommandQueue = null;
-
- /**
- * No default constructor - only for child classes
- */
- protected EsbListenerController() { }
-
- /**
- * Construct a Listener Manager from the named repository based
- * configuration.
- *
- * @param p_sParameterName
- * Name of the Repository entry containing the configuration.
- * @throws Exception
- * Unable to load/use the named configuration.
- */
- public EsbListenerController(String p_sParameterName) throws Exception {
- this(EsbListenerController.getListenerConfig(p_sParameterName));
- m_sParmsName = p_sParameterName;
- }
-
- /**
- * Construct a Listener Controller using the specified listener configuration.
- *
- * @param config
- * The configuration.
- * @throws Exception
- * Unable to load/use the supplied configuration.
- */
- public EsbListenerController(ConfigTree config) throws Exception {
- m_oParms = config;
- m_oState = State.Loading_parameters;
-
- try { checkParms(m_oParms); }
- catch (Exception e)
- {
- String configSource = config.getAttribute("configSource");
-
- m_oState = State.Exception_thrown;
- m_oState.m_oException = e;
- _logger.fatal("Listener configuration and startup error. Config Source: "
- + (configSource != null ? configSource
- : "unknown"), e);
-
- throw e;
- }
- }
-
- /**
- * Load the named listener configuration from the configured parameter
- * repository.
- *
- * @param reposParam
- * The name of the repository entry containing the Listener
- * configuration.
- * @return Listener Configuration as {@link ConfigTree}.
- * @throws IOException
- * Unable to access the repository.
- * @throws ParamRepositoryException
- * Unable to access the configuration in the repository.
- * @throws SAXException
- * Unable to parse the configuration.
- */
- private static ConfigTree getListenerConfig(String reposParam)
- throws IOException, ParamRepositoryException, SAXException {
- String sXml = ParamRepositoryFactory.getInstance().get(reposParam);
- ConfigTree config = ConfigTree.fromXml(sXml);
-
- config.setAttribute("configSource", "param-repository:" + reposParam);
-
- return config;
- }
-
- /**
- * Check to see if all needed parameters are there, and assign default
- * values to some of them
- *
- * @param p_oP
- * ConfigTree - Where to look for the mandatory/optional
- * configuration attributes
- * @throws Exception -
- * If attributes are wrong or not enough for a proper runtime
- * configuration
- */
- public void checkParms(ConfigTree p_oP) throws Exception {
- // We've just loaded - set to false until next reload requested
- m_bReloadRequested = false;
- commandQueue = createCommandQueue(p_oP);
-
- // Open the command queue...
- if (null!=commandQueue)
- commandQueue.open(org.jboss.soa.esb.helpers.DomElement.fromConfigTree(p_oP));
-
- // if PARM_RELOAD_SECS not set, and no command queue
- // then reload every 10 minutes
- // If there is a command queue, run until command is received
- String sRldSecs = p_oP.getAttribute(PARM_RELOAD_SECS);
- m_lNextReload = (null != sRldSecs)
- ? System.currentTimeMillis() + 1000 * Long.parseLong(sRldSecs)
- : (null == commandQueue)
- ? Long.MAX_VALUE
- : System.currentTimeMillis() + m_iDfltReloadMillis;
-
- // if PARM_END_TIME not set try to run forever
- // not a good practice if command queue is not set
- // Expected date format is "yyyyMMdd hh:mm:ss"
- String sEndT = p_oP.getAttribute(PARM_END_TIME);
- m_lEndTime = (null == sEndT) ? Long.MAX_VALUE : s_oDateParse.parse(
- sEndT).getTime();
-
- // Read and initialise the action definitions...
- ConfigTree actionConfig = p_oP.getFirstChild("Actions");
- if(actionConfig == null) {
- throw new ConfigurationException("No 'Actions' configuration.");
- }
- } // ________________________________
-
- /**
- * Factory method for creating the command queue.
- * @param config EsbListenerController config.
- * @return EsbListenerController CommandQueue instance.
- */
- private CommandQueue createCommandQueue(ConfigTree config) {
- String commandQueueClass = config.getAttribute("command-queue-class");
-
- if(commandQueueClass != null) {
- try {
- return (CommandQueue) Class.forName(commandQueueClass).newInstance();
- } catch (Exception e) {
- _logger.error("Failed to instantiate CommandQueue ["+ commandQueueClass + "]. Defaulting to no Command Queue", e);
- }
- }
-
- return defaultCommandQueue;
- }
-
- /**
- * Allows a default command queue to be set statically for all EsbListenerController instances.
- * @param defaultCommandQueue The defaultCommandQueue to set.
- */
- public static void setDefaultCommandQueue(CommandQueue defaultCommandQueue) {
- EsbListenerController.defaultCommandQueue = defaultCommandQueue;
- }
-
- /**
- * Main execution loop <p/> Will continue to run until either <p/>a) run
- * time is expired <p/>b) quiesce command is received in command queue
- * <p/>For every child element that contains a PARM_LISTENER_CLASS
- * attribute, this method will try to launch a child thread instantiating an
- * object of that class, and will call it's run() method <p/>Once all child
- * processes are trigered, the main thread will either <p/>1) wait for a
- * message in the command queue (if one was configured) until next reload or
- * end of run period expired <p/>or 2) Just sleep if there's no command
- * queue to listen on
- */
- public void run() {
- while (endNotRequested()) {
- m_oState = State.Running;
- for (ConfigTree oCurr : m_oParms.getAllChildren()) {
- String sClass = oCurr.getAttribute(PARM_LISTENER_CLASS);
- if (Util.isNullString(sClass))
- continue;
- tryToLaunchChildListener(oCurr, sClass);
- }
-
- waitForCmdOrSleep();
-
- if (endRequested()) {
- break;
- }
- if (m_sParmsName != null && timeToReload()) {
- try {
- m_oState = State.Loading_parameters;
- _logger
- .info("Reloading parameters _____________________________________________________");
- ConfigTree oNew = EsbListenerController.getListenerConfig(m_sParmsName);
- checkParms(oNew);
- m_oParms = oNew;
- } catch (Exception e) {
- _logger.error("Failed to reload parameters"
- + " - Continuing with cached version", e);
- }
- }
- }
- // m_oState = State.Shutting_down;
-
- m_oState = State.Done_OK;
- m_oState.m_iCompletionCode = 0;
- _logger
- .info("Finishing_____________________________________________________");
-
- // Close the command queue...
- try {
- commandQueue.close();
- } catch (CommandQueueException e) {
- _logger.error("Error closing Command Queue.", e);
- }
- } // ________________________________
-
- private void tryToLaunchChildListener(ConfigTree p_oP, String p_sClassName) {
- try
- {
- Class oListener = Class.forName(p_sClassName);
- Constructor oConst = oListener.getConstructor(new Class[] {this.getClass(), ConfigTree.class});
- Runnable oRun = (Runnable) oConst.newInstance(new Object[] { this,p_oP});
- new Thread(oRun).start();
- }
- catch (Exception e)
- {
- _logger.error("Cannot launch <" + p_sClassName + ">\n", e);
- }
- } // ________________________________
-
- long millisToWait() {
- return Math.min(m_lNextReload, m_lEndTime) - System.currentTimeMillis();
- } // ________________________________
-
- private void waitForCmdOrSleep() {
- long lToGo = millisToWait();
-
- if (null == commandQueue) {
- _logger.debug("About to sleep " + lToGo);
- // No command queue nor topic - Just sleep until time
- // exhausted, or thread interrupted
- try {
- if (lToGo > 0)
- Thread.sleep(lToGo);
- } catch (InterruptedException e) {
- m_lEndTime = 0; // mark as end requested and return
- }
- return;
- }
-
- // Wait for commands until time exhausted or command received
- // Note that received commands might change time variables (reload/end)
- // that's why time to go is recalculated on each cycle
- while ((lToGo = millisToWait()) > 0) {
- try {
- _logger.info("Waiting for command ... timeout=" + lToGo + " millis");
-
- String oM = commandQueue.receiveCommand(lToGo);
- if (null == oM) {
- return;
- }
- processCommand(oM);
- if (endRequested() || timeToReload()) {
- break;
- }
- } catch (CommandQueueException eJ) {
- _logger.info("receive on command queue failed", eJ);
- }
- }
- } // ________________________________
-
- /**
- * Processes the command that has been received in the command queue (or
- * topic) <p/>m_bEndRequested, m_bReloadRequested, and m_lEndTime could be
- * changed
- *
- * <p/> <p/><TABLE border="1"> <COLGROUP> <COL width="200"/> <COL
- * width="400"/> </COLGROUP>
- * <TR>
- * <TD align="center">message text</TD>
- * <TD align="center">effect</TD>
- * </TR>
- * <TR>
- * <TD>shutdown*</TD>
- * <TD>End time will be immediately set to 'now' - quiesce process will
- * start - Child threads will be allowed to finish normally</TD>
- * </TR>
- * <TR>
- * <TD>reload param*</TD>
- * <TD>Parameters will be immediately reloaded, and listener reconfigured
- * with new values</TD>
- * </TR>
- * <TR>
- * <TD>endTime yyyyMMdd hh:mm:ss</TD>
- * <TD>End time will be set to new value. If hh:mm:ss is not supplied =>
- * end of day assumed (23:59:59)</TD>
- * </TR>
- * </TABLE> * startsWith() <p/>
- *
- * @param p_oMsg
- * Message received from the command queue.
- *
- */
- private void processCommand(String sTxt) {
- if (null == sTxt)
- return;
-
- String sLow = sTxt.trim().toLowerCase();
- if (sLow.startsWith("shutdown")) {
- m_bEndRequested = true;
- _logger.info("Shutdown has been requested");
- return;
- }
- if (sLow.startsWith("reload param")) {
- m_bReloadRequested = true;
- _logger
- .info("Request for parameter reload has been received");
- return;
- }
- String[] sa = sLow.split("\\s+");
- if (sa.length > 1 && "endtime".equals(sa[0])) {
- try {
- String sDate = sa[1];
- String sTime = (sa.length < 3 || null == sa[2]) ? "23:59:59"
- : sa[2];
- Date oEnd = s_oDateParse.parse(sDate + " " + sTime);
- _logger.info("New end date set to : " + oEnd);
- m_lEndTime = oEnd.getTime();
- } catch (Exception eDat) {
- _logger.info("Problems with endTime command", eDat);
- }
- }
- } // ________________________________
-
- /**
- * Accessor to determine if execution time is expired or shutdown requested
- *
- * @return boolean if processing has to stop (all child threads will be
- * allowed to finish)
- */
- public boolean endRequested() {
- return m_bEndRequested || System.currentTimeMillis() >= m_lEndTime;
- }
-
- /**
- * Accessor to determine if execution time is not expired, and no shutdown
- * request received
- *
- * @return boolean - true if run time has not expired and quiesce has not
- * been requested
- */
- public boolean endNotRequested() {
- return !endRequested();
- }
-
- /**
- * Provide a common accessor to determine if parameters have to be reloaded
- * <p/> For child threads this means thread execution has to end
- * </p>
- * Child processes should only call this method when they are idle (as
- * opposed to in the middle of executing a unit of work)
- *
- * @return boolean - true if it's time to reload parameters
- */
- public boolean timeToReload() {
- return m_bReloadRequested
- || System.currentTimeMillis() >= m_lNextReload;
- }
-
- /**
- * Helper accessor for child processes that provides info to determine if
- * they can continue with yet another execution cycle
- *
- * @return boolean - true if runtime is not expired and not time yet to
- * reload parameters
- */
- public boolean continueLooping() {
- return (endNotRequested() && !timeToReload());
- } // ________________________________
-
- private static EPRManager getEprManager()
- {
- PropertyManager manager = ModulePropertyManager.getPropertyManager(ModulePropertyManager.CORE_MODULE);
- String sDir = manager.getProperty(Environment.REGISTRY_FILE_HELPER_DIR,".");
- return EPRManager.getInstance(sDir);
- }
-
- public void register (String name, EPR address)
- {
- try { getEprManager().saveEPR(name,address); }
- catch (IOException e)
- {
- _logger.fatal("Cannot register service",e);
- }
- } // ________________________________
-
- public void unRegister (String name)
- {
- try { getEprManager().removeEPR(name); }
- catch (IOException e)
- {
- _logger.fatal("Cannot un-register service",e);
- }
- } // ________________________________
-
-} // ____________________________________________________________________________
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/EsbListenerController.java (from rev 6961, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/EsbListenerController.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/EsbListenerController.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/EsbListenerController.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,540 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.soa.esb.listeners.message;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.command.CommandQueue;
+import org.jboss.internal.soa.esb.command.CommandQueueException;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.addressing.util.EPRManager;
+import org.jboss.soa.esb.addressing.EPR;
+import org.jboss.soa.esb.common.Environment;
+import org.jboss.soa.esb.common.ModulePropertyManager;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.parameters.ParamRepositoryException;
+import org.jboss.soa.esb.parameters.ParamRepositoryFactory;
+import org.jboss.soa.esb.util.Util;
+import org.xml.sax.SAXException;
+
+import com.arjuna.common.util.propertyservice.PropertyManager;
+
+/**
+ * Controlling class that will launch 'message aware' listener child threads for supported
+ * transport listener classes, as indicated in the configuration XML tree used in the constructor
+ * If you use the 'main' method, configuration file is expected in arg[0]
+ *
+ * <p />
+ * Can be launched as uppermost controller (it has a main(args) method)
+ * <p />
+ * Also implements Runnable, and can thus be launched in a child thread from an
+ * upper controlling process
+ * <p />
+ * Listens on a JMS queue (with an optional message selector) for commands (e.g.
+ * Quiesce, Reload Parameters, Set End Time, etc.)
+ * <p />
+ * Parameter reloading can also be set using the PARM_RELOAD_SECS attribute
+ * <p />
+ * End time for this instance can also be set using the PARM_END_TIME attribute
+ * <p />
+ *
+ * @author <a href="mailto:schifest at heuristica.com.ar">schifest at heuristica.com.ar</a>
+ * @since Version 4.0
+ */
+public class EsbListenerController implements Runnable {
+
+ private static Logger _logger = Logger.getLogger(EsbListenerController.class);
+
+ public static void main(String[] args) throws Exception {
+ EsbListenerController oProc = new EsbListenerController(args[0]);
+ oProc.run();
+ EsbListenerController.State oS = oProc.getState();
+
+ if (null != oS.getException()) {
+ _logger.error("EsbListenerController <" + args[0] + "> FAILED\n", oS
+ .getException());
+ }
+ System.exit(oS.getCompletionCode());
+ } // ________________________________
+
+ protected int m_iDfltReloadMillis = 180000 // default interval between
+ // parameter reloads
+ ;
+
+ public static final String PARM_RELOAD_SECS = "parameterReloadSecs";
+ public static final String PARM_END_TIME = "endTime";
+
+ // Attribute name that denotes listener class to be instantiated in a child
+ // thread
+ // This attribute is not in the root node but in first level child
+ // ConfigTrees
+ public static final String PARM_LISTENER_CLASS = "listenerClass";
+
+ private String m_sParmsName;
+ private ConfigTree m_oParms;
+
+ private HashMap<String, Object> m_oAtts;
+
+ /**
+ * Obtain a shallow copy of needed atributes in this object's last loaded
+ * parameter tree <p/>The local bject is cloned so child threads can use it
+ * as they choose to without interfering with the environment
+ * <p />
+ * Listener processes controlled by this object should keep a reference to
+ * this object at construction time, and not call this method again unless
+ * they specifically need updated values. Parameter reload could have
+ * happened since last call
+ *
+ * @return Map - a shallow copy of the attributes Map
+ */
+ @SuppressWarnings("unchecked")
+ public Map<String, Object> getControllerAttributes() {
+ return (Map<String, Object>) m_oAtts.clone();
+ }
+
+ private boolean m_bReloadRequested, m_bEndRequested;
+
+ private long m_lNextReload = Long.MAX_VALUE;
+
+ private long m_lEndTime = Long.MAX_VALUE;
+
+ public static final SimpleDateFormat s_oDateParse = new SimpleDateFormat(
+ "yyyyMMdd hh:mm:ss");
+
+ private State m_oState = null;
+
+ public State getState() {
+ return m_oState;
+ }
+
+ public static enum State {
+ Loading_parameters, Running, Shutting_down, Done_OK, Exception_thrown;
+ int m_iCompletionCode = 0;
+
+ Exception m_oException = null;
+
+ public int getCompletionCode() {
+ return m_iCompletionCode;
+ };
+
+ public Exception getException() {
+ return m_oException;
+ }
+ };
+
+ private CommandQueue commandQueue;
+ private static CommandQueue defaultCommandQueue = null;
+
+ /**
+ * No default constructor - only for child classes
+ */
+ protected EsbListenerController() { }
+
+ /**
+ * Construct a Listener Manager from the named repository based
+ * configuration.
+ *
+ * @param p_sParameterName
+ * Name of the Repository entry containing the configuration.
+ * @throws Exception
+ * Unable to load/use the named configuration.
+ */
+ public EsbListenerController(String p_sParameterName) throws Exception {
+ this(EsbListenerController.getListenerConfig(p_sParameterName));
+ m_sParmsName = p_sParameterName;
+ }
+
+ /**
+ * Construct a Listener Controller using the specified listener configuration.
+ *
+ * @param config
+ * The configuration.
+ * @throws Exception
+ * Unable to load/use the supplied configuration.
+ */
+ public EsbListenerController(ConfigTree config) throws Exception {
+ m_oParms = config;
+ m_oState = State.Loading_parameters;
+
+ try { checkParms(m_oParms); }
+ catch (Exception e)
+ {
+ String configSource = config.getAttribute("configSource");
+
+ m_oState = State.Exception_thrown;
+ m_oState.m_oException = e;
+ _logger.fatal("Listener configuration and startup error. Config Source: "
+ + (configSource != null ? configSource
+ : "unknown"), e);
+
+ throw e;
+ }
+ }
+
+ /**
+ * Load the named listener configuration from the configured parameter
+ * repository.
+ *
+ * @param reposParam
+ * The name of the repository entry containing the Listener
+ * configuration.
+ * @return Listener Configuration as {@link ConfigTree}.
+ * @throws IOException
+ * Unable to access the repository.
+ * @throws ParamRepositoryException
+ * Unable to access the configuration in the repository.
+ * @throws SAXException
+ * Unable to parse the configuration.
+ */
+ private static ConfigTree getListenerConfig(String reposParam)
+ throws IOException, ParamRepositoryException, SAXException {
+ String sXml = ParamRepositoryFactory.getInstance().get(reposParam);
+ ConfigTree config = ConfigTree.fromXml(sXml);
+
+ config.setAttribute("configSource", "param-repository:" + reposParam);
+
+ return config;
+ }
+
+ /**
+ * Check to see if all needed parameters are there, and assign default
+ * values to some of them
+ *
+ * @param p_oP
+ * ConfigTree - Where to look for the mandatory/optional
+ * configuration attributes
+ * @throws Exception -
+ * If attributes are wrong or not enough for a proper runtime
+ * configuration
+ */
+ public void checkParms(ConfigTree p_oP) throws Exception {
+ // We've just loaded - set to false until next reload requested
+ m_bReloadRequested = false;
+ commandQueue = createCommandQueue(p_oP);
+
+ // Open the command queue...
+ if (null!=commandQueue)
+ commandQueue.open(org.jboss.soa.esb.helpers.DomElement.fromConfigTree(p_oP));
+
+ // if PARM_RELOAD_SECS not set, and no command queue
+ // then reload every 10 minutes
+ // If there is a command queue, run until command is received
+ String sRldSecs = p_oP.getAttribute(PARM_RELOAD_SECS);
+ m_lNextReload = (null != sRldSecs)
+ ? System.currentTimeMillis() + 1000 * Long.parseLong(sRldSecs)
+ : (null == commandQueue)
+ ? Long.MAX_VALUE
+ : System.currentTimeMillis() + m_iDfltReloadMillis;
+
+ // if PARM_END_TIME not set try to run forever
+ // not a good practice if command queue is not set
+ // Expected date format is "yyyyMMdd hh:mm:ss"
+ String sEndT = p_oP.getAttribute(PARM_END_TIME);
+ m_lEndTime = (null == sEndT) ? Long.MAX_VALUE : s_oDateParse.parse(
+ sEndT).getTime();
+
+ // Read and initialise the action definitions...
+ ConfigTree actionConfig = p_oP.getFirstChild("Actions");
+ if(actionConfig == null) {
+ throw new ConfigurationException("No 'Actions' configuration.");
+ }
+ } // ________________________________
+
+ /**
+ * Factory method for creating the command queue.
+ * @param config EsbListenerController config.
+ * @return EsbListenerController CommandQueue instance.
+ */
+ private CommandQueue createCommandQueue(ConfigTree config) {
+ String commandQueueClass = config.getAttribute("command-queue-class");
+
+ if(commandQueueClass != null) {
+ try {
+ return (CommandQueue) Class.forName(commandQueueClass).newInstance();
+ } catch (Exception e) {
+ _logger.error("Failed to instantiate CommandQueue ["+ commandQueueClass + "]. Defaulting to no Command Queue", e);
+ }
+ }
+
+ return defaultCommandQueue;
+ }
+
+ /**
+ * Allows a default command queue to be set statically for all EsbListenerController instances.
+ * @param defaultCommandQueue The defaultCommandQueue to set.
+ */
+ public static void setDefaultCommandQueue(CommandQueue defaultCommandQueue) {
+ EsbListenerController.defaultCommandQueue = defaultCommandQueue;
+ }
+
+ /**
+ * Main execution loop <p/> Will continue to run until either <p/>a) run
+ * time is expired <p/>b) quiesce command is received in command queue
+ * <p/>For every child element that contains a PARM_LISTENER_CLASS
+ * attribute, this method will try to launch a child thread instantiating an
+ * object of that class, and will call it's run() method <p/>Once all child
+ * processes are trigered, the main thread will either <p/>1) wait for a
+ * message in the command queue (if one was configured) until next reload or
+ * end of run period expired <p/>or 2) Just sleep if there's no command
+ * queue to listen on
+ */
+ public void run() {
+ while (endNotRequested()) {
+ m_oState = State.Running;
+ for (ConfigTree oCurr : m_oParms.getAllChildren()) {
+ String sClass = oCurr.getAttribute(PARM_LISTENER_CLASS);
+ if (Util.isNullString(sClass))
+ continue;
+ tryToLaunchChildListener(oCurr, sClass);
+ }
+
+ waitForCmdOrSleep();
+
+ if (endRequested()) {
+ break;
+ }
+ if (m_sParmsName != null && timeToReload()) {
+ try {
+ m_oState = State.Loading_parameters;
+ _logger
+ .info("Reloading parameters _____________________________________________________");
+ ConfigTree oNew = EsbListenerController.getListenerConfig(m_sParmsName);
+ checkParms(oNew);
+ m_oParms = oNew;
+ } catch (Exception e) {
+ _logger.error("Failed to reload parameters"
+ + " - Continuing with cached version", e);
+ }
+ }
+ }
+ // m_oState = State.Shutting_down;
+
+ m_oState = State.Done_OK;
+ m_oState.m_iCompletionCode = 0;
+ _logger
+ .info("Finishing_____________________________________________________");
+
+ // Close the command queue...
+ try {
+ commandQueue.close();
+ } catch (CommandQueueException e) {
+ _logger.error("Error closing Command Queue.", e);
+ }
+ } // ________________________________
+
+ private void tryToLaunchChildListener(ConfigTree p_oP, String p_sClassName) {
+ try
+ {
+ Class oListener = Class.forName(p_sClassName);
+ Constructor oConst = oListener.getConstructor(new Class[] {this.getClass(), ConfigTree.class});
+ Runnable oRun = (Runnable) oConst.newInstance(new Object[] { this,p_oP});
+ new Thread(oRun).start();
+ }
+ catch (Exception e)
+ {
+ _logger.error("Cannot launch <" + p_sClassName + ">\n", e);
+ }
+ } // ________________________________
+
+ long millisToWait() {
+ return Math.min(m_lNextReload, m_lEndTime) - System.currentTimeMillis();
+ } // ________________________________
+
+ private void waitForCmdOrSleep() {
+ long lToGo = millisToWait();
+
+ if (null == commandQueue) {
+ _logger.debug("About to sleep " + lToGo);
+ // No command queue nor topic - Just sleep until time
+ // exhausted, or thread interrupted
+ try {
+ if (lToGo > 0)
+ Thread.sleep(lToGo);
+ } catch (InterruptedException e) {
+ m_lEndTime = 0; // mark as end requested and return
+ }
+ return;
+ }
+
+ // Wait for commands until time exhausted or command received
+ // Note that received commands might change time variables (reload/end)
+ // that's why time to go is recalculated on each cycle
+ while ((lToGo = millisToWait()) > 0) {
+ try {
+ _logger.info("Waiting for command ... timeout=" + lToGo + " millis");
+
+ String oM = commandQueue.receiveCommand(lToGo);
+ if (null == oM) {
+ return;
+ }
+ processCommand(oM);
+ if (endRequested() || timeToReload()) {
+ break;
+ }
+ } catch (CommandQueueException eJ) {
+ _logger.info("receive on command queue failed", eJ);
+ }
+ }
+ } // ________________________________
+
+ /**
+ * Processes the command that has been received in the command queue (or
+ * topic) <p/>m_bEndRequested, m_bReloadRequested, and m_lEndTime could be
+ * changed
+ *
+ * <p/> <p/><TABLE border="1"> <COLGROUP> <COL width="200"/> <COL
+ * width="400"/> </COLGROUP>
+ * <TR>
+ * <TD align="center">message text</TD>
+ * <TD align="center">effect</TD>
+ * </TR>
+ * <TR>
+ * <TD>shutdown*</TD>
+ * <TD>End time will be immediately set to 'now' - quiesce process will
+ * start - Child threads will be allowed to finish normally</TD>
+ * </TR>
+ * <TR>
+ * <TD>reload param*</TD>
+ * <TD>Parameters will be immediately reloaded, and listener reconfigured
+ * with new values</TD>
+ * </TR>
+ * <TR>
+ * <TD>endTime yyyyMMdd hh:mm:ss</TD>
+ * <TD>End time will be set to new value. If hh:mm:ss is not supplied =>
+ * end of day assumed (23:59:59)</TD>
+ * </TR>
+ * </TABLE> * startsWith() <p/>
+ *
+ * @param p_oMsg
+ * Message received from the command queue.
+ *
+ */
+ private void processCommand(String sTxt) {
+ if (null == sTxt)
+ return;
+
+ String sLow = sTxt.trim().toLowerCase();
+ if (sLow.startsWith("shutdown")) {
+ m_bEndRequested = true;
+ _logger.info("Shutdown has been requested");
+ return;
+ }
+ if (sLow.startsWith("reload param")) {
+ m_bReloadRequested = true;
+ _logger
+ .info("Request for parameter reload has been received");
+ return;
+ }
+ String[] sa = sLow.split("\\s+");
+ if (sa.length > 1 && "endtime".equals(sa[0])) {
+ try {
+ String sDate = sa[1];
+ String sTime = (sa.length < 3 || null == sa[2]) ? "23:59:59"
+ : sa[2];
+ Date oEnd = s_oDateParse.parse(sDate + " " + sTime);
+ _logger.info("New end date set to : " + oEnd);
+ m_lEndTime = oEnd.getTime();
+ } catch (Exception eDat) {
+ _logger.info("Problems with endTime command", eDat);
+ }
+ }
+ } // ________________________________
+
+ /**
+ * Accessor to determine if execution time is expired or shutdown requested
+ *
+ * @return boolean if processing has to stop (all child threads will be
+ * allowed to finish)
+ */
+ public boolean endRequested() {
+ return m_bEndRequested || System.currentTimeMillis() >= m_lEndTime;
+ }
+
+ /**
+ * Accessor to determine if execution time is not expired, and no shutdown
+ * request received
+ *
+ * @return boolean - true if run time has not expired and quiesce has not
+ * been requested
+ */
+ public boolean endNotRequested() {
+ return !endRequested();
+ }
+
+ /**
+ * Provide a common accessor to determine if parameters have to be reloaded
+ * <p/> For child threads this means thread execution has to end
+ * </p>
+ * Child processes should only call this method when they are idle (as
+ * opposed to in the middle of executing a unit of work)
+ *
+ * @return boolean - true if it's time to reload parameters
+ */
+ public boolean timeToReload() {
+ return m_bReloadRequested
+ || System.currentTimeMillis() >= m_lNextReload;
+ }
+
+ /**
+ * Helper accessor for child processes that provides info to determine if
+ * they can continue with yet another execution cycle
+ *
+ * @return boolean - true if runtime is not expired and not time yet to
+ * reload parameters
+ */
+ public boolean continueLooping() {
+ return (endNotRequested() && !timeToReload());
+ } // ________________________________
+
+ private static EPRManager getEprManager()
+ {
+ PropertyManager manager = ModulePropertyManager.getPropertyManager(ModulePropertyManager.CORE_MODULE);
+ String sDir = manager.getProperty(Environment.REGISTRY_FILE_HELPER_DIR,".");
+ return EPRManager.getInstance(sDir);
+ }
+
+ public void register (String name, EPR address)
+ {
+ try { getEprManager().saveEPR(name,address); }
+ catch (IOException e)
+ {
+ _logger.fatal("Cannot register service",e);
+ }
+ } // ________________________________
+
+ public void unRegister (String name)
+ {
+ try { getEprManager().removeEPR(name); }
+ catch (IOException e)
+ {
+ _logger.fatal("Cannot un-register service",e);
+ }
+ } // ________________________________
+
+} // ____________________________________________________________________________
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/JmsQueueListener.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/JmsQueueListener.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/JmsQueueListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,232 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.message.listeners;
-
-import javax.jms.JMSException;
-import javax.jms.MessageConsumer;
-import javax.jms.ObjectMessage;
-import javax.jms.Queue;
-import javax.jms.QueueConnection;
-import javax.jms.QueueConnectionFactory;
-import javax.jms.QueueSession;
-import javax.jms.TopicSession;
-import javax.naming.Context;
-
-import org.apache.log4j.Logger;
-
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.helpers.AppServerContext;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.actions.ActionUtils;
-import org.jboss.soa.esb.addressing.helpers.JMSEpr;
-
-/**
- * Esb Message aware JMS queue listener.
- * <p/> Expects an Object message whose getObject() method returns an org.jboss.soa.esb.message.Message
- * <br/>Clones the 'static' ConfigTree with which this listener was created, and stores the cloned tree
- * inside the Message (to enable all actions in the chain to use the configuration)
- * <br/>Instantiates and runs a new ActionProcessingPipeline on the received esb Message (augmented with
- * ConfigTree) that will in turn instantiate and run all action classes in the chain
- *
- * @author <a href="mailto:schifest at heuristica.com.ar">schifest at heuristica.com.ar</a>
- * @since Version 4.0
- */
-
-public class JmsQueueListener implements Runnable
-{
- /**
- * public constructor
- * @param controller EsbListenerController - the controlling process
- * @param config ConfigTree - Containing 'static' configuration for this instance
- * @throws Exception
- */
- public JmsQueueListener(EsbListenerController controller, ConfigTree config)
- throws ConfigurationException
- {
- _controller = controller;
- _config = config;
- _iSleepForRetry = 3;
- checkMyParms();
- } // _______________________________
-
- /**
- * Loops until controlling process determines
- * <br/>Waits for JMS Object messages containing ESB messages
- * <br/>When one is received, instantiates an action processing pipeline to process it
- * <br/>Pipeline is started in new Thread
- */
- public void run()
- {
- _controller.register(_eprName,_epr);
-
- while (_controller.continueLooping())
- {
- org.jboss.soa.esb.message.Message message = receiveEsbMessage(_controller.millisToWait());
- if (null!=message)
- {
- ActionUtils.setConfigTree(message,_config);
- ActionProcessingPipeline chain = null;
-
- try { chain = new ActionProcessingPipeline(message); }
- catch (IllegalArgumentException e)
- { _logger.error(e); continue; }
- catch (ConfigurationException e)
- { _logger.error(e); continue; }
-
- // TODO Take care of thread pooling and (eventually) maximum child threads
- new Thread(chain).start();
- }
- }
-
- _controller.unRegister(_eprName);
- cleanup();
- } // _______________________________
-
- /**
- * Check for mandatory and optional attributes in parameter tree
- *
- * @throws Exception -
- * if mandatory atts are not right or actionClass not in
- * classpath
- */
- protected void checkMyParms() throws ConfigurationException
- {
- // Default value of obtainAttribute is null - Exception will be thrown
- String sQueue = obtainAttribute(JMSEpr.DESTINATION_NAME_TAG, null);
-
- _eprName = obtainAttribute(ListenerTagNames.EPR_IN_NAME,null);
-
- // No problem if selector is null - everything in queue will be returned
- _sSelector = _config.getAttribute(JMSEpr.MESSAGE_SELECTOR_TAG);
-
- _oQconn = null;
- _oQsess = null;
- _oQueue = null;
-
- String sJndiType = obtainAttribute (JMSEpr.JNDI_TYPE_TAG ,"jboss");
- String sJndiURL = obtainAttribute (JMSEpr.JNDI_URL_TAG ,"localhost");
- Context oJndiCtx = AppServerContext.getServerContext(sJndiType,sJndiURL);
-
- String sFactClass = obtainAttribute(JMSEpr.CONNECTION_FACTORY_TAG, "ConnectionFactory");
- _epr = new JMSEpr(JMSEpr.QUEUE_TYPE,sQueue,sFactClass
- ,sJndiType,sJndiURL,_sSelector);
-
- Exception thrown = null;
- try
- {
- Object tmp = oJndiCtx.lookup(sFactClass);
- QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
-
- _oQconn = qcf.createQueueConnection();
- _oQueue = (Queue) oJndiCtx.lookup(sQueue);
- _oQsess = _oQconn.createQueueSession(false,TopicSession.AUTO_ACKNOWLEDGE);
- _oQconn.start();
- _receiver = _oQsess.createReceiver(_oQueue, _sSelector);
- }
- catch (javax.naming.NamingException e) { thrown = e; }
- catch (JMSException e) { thrown = e; }
- throw new ConfigurationException(thrown);
-
- } // ________________________________
-
- protected org.jboss.soa.esb.message.Message receiveEsbMessage(long millis)
- {
- javax.jms.Message jmsMessage = null;
- try { jmsMessage = _receiver.receive(millis); }
- catch (JMSException oJ)
- {
- _logger.error("JMS error on receive. Attempting JMS Destination reconnect.", oJ);
- for (int i1 = 0; i1 < 3; i1++)
- // try to reconnect to the queue
- try { checkMyParms(); }
- catch (Exception e)
- {
- _logger.error("Reconnecting to Queue", e);
- try { Thread.sleep(_iSleepForRetry); }
- catch (InterruptedException e1)
- { // Just return after logging
- _logger.error("Unexpected thread interupt exception.", e);
- return null;
- }
- }
- }
- if (null == jmsMessage)
- return null;
-
- if (!(jmsMessage instanceof ObjectMessage))
- {
- _logger.error("Unsupported JMS message type: " + jmsMessage.getClass().getName());
- return null;
- }
- try
- {
- return (org.jboss.soa.esb.message.Message)((ObjectMessage)jmsMessage).getObject();
- }
- catch (JMSException e1)
- { _logger.error("Failed to read Serialized Object from JMS message.", e1);
- return null;
- }
- catch (ClassCastException e2)
- { _logger.error("Object in JMS message is not a org.jboss.soa.esb.message.Message", e2);
- }
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.jboss.soa.esb.listeners.AbstractListener#close()
- */
-
- protected void cleanup()
- {
- if (null != _oQsess)
- try { _oQsess.close(); }
- catch (Exception e1) {/* Tried my best - Just continue */ }
- if (null != _oQconn)
- try { _oQconn.close(); }
- catch (Exception e2) {/* Tried my best - Just continue */ }
- }
-
- protected String obtainAttribute(String p_sAtt, String p_sDefault)
- throws ConfigurationException
- {
- String sVal = _config.getAttribute(p_sAtt);
- if ((null == sVal) && (null == p_sDefault))
- throw new ConfigurationException("Missing or invalid <" + p_sAtt + "> attribute");
-
- return (null != sVal) ? sVal : p_sDefault;
- } // ________________________________
-
- protected EsbListenerController _controller;
- protected ConfigTree _config;
- protected String _eprName;
- protected JMSEpr _epr;
- protected MessageConsumer _receiver;
- protected boolean _bError = false;
- protected QueueConnection _oQconn;
- protected QueueSession _oQsess;
- protected Queue _oQueue;
- protected String _sSelector;
- protected int _iSleepForRetry;
-
- protected static transient Logger _logger = Logger.getLogger(JmsQueueListener.class);
-}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/JmsQueueListener.java (from rev 6961, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/JmsQueueListener.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/JmsQueueListener.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/JmsQueueListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,233 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.soa.esb.listeners.message;
+
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueSession;
+import javax.jms.TopicSession;
+import javax.naming.Context;
+
+import org.apache.log4j.Logger;
+
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.helpers.AppServerContext;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+import org.jboss.soa.esb.actions.ActionUtils;
+import org.jboss.soa.esb.addressing.helpers.JMSEpr;
+
+/**
+ * Esb Message aware JMS queue listener.
+ * <p/> Expects an Object message whose getObject() method returns an org.jboss.soa.esb.message.Message
+ * <br/>Clones the 'static' ConfigTree with which this listener was created, and stores the cloned tree
+ * inside the Message (to enable all actions in the chain to use the configuration)
+ * <br/>Instantiates and runs a new ActionProcessingPipeline on the received esb Message (augmented with
+ * ConfigTree) that will in turn instantiate and run all action classes in the chain
+ *
+ * @author <a href="mailto:schifest at heuristica.com.ar">schifest at heuristica.com.ar</a>
+ * @since Version 4.0
+ */
+
+public class JmsQueueListener implements Runnable
+{
+ /**
+ * public constructor
+ * @param controller EsbListenerController - the controlling process
+ * @param config ConfigTree - Containing 'static' configuration for this instance
+ * @throws Exception
+ */
+ public JmsQueueListener(EsbListenerController controller, ConfigTree config)
+ throws ConfigurationException
+ {
+ _controller = controller;
+ _config = config;
+ _iSleepForRetry = 3;
+ checkMyParms();
+ } // _______________________________
+
+ /**
+ * Loops until controlling process determines
+ * <br/>Waits for JMS Object messages containing ESB messages
+ * <br/>When one is received, instantiates an action processing pipeline to process it
+ * <br/>Pipeline is started in new Thread
+ */
+ public void run()
+ {
+ _controller.register(_eprName,_epr);
+
+ while (_controller.continueLooping())
+ {
+ org.jboss.soa.esb.message.Message message = receiveEsbMessage(_controller.millisToWait());
+ if (null!=message)
+ {
+ ActionUtils.setConfigTree(message,_config);
+ ActionProcessingPipeline chain = null;
+
+ try { chain = new ActionProcessingPipeline(message); }
+ catch (IllegalArgumentException e)
+ { _logger.error(e); continue; }
+ catch (ConfigurationException e)
+ { _logger.error(e); continue; }
+
+ // TODO Take care of thread pooling and (eventually) maximum child threads
+ new Thread(chain).start();
+ }
+ }
+
+ _controller.unRegister(_eprName);
+ cleanup();
+ } // _______________________________
+
+ /**
+ * Check for mandatory and optional attributes in parameter tree
+ *
+ * @throws Exception -
+ * if mandatory atts are not right or actionClass not in
+ * classpath
+ */
+ protected void checkMyParms() throws ConfigurationException
+ {
+ // Default value of obtainAttribute is null - Exception will be thrown
+ String sQueue = obtainAttribute(JMSEpr.DESTINATION_NAME_TAG, null);
+
+ _eprName = obtainAttribute(ListenerTagNames.SERVICE_NAME_TAG,null);
+
+ // No problem if selector is null - everything in queue will be returned
+ _sSelector = _config.getAttribute(JMSEpr.MESSAGE_SELECTOR_TAG);
+
+ _oQconn = null;
+ _oQsess = null;
+ _oQueue = null;
+
+ String sJndiType = obtainAttribute (JMSEpr.JNDI_TYPE_TAG ,"jboss");
+ String sJndiURL = obtainAttribute (JMSEpr.JNDI_URL_TAG ,"localhost");
+ Context oJndiCtx = AppServerContext.getServerContext(sJndiType,sJndiURL);
+
+ String sFactClass = obtainAttribute(JMSEpr.CONNECTION_FACTORY_TAG, "ConnectionFactory");
+ _epr = new JMSEpr(JMSEpr.QUEUE_TYPE,sQueue,sFactClass
+ ,sJndiType,sJndiURL,_sSelector);
+
+ Exception thrown = null;
+ try
+ {
+ Object tmp = oJndiCtx.lookup(sFactClass);
+ QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
+
+ _oQconn = qcf.createQueueConnection();
+ _oQueue = (Queue) oJndiCtx.lookup(sQueue);
+ _oQsess = _oQconn.createQueueSession(false,TopicSession.AUTO_ACKNOWLEDGE);
+ _oQconn.start();
+ _receiver = _oQsess.createReceiver(_oQueue, _sSelector);
+ }
+ catch (javax.naming.NamingException e) { thrown = e; }
+ catch (JMSException e) { thrown = e; }
+ throw new ConfigurationException(thrown);
+
+ } // ________________________________
+
+ protected org.jboss.soa.esb.message.Message receiveEsbMessage(long millis)
+ {
+ javax.jms.Message jmsMessage = null;
+ try { jmsMessage = _receiver.receive(millis); }
+ catch (JMSException oJ)
+ {
+ _logger.error("JMS error on receive. Attempting JMS Destination reconnect.", oJ);
+ for (int i1 = 0; i1 < 3; i1++)
+ // try to reconnect to the queue
+ try { checkMyParms(); }
+ catch (Exception e)
+ {
+ _logger.error("Reconnecting to Queue", e);
+ try { Thread.sleep(_iSleepForRetry); }
+ catch (InterruptedException e1)
+ { // Just return after logging
+ _logger.error("Unexpected thread interupt exception.", e);
+ return null;
+ }
+ }
+ }
+ if (null == jmsMessage)
+ return null;
+
+ if (!(jmsMessage instanceof ObjectMessage))
+ {
+ _logger.error("Unsupported JMS message type: " + jmsMessage.getClass().getName());
+ return null;
+ }
+ try
+ {
+ return (org.jboss.soa.esb.message.Message)((ObjectMessage)jmsMessage).getObject();
+ }
+ catch (JMSException e1)
+ { _logger.error("Failed to read Serialized Object from JMS message.", e1);
+ return null;
+ }
+ catch (ClassCastException e2)
+ { _logger.error("Object in JMS message is not a org.jboss.soa.esb.message.Message", e2);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#close()
+ */
+
+ protected void cleanup()
+ {
+ if (null != _oQsess)
+ try { _oQsess.close(); }
+ catch (Exception e1) {/* Tried my best - Just continue */ }
+ if (null != _oQconn)
+ try { _oQconn.close(); }
+ catch (Exception e2) {/* Tried my best - Just continue */ }
+ }
+
+ protected String obtainAttribute(String p_sAtt, String p_sDefault)
+ throws ConfigurationException
+ {
+ String sVal = _config.getAttribute(p_sAtt);
+ if ((null == sVal) && (null == p_sDefault))
+ throw new ConfigurationException("Missing or invalid <" + p_sAtt + "> attribute");
+
+ return (null != sVal) ? sVal : p_sDefault;
+ } // ________________________________
+
+ protected EsbListenerController _controller;
+ protected ConfigTree _config;
+ protected String _eprName;
+ protected JMSEpr _epr;
+ protected MessageConsumer _receiver;
+ protected boolean _bError = false;
+ protected QueueConnection _oQconn;
+ protected QueueSession _oQsess;
+ protected Queue _oQueue;
+ protected String _sSelector;
+ protected int _iSleepForRetry;
+
+ protected static transient Logger _logger = Logger.getLogger(JmsQueueListener.class);
+}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ListenerTagNames.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/ListenerTagNames.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ListenerTagNames.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,13 +0,0 @@
-package org.jboss.soa.esb.message.listeners;
-
-public class ListenerTagNames
-{
- public static final String EPR_IN_NAME = "epr-in-name";
- public static final String EPR_OUT_NAME = "epr-out-name";
-
- public static final String ACTION_ELEMENT = "action";
- public static final String ACTION_CLASS_ATTRIBUTE = "class";
- public static final String ACTION_PROCESS_METHOD = "process";
- public static final String ACTION_NORMAL_COMPLETION_CALLBACK = "okMethod";
- public static final String ACTION_EXCEPTION_CALLBACK= "exceptionMethod";
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/MockAction.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/MockAction.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/MockAction.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,137 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.soa.esb.message.listeners;
-
-import java.text.*;
-
-import org.apache.log4j.Logger;
-import org.jboss.soa.esb.actions.ActionUtils;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.helpers.*;
-import org.jboss.soa.esb.notification.*;
-
-
-/**
- * Use this class to tune your XML configurations <p/>Once your config works
- * with this dummy class, you can switch to your own action class <p/>You will
- * have to implement these three methods in your own action class
- *
- * @author Esteban
- *
- */
-public class MockAction
-{
- protected Message _message;
- protected ConfigTree _config;
-
- public MockAction(ConfigTree config) { _config = config; }
- public Message noOperation(Message message) { return message; }
-
- public Message process(Message message)
- {
- _message = message;
- Object oCurr = ActionUtils.getTaskObject(message);
- if (null==oCurr)
- oCurr = "null";
- _logger.info(getStamp()+" process was called with <<" + oCurr.toString() + ">>");
- return message;
- } // ________________________________
-
-
- public Message process222(Message message)
- {
- _message = message;
- Object oCurr = ActionUtils.getTaskObject(message);
- if (null==oCurr)
- oCurr = "null";
- _logger.info(getStamp()+" process222 was called with <<" + oCurr.toString() + ">>");
- return message;
- } // ________________________________
-
- private static final SimpleDateFormat s_oTS
- = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS");
-
- private String getStamp()
- { return s_oTS.format(new java.util.Date(System.currentTimeMillis())); }
-
- private static Logger _logger = Logger.getLogger(MockAction.class);
-
- public void myOkMethod1()
- {
- String sMsg = new StringBuilder(getStamp())
- .append(" MockAction.myOkMethod1 was called ")
- .append(_message)
- .toString();
- _logger.info(sMsg);
- @SuppressWarnings("unused")
- NotificationList nl = ActionUtils.getNotifyList(_config,"ok");
- // Here you can send notifications to everybody
- }
-
- public void myMethod2()
- {
- String sMsg = new StringBuilder(getStamp())
- .append(" Method2 Method2 Method2 Method2 Method2 CALLED ")
- .append(_message)
- .toString();
- _logger.info(sMsg);
- @SuppressWarnings("unused")
- NotificationList nl = ActionUtils.getNotifyList(_config,"ok");
- // Here you can send notifications to everybody
- }
-
- public void endOfChainNotification()
- {
- String sMsg = new StringBuilder(getStamp())
- .append(" End of action chain reached - Bye bye")
- .toString();
- _logger.info(sMsg);
- @SuppressWarnings("unused")
- NotificationList nl = ActionUtils.getNotifyList(_config,"ok");
- // Here you can send notifications to everybody
- }
-
- public Message justThrow(Message message) throws Exception
- {
- throw new MockException("Mock exception thrown at "+getStamp());
- } // ________________________________
-
- @SuppressWarnings("serial")
- private class MockException extends Exception
- {
- MockException(String str) { super(str); }
- }
-
- public void exceptionCallback1(Exception e)
- {
- String sMsg = new StringBuilder(getStamp())
- .append(" MockExceptionTrower.exceptionCallback1 CALLED ")
- .append(_message)
- .toString();
- _logger.fatal(sMsg,e);
- @SuppressWarnings("unused")
- NotificationList nl = ActionUtils.getNotifyList(_config,"err");
- // Here you can send notifications to everybody
- }
-
-} // ____________________________________________________________________________
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/MockAction.java (from rev 6961, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/MockAction.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/MockAction.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/MockAction.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,137 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.soa.esb.listeners.message;
+
+import java.text.*;
+
+import org.apache.log4j.Logger;
+import org.jboss.soa.esb.actions.ActionUtils;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.helpers.*;
+import org.jboss.soa.esb.notification.*;
+
+
+/**
+ * Use this class to tune your XML configurations <p/>Once your config works
+ * with this dummy class, you can switch to your own action class <p/>You will
+ * have to implement these three methods in your own action class
+ *
+ * @author Esteban
+ *
+ */
+public class MockAction
+{
+ protected Message _message;
+ protected ConfigTree _config;
+
+ public MockAction(ConfigTree config) { _config = config; }
+ public Message noOperation(Message message) { return message; }
+
+ public Message process(Message message)
+ {
+ _message = message;
+ Object oCurr = ActionUtils.getTaskObject(message);
+ if (null==oCurr)
+ oCurr = "null";
+ _logger.info(getStamp()+" process was called with <<" + oCurr.toString() + ">>");
+ return message;
+ } // ________________________________
+
+
+ public Message process222(Message message)
+ {
+ _message = message;
+ Object oCurr = ActionUtils.getTaskObject(message);
+ if (null==oCurr)
+ oCurr = "null";
+ _logger.info(getStamp()+" process222 was called with <<" + oCurr.toString() + ">>");
+ return message;
+ } // ________________________________
+
+ private static final SimpleDateFormat s_oTS
+ = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS");
+
+ private String getStamp()
+ { return s_oTS.format(new java.util.Date(System.currentTimeMillis())); }
+
+ private static Logger _logger = Logger.getLogger(MockAction.class);
+
+ public void myOkMethod1()
+ {
+ String sMsg = new StringBuilder(getStamp())
+ .append(" MockAction.myOkMethod1 was called ")
+ .append(_message)
+ .toString();
+ _logger.info(sMsg);
+ @SuppressWarnings("unused")
+ NotificationList nl = ActionUtils.getNotifyList(_config,"ok");
+ // Here you can send notifications to everybody
+ }
+
+ public void myMethod2()
+ {
+ String sMsg = new StringBuilder(getStamp())
+ .append(" Method2 Method2 Method2 Method2 Method2 CALLED ")
+ .append(_message)
+ .toString();
+ _logger.info(sMsg);
+ @SuppressWarnings("unused")
+ NotificationList nl = ActionUtils.getNotifyList(_config,"ok");
+ // Here you can send notifications to everybody
+ }
+
+ public void endOfChainNotification()
+ {
+ String sMsg = new StringBuilder(getStamp())
+ .append(" End of action chain reached - Bye bye")
+ .toString();
+ _logger.info(sMsg);
+ @SuppressWarnings("unused")
+ NotificationList nl = ActionUtils.getNotifyList(_config,"ok");
+ // Here you can send notifications to everybody
+ }
+
+ public Message justThrow(Message message) throws Exception
+ {
+ throw new MockException("Mock exception thrown at "+getStamp());
+ } // ________________________________
+
+ @SuppressWarnings("serial")
+ private class MockException extends Exception
+ {
+ MockException(String str) { super(str); }
+ }
+
+ public void exceptionCallback1(Exception e)
+ {
+ String sMsg = new StringBuilder(getStamp())
+ .append(" MockExceptionTrower.exceptionCallback1 CALLED ")
+ .append(_message)
+ .toString();
+ _logger.fatal(sMsg,e);
+ @SuppressWarnings("unused")
+ NotificationList nl = ActionUtils.getNotifyList(_config,"err");
+ // Here you can send notifications to everybody
+ }
+
+} // ____________________________________________________________________________
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/easier2ReadExample.xml
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/easier2ReadExample.xml 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/easier2ReadExample.xml 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,36 +0,0 @@
-<EsbListenerControllerExample
- parameterReloadSecs="180"
->
- <ListenJmsQueueExample
- epr-name="myEprMnemonicName"
- listenerClass="org.jboss.soa.esb.message.listeners.JmsQueueListener"
- connection-factory="ConnectionFactory"
- destination-type="queue"
- destination-name="queue/A"
- jndi-type="jboss"
- jndi-URL="localhost"
- message-selector="service='handOfGod'"
- >
- <action class="org.jboss.soa.esb.message.listeners.MockAction" />
- <action class="org.jboss.soa.esb.message.listeners.MockAction" process="process222" />
- <action class="org.jboss.soa.esb.message.listeners.MockAction"
- process="noOperation" okMethod="endOfChainNotification"/>
-
- <NotificationList type="OK">
- <target class="NotifyFiles">
- <file URI="file:///E:/tmp/jbossEsb/notifyDir/GpListenerExample.notifOK"
- append="true"
- />
- </target>
- </NotificationList>
-
- <NotificationList type="err">
- <target class="NotifyFiles">
- <file URI="file:///E:/tmp/jbossEsb/notifyDir/GpListenerExample.notifErr"
- append="true"
- />
- </target>
- </NotificationList>
- </ListenJmsQueueExample>
-
-</EsbListenerControllerExample>
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/easier2ReadExample.xml (from rev 6961, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/easier2ReadExample.xml)
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/example.xml
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/example.xml 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/example.xml 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,44 +0,0 @@
-<EsbListenerControllerExample
- parameterReloadSecs="180"
->
- <ListenJmsQueueExample
- epr-name="myEprMnemonicName"
- listenerClass="org.jboss.soa.esb.message.listeners.JmsQueueListener"
- connection-factory="ConnectionFactory"
- destination-type="queue"
- destination-name="queue/A"
- jndi-type="jboss"
- jndi-URL="localhost"
- message-selector="service='maradona'"
- >
- <!-- next line will call (default) process(Message) method with no notification for step -->
- <action class="org.jboss.soa.esb.message.listeners.MockAction" />
- <!-- next line will call process222(Message) method with no notification for step -->
- <action class="org.jboss.soa.esb.message.listeners.MockAction" process="process222" />
- <!-- next line will call (default) process(Message) - on success=>invoke myOkMethod1 -->
- <action class="org.jboss.soa.esb.message.listeners.MockAction" okMethod="myOkMethod1" />
- <action class="org.jboss.soa.esb.message.listeners.MockAction" process="process222"
- okMethod="myMethod2" />
- <!-- next line would be useful to notify end of action chain process=noOperation (see class)-->
- <action class="org.jboss.soa.esb.message.listeners.MockAction" process="noOperation" />
- <!-- example of a method that will always throw an Exception -->
- <action class="org.jboss.soa.esb.message.listeners.MockAction" process="justThrow" exceptionMethod="exceptionCallback1"/>
-
- <NotificationList type="OK">
- <target class="NotifyFiles">
- <file URI="file:///E:/tmp/jbossEsb/notifyDir/GpListenerExample.notifOK"
- append="true"
- />
- </target>
- </NotificationList>
-
- <NotificationList type="err">
- <target class="NotifyFiles">
- <file URI="file:///E:/tmp/jbossEsb/notifyDir/GpListenerExample.notifErr"
- append="true"
- />
- </target>
- </NotificationList>
- </ListenJmsQueueExample>
-
-</EsbListenerControllerExample>
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/example.xml (from rev 6961, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/message/listeners/example.xml)
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/AbstractListener.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractListener.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractListener.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/AbstractListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,293 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.soa.esb.listeners.old;
+
+import java.util.Arrays;
+
+import org.apache.log4j.Logger;
+import org.jboss.soa.esb.actions.ActionDefinition;
+import org.jboss.soa.esb.actions.ActionDefinitionFactory;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.actions.ActionProcessor;
+import org.jboss.soa.esb.actions.ActionUtils;
+import org.jboss.soa.esb.helpers.DomElement;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+
+/**
+ * Base abstract listener implementation.
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ * @since Version 4.0
+ */
+public abstract class AbstractListener implements Runnable {
+
+ /**
+ * Name constant def for the Message attachemnt carrying the list of actions to be applied to the
+ * incomming message. This allows the configured processing pipeline to be overridden by the Message
+ * producer.
+ */
+ public static final String MESSAGE_PROCESSING_ACTIONS_LIST = "MESSAGE_PROCESSING_ACTIONS_LIST";
+
+ // You can override these values at constructor time of your
+ // derived class after calling super(GpListener,DomElement)
+ protected int m_iSleepForThreads = 3000; // default sleep if no threads available
+ protected int m_iUpperThreadLimit = 10; // just in case - override if you wish
+
+ protected int m_iQthr = 0, m_iMaxThr;
+
+ protected ThreadGroup m_oThrGrp = null;
+ protected Logger logger;
+ protected GpListener m_oDad;
+ protected DomElement listenerConfig;
+ protected String[] m_oActions;
+ protected ActionDefinitionFactory m_oActionDefinitionFactory;
+ protected MessageFactory m_oMsgFactory;
+
+ protected AbstractListener(GpListener p_oDad, DomElement p_oParms, ActionDefinitionFactory actionDefinitionFactory) throws Exception {
+
+ logger = Logger.getLogger(this.getClass());
+ m_oDad = p_oDad;
+ listenerConfig = p_oParms.cloneObj();
+ m_oActionDefinitionFactory = actionDefinitionFactory;
+ m_oMsgFactory = MessageFactory.getInstance();
+ m_oThrGrp = new ThreadGroup(listenerConfig.getName());
+
+ String sAtt = GpListener.obtainAtt(listenerConfig, GpListener.PARM_ACTIONS, "");
+ if(!sAtt.trim().equals("")) {
+ m_oActions = sAtt.split(",");
+ }
+
+ sAtt = GpListener.obtainAtt(listenerConfig, GpListener.PARM_MAX_THREADS, "1");
+ int iMax = Integer.parseInt(sAtt);
+ m_iMaxThr = Math.min(iMax, m_iUpperThreadLimit);
+ } // __________________________________
+
+ /**
+ * Implement run method for this Runnable <p/> Will continue to run until
+ * controlling class (ref in m_oDad) indicates no more looping allowed for
+ * all child classes <p/> This condition will not prevent child processes to
+ * finish normally
+ */
+ public void run() {
+ while (m_oDad.continueLooping()) {
+ Object[] processList = receive();
+ if (null==processList) {
+ try { Thread.sleep(500); }
+ catch(InterruptedException e) {/* ok do nothing */}
+ } else {
+ for (Object currentObj : processList) {
+ if (m_iQthr >= m_iMaxThr) {
+ logger.info("Waiting for available threads...(max=" + m_iMaxThr + ")");
+ try {
+ Thread.sleep(m_iSleepForThreads);
+ } catch (InterruptedException e) {
+ return;
+ }
+ break;
+ }
+
+ // Spawn a thread and push the message message through the pipeline...
+ ActionProcessingPipeline runner = new ActionProcessingPipeline(currentObj);
+ new Thread(runner).start();
+ incThreads();
+ }
+ }
+ }
+
+ // Wait for all the processing pipelines to complete before closing the listener and existing...
+ while(m_iQthr > 0) {
+ logger.info("Waiting for all processing pipelines to complete.");
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ logger.warn("Thread interrupted while waiting for all processing pipelines to complete.", e);
+ }
+ }
+
+ logger.info("All processing pipelines complete. Closing listener now.");
+
+ close();
+ }
+
+ /**
+ * Receive message from underlying channel implementation.
+ * <p/>
+ * Implementations must perform a blocking receive.
+ * @return An array of Objects received on the channel.
+ */
+ protected abstract Object[] receive();
+
+ /**
+ * Called on the listener implementation when pipeline processing error has occured.
+ * @param initialMsg The message that was initialy supplied to the pipeline.
+ * @param processor The processor that raised the error. Can be null where the error was raised before
+ * pipeline processing of the message.
+ * @param error The error. Can be null.
+ */
+ protected abstract void processingError(Object initialMsg, ActionProcessor processor, Throwable error);
+
+ /**
+ * Called on the listener implementation when pipeline processing of a message is complete.
+ * @param initialMsg The message that was initialy supplied to the pipeline.
+ */
+ protected abstract void processingComplete(Object initialMsg);
+
+ /**
+ * Close the listener implemenation.
+ * <p/>
+ * Allows the listener to perform relevant close/cleanup tasks.
+ */
+ protected abstract void close();
+
+ /**
+ * Increment the active thread count.
+ */
+ private void incThreads() {
+ m_iQthr++;
+ }
+
+ /**
+ * Decrement the active thread count.
+ */
+ private void decThreads() {
+ m_iQthr--;
+ }
+
+ /**
+ * Action Processing Pipeline.
+ * <p/>
+ * Runs the actions in a listeners "actions" config on a message payload message received
+ * by the listener implementation.
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ * @since Version 4.0
+ */
+ private class ActionProcessingPipeline implements Runnable {
+
+ private Object initialObject;
+
+ /**
+ * Private constructor.
+ * @param pMessage The inital processing target message.
+ */
+ private ActionProcessingPipeline(Object obj) {
+ initialObject = obj;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ String currentAction = null;
+ ActionProcessor currentProcessor = null;
+
+ try {
+ Message message;
+ String[] actions;
+
+ if(initialObject instanceof Message) {
+ message = (Message)initialObject;
+ } else {
+ message = m_oMsgFactory.getMessage();
+ ActionUtils.setTaskObject(message,initialObject);
+ }
+
+ actions = getActions(message);
+
+ // Run the message through each ActionProcessor...
+ for(String action : actions) {
+ ActionDefinition actionDefinition;
+
+ currentAction = action.trim();
+ actionDefinition = m_oActionDefinitionFactory.getInstance(currentAction);
+ if(actionDefinition == null) {
+ throw new java.lang.IllegalStateException("Bad Listener Configuration. No 'Actions/Action' definition for action [" + currentAction + "].");
+ }
+
+ // The processing result of each action feeds into the processing of the next action...
+ currentProcessor = actionDefinition.getProcessor();
+ try {
+ ActionUtils.copyCurrentToPrevious(message);
+ message = currentProcessor.process(message);
+ } catch (Exception e) {
+ GpListener.notifyError(listenerConfig, e, currentProcessor.getErrorNotification(message));
+ throw e;
+ }
+
+ if(message == null && action != m_oActions[m_oActions.length - 1]) {
+ String exceptionMessage = "Premature termination of action processing pipeline [" + Arrays.asList(m_oActions) + "]. ActionProcessor [" + currentProcessor.getClass().getName() + "] returned a null message result on processing of action [" + currentAction + "].";
+ processingError(initialObject, currentProcessor, new ActionProcessingException(exceptionMessage));
+ logger.warn(exceptionMessage);
+ return;
+ }
+ // Notify on all processors. May want to do this differently in the future i.e. more selectively ...
+ GpListener.notifyOK(listenerConfig, currentProcessor.getOkNotification(message));
+
+ // Setup the message for processing by the next processor...
+ if(message != null) {
+ message.getBody().remove(ActionUtils.BEFORE_ACTION);
+ }
+ }
+
+ processingComplete(initialObject);
+ } catch(Throwable thrown) {
+ processingError(initialObject, currentProcessor, thrown);
+ logger.error("Premature termination of action processing pipeline [" + (m_oActions != null?Arrays.asList(m_oActions):"") + "]. Action [" + currentAction + "] threw an exception.", thrown);
+ } finally {
+ // Decrement the active thread count for the listener on completion...
+ decThreads();
+ }
+ }
+
+ /**
+ * Get the list of actions to be applied to the supplied message.
+ * @param message The message to be processed.
+ * @return The set of processing actions to be performed on the message.
+ * @throws ActionProcessingException Invalid actions list attachment setting.
+ */
+ private String[] getActions(Message message) throws ActionProcessingException {
+ // Check is there an attachment specifying an override pipeline config...
+ Object overrideActionsAttachment = message.getAttachment().get(MESSAGE_PROCESSING_ACTIONS_LIST);
+ if(overrideActionsAttachment != null) {
+ if(overrideActionsAttachment instanceof String) {
+ String overrideActions = (String)overrideActionsAttachment;
+
+ if(overrideActions.trim().equals("")) {
+ throw new ActionProcessingException("Message attachement [" + MESSAGE_PROCESSING_ACTIONS_LIST + "] was specified but with an empty value. Aborting message processing.");
+ }
+
+ return overrideActions.split(",");
+ } else {
+ throw new ActionProcessingException("Message attachement [" + MESSAGE_PROCESSING_ACTIONS_LIST + "] must be of type java.lang.String. Received [" + overrideActionsAttachment.getClass().getName() + "]. Aborting message processing.");
+ }
+ } else {
+ // Otherwise use the actions configured on the listener...
+ if(m_oActions == null || m_oActions.length == 0) {
+ throw new ActionProcessingException("No actions configuration specified either on the listener or as a Message attachement [" + MESSAGE_PROCESSING_ACTIONS_LIST + "]. Aborting message processing.");
+ }
+ return m_oActions;
+ }
+ }
+ }
+
+} // ____________________________________________________________________________
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/AbstractPoller.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractPoller.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/AbstractPoller.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/AbstractPoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.soa.esb.listeners.old;
+
+import java.util.List;
+
+import org.jboss.soa.esb.actions.ActionDefinitionFactory;
+import org.jboss.soa.esb.helpers.DomElement;
+
+/**
+ * Abstract Polling Listener.
+ * <p/>
+ * Polling listeners are listener implementations that periodically poll for message objects
+ * that require processing. This type of listener implementation is required where the underlying
+ * message channel doesn't support a blocking receive operation.
+ *
+ * @author Esteban
+ */
+public abstract class AbstractPoller extends AbstractListener {
+
+ // You can override these values at constructor time of your
+ // derived class after calling super(GpListener,DomElement)
+ protected int m_iMinPollMillis = 3000 // minimum polling interval
+ , m_iDfltPollMillis = 20000 // default polling interval
+ ;
+
+ public static final String PARM_POLL_LTCY = "pollLatencySecs";
+
+ protected int m_iPollMillis;
+
+ /**
+ * Construct an abstract polling listener.
+ * @param commandListener The command listener.
+ * @param listenerConfig The configuration for this polling listener.
+ * @param actionDefinitionFactory The action definition factory for the bus.
+ * @throws Exception
+ */
+ protected AbstractPoller(GpListener commandListener, DomElement listenerConfig, ActionDefinitionFactory actionDefinitionFactory) throws Exception {
+ super(commandListener, listenerConfig, actionDefinitionFactory);
+
+ String sAtt = listenerConfig.getAttr(PARM_POLL_LTCY);
+ m_iPollMillis = (null == sAtt) ? m_iDfltPollMillis : 1000 * Integer.parseInt(sAtt);
+ if (m_iPollMillis < m_iMinPollMillis) {
+ m_iPollMillis = m_iMinPollMillis;
+ }
+ }
+
+ /**
+ * Polling listener receive implementation.
+ * @return An array of objects polled from the concrete Poller implementation.
+ */
+ protected Object[] receive() {
+ while (m_oDad.continueLooping()) {
+ List<Object> olPending = pollForCandidates();
+
+ if (olPending == null || olPending.isEmpty()) {
+ try {
+ Thread.sleep(m_iPollMillis);
+ } catch (InterruptedException e) {
+ logger.error("Unexpected thread interupt exception. Not terminating blocking receive!!", e);
+ }
+ continue;
+ } else {
+ Object[] objForProcessing = new Object[olPending.size()];
+
+ // Preprocess all the message objects.
+ // TODO: I really think this is no longer required or a good idea!!
+ for(int i = 0; i < olPending.size(); i++) {
+ objForProcessing[i] = preProcess(olPending.get(i));
+ }
+ return objForProcessing;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Poll for message objects.
+ * @return A list of message objects, or an empty list if there are no message objects.
+ */
+ protected abstract List<Object> pollForCandidates();
+
+ /**
+ * Preprocess the message object before returning for pipeline processing.
+ * @param message Message object for preprocessing.
+ * @return The preprocessed message object, or the supplied message unmodified.
+ */
+ protected abstract Object preProcess(Object message);
+ // TODO: Is this "preprocessing" step needed now that we have processing pipelines on listeners???
+}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/DirectoryPoller.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/DirectoryPoller.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/DirectoryPoller.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/DirectoryPoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,263 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY 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 along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+
+package org.jboss.soa.esb.listeners.old;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import org.jboss.soa.esb.actions.ActionDefinitionFactory;
+import org.jboss.soa.esb.actions.ActionProcessor;
+import org.jboss.soa.esb.helpers.DomElement;
+import org.jboss.soa.esb.util.Util;
+
+public class DirectoryPoller extends AbstractPoller
+{
+ public static final String FILE_INPUT_DIR = "inputDirURI";
+ public static final String FILE_INPUT_SFX = "inputSuffix";
+ public static final String FILE_WORK_SFX = "workSuffix";
+ public static final String FILE_ERROR_DIR = "errorDirURI";
+ public static final String FILE_ERROR_SFX = "errorSuffix";
+ public static final String FILE_POST_DIR = "postDirURI";
+ public static final String FILE_POST_SFX = "postSuffix";
+ public static final String FILE_POST_DEL = "postDelete";
+
+ public DirectoryPoller(GpListener p_oDad, DomElement p_oParms, ActionDefinitionFactory actionDefinitionFactory) throws Exception
+ {
+ super(p_oDad, p_oParms, actionDefinitionFactory);
+ checkMyParms();
+ } //__________________________________
+
+
+ protected File m_oInpDir ,m_oErrorDir ,m_oPostDir;
+ protected FileFilter m_oFFilt;
+ protected String m_sInpSfx ,m_sWrkSfx ,m_sErrSfx ,m_sPostSfx;
+ protected boolean m_bPostDel;
+
+ /**
+ *
+ * @param inputObject Object - Must be a File representing the file that has to be processed
+ * @return Object - an array of 3 Files containing:
+ * <p/>[0] renamed file (workSuffix appended to input file name)
+ * <p/>[1] target file name in case actionClass is unable to complete successfuly
+ * <p/>[2] target file name in case actionClass finishes successfuly
+ */
+ @Override
+ public Object preProcess(Object inputObject)
+ {
+ if (!(inputObject instanceof File)) {
+ return null;
+ }
+
+ File inputFile = (File)inputObject;
+ WorkingFile workingFile = new WorkingFile(inputFile.getParentFile(), inputFile.getName() + m_sWrkSfx);
+
+ if (!inputFile.renameTo(workingFile)) {
+ return null;
+ }
+
+ workingFile.postDelete = m_bPostDel;
+ workingFile.inputFile = inputFile;
+ workingFile.errorFile = new File (m_oErrorDir ,inputFile.getName()+m_sErrSfx);
+ workingFile.outputFile = new File (m_oPostDir ,inputFile.getName()+m_sPostSfx);
+
+ return workingFile;
+ } //________________________________
+
+ @Override
+ protected List<Object> pollForCandidates()
+ {
+ File[] oaF = m_oInpDir.listFiles(m_oFFilt);
+ return Arrays.asList((Object[])oaF);
+ } //________________________________
+
+ private void checkMyParms() throws Exception
+ {
+ // INPUT directory and suffix (used for FileFilter)
+ String sInpDir = GpListener.obtainAtt(listenerConfig,FILE_INPUT_DIR,null);
+ m_oInpDir = getFile(sInpDir);
+ seeIfOkToWorkOnDir(m_oInpDir);
+
+ m_sInpSfx = GpListener.obtainAtt(listenerConfig,FILE_INPUT_SFX,null);
+ m_sInpSfx = m_sInpSfx.trim();
+ if (m_sInpSfx.length()<1)
+ throw new Exception ("Invalid "+FILE_INPUT_SFX+" attribute");
+ m_oFFilt = new FileEndsWith(m_sInpSfx);
+
+ // WORK suffix (will rename in input directory)
+ m_sWrkSfx = GpListener.obtainAtt(listenerConfig,FILE_WORK_SFX,".esbWork").trim();
+ if (m_sWrkSfx.length()<1)
+ throw new Exception ("Invalid "+FILE_WORK_SFX+" attribute");
+ if (m_sInpSfx.equals(m_sWrkSfx))
+ throw new Exception("Work suffix must differ from input suffix <"+m_sWrkSfx+">");
+
+ // ERROR directory and suffix (defaults to input dir and ".esbError" suffix)
+ String sErrDir = GpListener.obtainAtt(listenerConfig,FILE_ERROR_DIR,sInpDir);
+ m_oErrorDir = getFile(sErrDir);
+ seeIfOkToWorkOnDir(m_oErrorDir);
+
+ m_sErrSfx = GpListener.obtainAtt(listenerConfig,FILE_ERROR_SFX,".esbError").trim();
+ if (m_sErrSfx.length()<1)
+ throw new Exception ("Invalid "+FILE_ERROR_SFX+" attribute");
+ if (m_oErrorDir.equals(m_oInpDir) && m_sInpSfx.equals(m_sErrSfx))
+ throw new Exception("Error suffix must differ from input suffix <"+m_sErrSfx+">");
+
+
+ // Do users wish to delete files that were processed OK ?
+ String sPostDel = GpListener.obtainAtt(listenerConfig,FILE_POST_DEL,"false").trim();
+ m_bPostDel = Boolean.parseBoolean(sPostDel);
+ if (m_bPostDel)
+ return;
+
+ // POST (done) directory and suffix (defaults to input dir and ".esbDone" suffix)
+ String sPostDir = GpListener.obtainAtt(listenerConfig,FILE_POST_DIR,sInpDir);
+ m_oPostDir = getFile(sPostDir);
+ seeIfOkToWorkOnDir(m_oPostDir);
+ m_sPostSfx = GpListener.obtainAtt(listenerConfig,FILE_POST_SFX,".esbDone").trim();
+ if (m_oPostDir.equals(m_oInpDir))
+ { if (m_sPostSfx.length()<1)
+ throw new Exception ("Invalid "+FILE_POST_SFX+" attribute");
+ if (m_sPostSfx.equals(m_sInpSfx))
+ throw new Exception("Post process suffix must differ from input suffix <"+m_sPostSfx+">");
+ }
+
+ } //________________________________
+
+ private File getFile(String file) {
+ try {
+ return new File(new URI(file));
+ } catch(Exception e) {
+ return new File(file);
+ }
+ }
+
+ protected void seeIfOkToWorkOnDir (File p_oDir) throws Exception
+ {
+ if (! p_oDir.exists())
+ throw new Exception ("Directory "+p_oDir.toString()+" not found");
+ if (!p_oDir.isDirectory())
+ throw new Exception(p_oDir.toString()+" is not a directory");
+ if (!p_oDir.canRead())
+ throw new Exception("Can't read directory "+p_oDir.toString());
+ if (! p_oDir.canWrite())
+ throw new Exception ("Can't write/rename in directory "+p_oDir.toString());
+ } //________________________________
+
+
+ private class FileEndsWith implements FileFilter
+ {
+ String m_sSuffix;
+ FileEndsWith(String p_sEnd) throws Exception
+ {
+ m_sSuffix = p_sEnd;
+ if (Util.isNullString(m_sSuffix))
+ throw new Exception("Must specify file extension");
+ } //______________________________
+
+ public boolean accept(File p_f)
+ { return (p_f.isFile())
+ ? p_f.toString().endsWith(m_sSuffix)
+ : false;
+ } //______________________________
+ } //____________________________________________________
+
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#close()
+ */
+ @Override
+ protected void close() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#processingError(java.lang.Object, org.jboss.soa.esb.actions.ActionProcessor, java.lang.Throwable)
+ */
+ @Override
+ protected void processingError(Object currentObject, ActionProcessor processor, Throwable error) {
+
+ if (null!=currentObject)
+ { WorkingFile workingFile = (WorkingFile) currentObject;
+ workingFile.renameToError();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#processingComplete(java.lang.Object)
+ */
+ @Override
+ protected void processingComplete(Object currentObject) {
+ WorkingFile workingFile = (WorkingFile) currentObject;
+
+ // Delete or rename the file...
+ if (workingFile.postDelete) {
+ workingFile.delete();
+ } else {
+ workingFile.renameToOutputFile();
+ }
+ }
+
+ /**
+ * Working file.
+ * <p/>
+ * Once the directory poller picks up on an input file, it immediately renames it to a working file
+ * in order to avoid a situation where the file gets processed again.
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ * @since Version 4.0
+ */
+ public static class WorkingFile extends File {
+ private static final long serialVersionUID = 1L;
+
+ private boolean postDelete;
+ public boolean isPostDelete() { return postDelete; }
+
+ private File inputFile, errorFile, outputFile;
+
+ public WorkingFile(String filename) {
+ super(filename);
+ }
+
+ public WorkingFile(File parentFile, String filename) {
+ super(parentFile, filename);
+ }
+
+ public boolean renameToError() {
+ return renameTo(errorFile);
+ }
+
+ public boolean renameToOutputFile() {
+ return renameTo(outputFile);
+ }
+
+ /**
+ * Get the File instance representing the original input file.
+ * @return Original input file.
+ */
+ public File getInputFile() {
+ return inputFile;
+ }
+ }
+}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/GpListener.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GpListener.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/GpListener.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/GpListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,660 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.soa.esb.listeners.old;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.command.CommandQueue;
+import org.jboss.internal.soa.esb.command.CommandQueueException;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.ActionDefinitionFactory;
+import org.jboss.soa.esb.common.Configuration;
+import org.jboss.soa.esb.common.Environment;
+import org.jboss.soa.esb.common.ModulePropertyManager;
+import org.jboss.soa.esb.helpers.DomElement;
+import org.jboss.soa.esb.notification.NotificationList;
+import org.jboss.soa.esb.parameters.ParamRepositoryException;
+import org.jboss.soa.esb.parameters.ParamRepositoryFactory;
+import org.jboss.soa.esb.services.NotificationHandlerFactory;
+import org.jboss.soa.esb.services.NotificationManager;
+import org.jboss.soa.esb.util.Util;
+import org.xml.sax.SAXException;
+
+/**
+ * Controlling class that will launch listener child threads for supported
+ * transport listener classes, as indicated in the configuration XML tree
+ * pointed by arg[0]
+ *
+ * <p />
+ * Can be launched as uppermost controller (it has a main(args) method)
+ * <p />
+ * Also implements Runnable, and can thus be launched in a child thread from an
+ * upper controlling process
+ * <p />
+ * Listens on a JMS queue (with an optional message selector) for commands (e.g.
+ * Quiesce, Reload Parameters, Set End Time, etc.)
+ * <p />
+ * Parameter reloading can also be set using the PARM_RELOAD_SECS attribute
+ * <p />
+ * End time for this instance can also be set using the PARM_END_TIME attribute
+ * <p />
+ *
+ * @author Esteban
+ *
+ */
+public class GpListener implements Runnable {
+
+ private static Logger m_oLogger = Logger.getLogger(GpListener.class);
+
+ public static void main(String[] args) throws Exception {
+ GpListener oProc = new GpListener(args[0]);
+ oProc.run();
+ GpListener.State oS = oProc.getState();
+
+ if (null != oS.getException()) {
+ m_oLogger.error("GpListener <" + args[0] + "> FAILED\n", oS
+ .getException());
+ }
+ System.exit(oS.getCompletionCode());
+ } // ________________________________
+
+ protected int m_iDfltReloadMillis = 180000 // default interval between
+ // parameter reloads
+ ;
+
+ public static final String PARM_RELOAD_SECS = "parameterReloadSecs";
+ public static final String PARM_END_TIME = "endTime";
+
+ // Attribute name that denotes listener class to be instantiated in a child
+ // thread
+ // This attribute is not in the root node but in first level child
+ // DomElements
+ public static final String PARM_LISTENER_CLASS = "listenerClass";
+ public static final String PARM_ACTIONS = "actions";
+ public static final String PARM_MAX_THREADS = "maxThreads";
+ public static final String CHLD_EMAIL_PARMS = "EmailProperties";
+
+ private String m_sParmsName;
+ private DomElement m_oParms;
+
+ private HashMap<String, Object> m_oAtts;
+
+ /**
+ * Obtain a shallow copy of needed atributes in this object's last loaded
+ * parameter tree <p/>The local bject is cloned so child threads can use it
+ * as they choose to without interfering with the environment
+ * <p />
+ * Listener processes controlled by this object should keep a reference to
+ * this object at construction time, and not call this method again unless
+ * they specifically need updated values. Parameter reload could have
+ * happened since last call
+ *
+ * @return Map - a shallow copy of the attributes Map
+ */
+ @SuppressWarnings("unchecked")
+ public Map<String, Object> getControllerAttributes() {
+ return (Map<String, Object>) m_oAtts.clone();
+ }
+
+ private boolean m_bReloadRequested, m_bEndRequested;
+
+ private long m_lNextReload = Long.MAX_VALUE;
+
+ private long m_lEndTime = Long.MAX_VALUE;
+
+ public static final SimpleDateFormat s_oDateParse = new SimpleDateFormat(
+ "yyyyMMdd hh:mm:ss");
+
+ private State m_oState = null;
+
+ public State getState() {
+ return m_oState;
+ }
+
+ public static enum State {
+ Loading_parameters, Running, Shutting_down, Done_OK, Exception_thrown;
+ int m_iCompletionCode = 0;
+
+ Exception m_oException = null;
+
+ public int getCompletionCode() {
+ return m_iCompletionCode;
+ };
+
+ public Exception getException() {
+ return m_oException;
+ }
+ };
+
+ private CommandQueue commandQueue;
+
+ private ActionDefinitionFactory actionDefinitionFactory;
+
+ private static CommandQueue defaultCommandQueue = null;
+
+ /**
+ * Package pivate default constructor.
+ */
+ protected GpListener() {
+ }
+
+ /**
+ * Construct a Listener Manager from the named repository based
+ * configuration.
+ *
+ * @param p_sParameterName
+ * Name of the Repository entry containing the configuration.
+ * @throws Exception
+ * Unable to load/use the named configuration.
+ */
+ public GpListener(String p_sParameterName) throws Exception {
+ this(GpListener.getListenerConfig(p_sParameterName));
+ m_sParmsName = p_sParameterName;
+ }
+
+ /**
+ * Construct a Listener Manager using the specified listener configuration.
+ *
+ * @param config
+ * The configuration.
+ * @throws Exception
+ * Unable to load/use the supplied configuration.
+ */
+ public GpListener(DomElement config) throws Exception {
+ m_oParms = config;
+ m_oState = State.Loading_parameters;
+
+ try {
+ checkParms(m_oParms);
+ setEmailSystemProperties();
+ } catch (Exception e) {
+ String configSource = config.getAttr("configSource");
+
+ m_oState = State.Exception_thrown;
+ m_oState.m_oException = e;
+ m_oLogger.fatal("Listener configuration and startup error. Config Source: "
+ + (configSource != null ? configSource
+ : "unknown"), e);
+
+ throw e;
+ }
+ }
+
+ /**
+ * Load the named listener configuration from the configured parameter
+ * repository.
+ *
+ * @param reposParam
+ * The name of the repository entry containing the Listener
+ * configuration.
+ * @return Listener Configuration as {@link DomElement}.
+ * @throws IOException
+ * Unable to access the repository.
+ * @throws ParamRepositoryException
+ * Unable to access the configuration in the repository.
+ * @throws SAXException
+ * Unable to parse the configuration.
+ */
+ private static DomElement getListenerConfig(String reposParam)
+ throws IOException, ParamRepositoryException, SAXException {
+ String sXml = ParamRepositoryFactory.getInstance().get(reposParam);
+ DomElement config = DomElement.fromXml(sXml);
+
+ config.setAttr("configSource", "param-repository:" + reposParam);
+
+ return config;
+ }
+
+ /**
+ * Check to see if all needed parameters are there, and assign default
+ * values to some of them
+ *
+ * @param p_oP
+ * DomElement - Where to look for the mandatory/optional
+ * configuration attributes
+ * @throws Exception -
+ * If attributes are wrong or not enough for a proper runtime
+ * configuration
+ */
+ public void checkParms(DomElement p_oP) throws Exception {
+ // We've just loaded - set to false until next reload requested
+ m_bReloadRequested = false;
+ commandQueue = createCommandQueue(p_oP);
+
+ // Open the command queue...
+ if (null!=commandQueue)
+ commandQueue.open(p_oP);
+
+ // if PARM_RELOAD_SECS not set, and no command queue
+ // then reload every 10 minutes
+ // If there is a command queue, run until command is received
+ String sRldSecs = p_oP.getAttr(PARM_RELOAD_SECS);
+ m_lNextReload = (null != sRldSecs)
+ ? System.currentTimeMillis() + 1000 * Long.parseLong(sRldSecs)
+ : (null == commandQueue)
+ ? Long.MAX_VALUE
+ : System.currentTimeMillis() + m_iDfltReloadMillis;
+
+ // if PARM_END_TIME not set try to run forever
+ // not a good practice if command queue is not set
+ // Expected date format is "yyyyMMdd hh:mm:ss"
+ String sEndT = p_oP.getAttr(PARM_END_TIME);
+ m_lEndTime = (null == sEndT) ? Long.MAX_VALUE : s_oDateParse.parse(
+ sEndT).getTime();
+
+ // Read and initialise the action definitions...
+ DomElement actionConfig = p_oP.getFirstElementChild("Actions");
+ if(actionConfig == null) {
+ throw new ConfigurationException("No 'Actions' configuration.");
+ }
+ actionDefinitionFactory = new ActionDefinitionFactory(actionConfig);
+
+ } // ________________________________
+
+ /**
+ * Factory method for creating the command queue.
+ * @param config GpListener config.
+ * @return GpListener CommandQueue instance.
+ */
+ private CommandQueue createCommandQueue(DomElement config) {
+ String commandQueueClass = config.getAttr("command-queue-class");
+
+ if(commandQueueClass != null) {
+ try {
+ return (CommandQueue) Class.forName(commandQueueClass).newInstance();
+ } catch (Exception e) {
+ m_oLogger.error("Failed to instantiate CommandQueue ["+ commandQueueClass + "]. Defaulting to no Command Queue", e);
+ }
+ }
+
+ return defaultCommandQueue;
+ }
+
+ /**
+ * Allows a default command queue to be set statically for all GpListener instances.
+ * @param defaultCommandQueue The defaultCommandQueue to set.
+ */
+ public static void setDefaultCommandQueue(CommandQueue defaultCommandQueue) {
+ GpListener.defaultCommandQueue = defaultCommandQueue;
+ }
+
+ /**
+ * Main execution loop <p/> Will continue to run until either <p/>a) run
+ * time is expired <p/>b) quiesce command is received in command queue
+ * <p/>For every child element that contains a PARM_LISTENER_CLASS
+ * attribute, this method will try to launch a child thread instantiating an
+ * object of that class, and will call it's run() method <p/>Once all child
+ * processes are trigered, the main thread will either <p/>1) wait for a
+ * message in the command queue (if one was configured) until next reload or
+ * end of run period expired <p/>or 2) Just sleep if there's no command
+ * queue to listen on
+ */
+ public void run() {
+ while (endNotRequested()) {
+ m_oState = State.Running;
+ for (DomElement oCurr : m_oParms.getAllElemChildren()) {
+ String sClass = oCurr.getAttr(PARM_LISTENER_CLASS);
+ if (Util.isNullString(sClass))
+ continue;
+ tryToLaunchChildListener(oCurr, sClass);
+ }
+
+ waitForCmdOrSleep();
+
+ if (endRequested()) {
+ break;
+ }
+ if (m_sParmsName != null && timeToReload()) {
+ try {
+ m_oState = State.Loading_parameters;
+ m_oLogger
+ .info("Reloading parameters _____________________________________________________");
+ DomElement oNew = GpListener.getListenerConfig(m_sParmsName);
+ checkParms(oNew);
+ m_oParms = oNew;
+ setEmailSystemProperties();
+ } catch (Exception e) {
+ m_oLogger.error("Failed to reload parameters"
+ + " - Continuing with cached version", e);
+ }
+ }
+ }
+ // m_oState = State.Shutting_down;
+
+ m_oState = State.Done_OK;
+ m_oState.m_iCompletionCode = 0;
+ m_oLogger
+ .info("Finishing_____________________________________________________");
+
+ // Close the command queue...
+ try {
+ commandQueue.close();
+ } catch (CommandQueueException e) {
+ m_oLogger.error("Error closing Command Queue.", e);
+ }
+ } // ________________________________
+
+ private void tryToLaunchChildListener(DomElement p_oP, String p_sClassName) {
+ try {
+ Class oListener = Class.forName(p_sClassName);
+ Constructor oConst = oListener.getConstructor(new Class[] {
+ this.getClass(), DomElement.class, ActionDefinitionFactory.class });
+ Runnable oRun = (Runnable) oConst.newInstance(new Object[] { this,
+ p_oP, actionDefinitionFactory });
+ new Thread(oRun).start();
+ } catch (Exception e) {
+ m_oLogger.error("Cannot launch <" + p_sClassName + ">\n", e);
+ }
+ } // ________________________________
+
+ public long millisToWait() {
+ return Math.min(m_lNextReload, m_lEndTime) - System.currentTimeMillis();
+ } // ________________________________
+
+ private void waitForCmdOrSleep() {
+ long lToGo = millisToWait();
+
+ if (null == commandQueue) {
+ m_oLogger.debug("About to sleep " + lToGo);
+ // No command queue nor topic - Just sleep until time
+ // exhausted, or thread interrupted
+ try {
+ if (lToGo > 0)
+ Thread.sleep(lToGo);
+ } catch (InterruptedException e) {
+ m_lEndTime = 0; // mark as end requested and return
+ }
+ return;
+ }
+
+ // Wait for commands until time exhausted or command received
+ // Note that received commands might change time variables (reload/end)
+ // that's why time to go is recalculated on each cycle
+ while ((lToGo = millisToWait()) > 0) {
+ try {
+ m_oLogger.info("Waiting for command ... timeout=" + lToGo + " millis");
+
+ String oM = commandQueue.receiveCommand(lToGo);
+ if (null == oM) {
+ return;
+ }
+ processCommand(oM);
+ if (endRequested() || timeToReload()) {
+ break;
+ }
+ } catch (CommandQueueException eJ) {
+ m_oLogger.info("receive on command queue failed", eJ);
+ }
+ }
+ } // ________________________________
+
+ /**
+ * Processes the command that has been received in the command queue (or
+ * topic) <p/>m_bEndRequested, m_bReloadRequested, and m_lEndTime could be
+ * changed
+ *
+ * <p/> <p/><TABLE border="1"> <COLGROUP> <COL width="200"/> <COL
+ * width="400"/> </COLGROUP>
+ * <TR>
+ * <TD align="center">message text</TD>
+ * <TD align="center">effect</TD>
+ * </TR>
+ * <TR>
+ * <TD>shutdown*</TD>
+ * <TD>End time will be immediately set to 'now' - quiesce process will
+ * start - Child threads will be allowed to finish normally</TD>
+ * </TR>
+ * <TR>
+ * <TD>reload param*</TD>
+ * <TD>Parameters will be immediately reloaded, and listener reconfigured
+ * with new values</TD>
+ * </TR>
+ * <TR>
+ * <TD>endTime yyyyMMdd hh:mm:ss</TD>
+ * <TD>End time will be set to new value. If hh:mm:ss is not supplied =>
+ * end of day assumed (23:59:59)</TD>
+ * </TR>
+ * </TABLE> * startsWith() <p/>
+ *
+ * @param p_oMsg
+ * Message received from the command queue.
+ *
+ */
+ private void processCommand(String sTxt) {
+ if (null == sTxt)
+ return;
+
+ String sLow = sTxt.trim().toLowerCase();
+ if (sLow.startsWith("shutdown")) {
+ m_bEndRequested = true;
+ m_oLogger.info("Shutdown has been requested");
+ return;
+ }
+ if (sLow.startsWith("reload param")) {
+ m_bReloadRequested = true;
+ m_oLogger
+ .info("Request for parameter reload has been received");
+ return;
+ }
+ String[] sa = sLow.split("\\s+");
+ if (sa.length > 1 && "endtime".equals(sa[0])) {
+ try {
+ String sDate = sa[1];
+ String sTime = (sa.length < 3 || null == sa[2]) ? "23:59:59"
+ : sa[2];
+ Date oEnd = s_oDateParse.parse(sDate + " " + sTime);
+ m_oLogger.info("New end date set to : " + oEnd);
+ m_lEndTime = oEnd.getTime();
+ } catch (Exception eDat) {
+ m_oLogger.info("Problems with endTime command", eDat);
+ }
+ }
+ } // ________________________________
+
+ /**
+ * Accessor to determine if execution time is expired or shutdown requested
+ *
+ * @return boolean if processing has to stop (all child threads will be
+ * allowed to finish)
+ */
+ public boolean endRequested() {
+ return m_bEndRequested || System.currentTimeMillis() >= m_lEndTime;
+ }
+
+ /**
+ * Accessor to determine if execution time is not expired, and no shutdown
+ * request received
+ *
+ * @return boolean - true if run time has not expired and quiesce has not
+ * been requested
+ */
+ public boolean endNotRequested() {
+ return !endRequested();
+ }
+
+ /**
+ * Provide a common accessor to determine if parameters have to be reloaded
+ * <p/> For child threads this means thread execution has to end
+ * </p>
+ * Child processes should only call this method when they are idle (as
+ * opposed to in the middle of executing a unit of work)
+ *
+ * @return boolean - true if it's time to reload parameters
+ */
+ public boolean timeToReload() {
+ return m_bReloadRequested
+ || System.currentTimeMillis() >= m_lNextReload;
+ }
+
+ /**
+ * Helper accessor for child processes that provides info to determine if
+ * they can continue with yet another execution cycle
+ *
+ * @return boolean - true if runtime is not expired and not time yet to
+ * reload parameters
+ */
+ public boolean continueLooping() {
+ return (endNotRequested() && !timeToReload());
+ } // ________________________________
+
+ private static final String[] s_saMailProps = { Environment.SMTP_HOST,
+ Environment.SMTP_USERNAME, Environment.SMTP_PASSWORD,
+ Environment.SMTP_PORT, Environment.SMTP_FROM,
+ Environment.SMTP_AUTH };
+
+ private void setEmailSystemProperties() {
+ DomElement oEmail = m_oParms.getFirstElementChild(CHLD_EMAIL_PARMS);
+ if (null != oEmail)
+ for (String sCurr : s_saMailProps) {
+ String sProp = oEmail.getAttr(sCurr);
+ if (null != sProp)
+ ModulePropertyManager.getPropertyManager(ModulePropertyManager.TRANSPORTS_MODULE).setProperty(sCurr, sProp);
+ }
+ } // ________________________________
+
+ /**
+ * Find an attribute in the tree (arg 0) or assign default value (arg 2)
+ *
+ * @param p_oP
+ * DomElement - 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 Exception -
+ * If requested attribute not found and no default value
+ * supplied by invoker
+ */
+ public static String obtainAtt(DomElement p_oP, String p_sAtt, String p_sDefault)
+ throws ConfigurationException {
+ String sVal = p_oP.getAttr(p_sAtt);
+ if ((null == sVal) && (null == p_sDefault))
+ throw new ConfigurationException("Missing or invalid <" + p_sAtt + "> attribute");
+
+ return (null != sVal) ? sVal : p_sDefault;
+ } // ________________________________
+
+ /**
+ * Find child nodes named "NotificationList" that contain an attribute
+ * 'type' that starts with "ok" (case insensitive)
+ *
+ * @param p_oP -
+ * DomElement to search for "NotificationList" child Elements
+ * @param p_oSer
+ * Serializable - Will constitute the body of the notification
+ */
+ public static void notifyOK(DomElement p_oP, Serializable p_oSer) {
+ if(p_oSer == null) {
+ return;
+ }
+
+ try {
+ Serializable oNotif = p_oSer;
+ for (DomElement oCurr : p_oP
+ .getElementChildren(NotificationList.ELEMENT)) {
+ NotificationList oNL = new NotificationList(oCurr);
+ if (!oNL.isOK())
+ continue;
+ getNotifHandler().sendNotifications(oCurr, oNotif);
+ }
+ } catch (Exception e) {
+ }
+ } // __________________________________
+
+ /**
+ * Find child nodes named "NotificationList" that contain an attribute
+ * 'type' that starts with "err" (case insensitive) or no 'type' attribute
+ * set
+ *
+ * @param p_oP -
+ * DomElement to search for "NotificationList" child Elements
+ * @param p_e -
+ * Exception if not null, will be appended to the body
+ * @param p_oSer
+ * Serializable - Will be included at the beginning of the body
+ * of the notification
+ */
+ public static void notifyError(DomElement p_oP, Exception p_e, Serializable p_oSer) {
+ if(p_oSer == null) {
+ return;
+ }
+
+ Serializable oNotif = p_oSer;
+ ByteArrayOutputStream oBO = new ByteArrayOutputStream();
+ PrintStream oPS = new PrintStream(oBO);
+ try {
+ oPS.println(oNotif.toString());
+ if (null != p_e)
+ p_e.printStackTrace(oPS);
+ oPS.close();
+
+ String sMsg = oBO.toString();
+ for (DomElement oCurr : p_oP
+ .getElementChildren(NotificationList.ELEMENT)) {
+ NotificationList oNL = new NotificationList(oCurr);
+ if (!oNL.isErr())
+ continue;
+ getNotifHandler().sendNotifications(oNL, sMsg);
+ }
+ } catch (Exception e) {
+ }
+ } // ________________________________
+
+ private static NotificationManager s_oNH;
+
+ private static final Object s_oSync = new Integer(0);
+
+ /**
+ * Lazy instantiator of a InotificationHandler
+ *
+ * @return - a reference to an implementation of the interface or null if it
+ * can't be instantiated
+ */
+ protected static NotificationManager getNotifHandler() {
+ if (null != s_oNH)
+ return s_oNH;
+ synchronized (s_oSync) {
+ if (null == s_oNH)
+ try {
+ s_oNH = NotificationHandlerFactory.getNotifHandler(
+ "remote", Configuration.getJndiServerType(),
+ Configuration.getJndiServerURL());
+ } catch (Exception e) {
+ Logger.getLogger(GpListener.class).error(
+ "Notification FAILED", e);
+ }
+ }
+ return s_oNH;
+ } // ______________________________
+
+} // ____________________________________________________________________________
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/JmsQueueListener.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsQueueListener.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/JmsQueueListener.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/JmsQueueListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,187 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.soa.esb.listeners.old;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueSession;
+import javax.jms.TextMessage;
+import javax.jms.TopicSession;
+import javax.naming.Context;
+
+import org.jboss.soa.esb.actions.ActionDefinitionFactory;
+import org.jboss.soa.esb.actions.ActionProcessor;
+import org.jboss.soa.esb.helpers.AppServerContext;
+import org.jboss.soa.esb.helpers.DomElement;
+
+public class JmsQueueListener extends AbstractListener {
+
+ public static final String LISTEN_QUEUE_CONN_FACT = "queueConnFactoryClass";
+ public static final String LISTEN_JNDI_TYPE = "listenJndiType";
+ public static final String LISTEN_JNDI_URL = "listenJndiURL";
+ public static final String LISTEN_QUEUE = "listenQueue";
+ public static final String LISTEN_MSG_SELECTOR = "listenMsgSelector";
+
+ protected boolean m_bError = false;
+ protected QueueConnection m_oQconn;
+ protected QueueSession m_oQsess;
+ protected Queue m_oQueue;
+ protected String m_sSelector;
+
+ protected MessageConsumer jmsMessageReceiver;
+
+
+ public JmsQueueListener(GpListener commandListener, DomElement listenerConfig, ActionDefinitionFactory actionDefinitionFactory) throws Exception {
+ super(commandListener, listenerConfig, actionDefinitionFactory);
+ checkMyParms();
+ } // __________________________________
+
+ /**
+ * Check for mandatory and optional attributes in parameter tree
+ *
+ * @throws Exception -
+ * if mandatory atts are not right or actionClass not in
+ * classpath
+ */
+ protected void checkMyParms() throws Exception {
+ // Third arg is null - Exception will br thrown if listenQueue is not
+ // found
+ String sQueue = GpListener.obtainAtt(listenerConfig, LISTEN_QUEUE, null);
+
+ // No problem if selector is null - everything in queue will be returned
+ m_sSelector = listenerConfig.getAttr(LISTEN_MSG_SELECTOR);
+
+ m_oQconn = null;
+ m_oQsess = null;
+ m_oQueue = null;
+
+ String sJndiType = GpListener.obtainAtt(listenerConfig, LISTEN_JNDI_TYPE,
+ "jboss");
+ String sJndiURL = GpListener.obtainAtt(listenerConfig, LISTEN_JNDI_URL,
+ "localhost");
+ Context oJndiCtx = AppServerContext.getServerContext(sJndiType,
+ sJndiURL);
+
+ String sFactClass = GpListener.obtainAtt(listenerConfig,
+ LISTEN_QUEUE_CONN_FACT, "ConnectionFactory");
+ Object tmp = oJndiCtx.lookup(sFactClass);
+ QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
+
+ m_oQconn = qcf.createQueueConnection();
+ m_oQueue = (Queue) oJndiCtx.lookup(sQueue);
+ m_oQsess = m_oQconn.createQueueSession(false,
+ TopicSession.AUTO_ACKNOWLEDGE);
+ m_oQconn.start();
+ jmsMessageReceiver = m_oQsess.createReceiver(m_oQueue, m_sSelector);
+
+ } // ________________________________
+
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#receive()
+ */
+ @Override
+ protected Object[] receive() {
+ while (m_oDad.continueLooping()) {
+ Message jmsMessage = null;
+ try {
+ jmsMessage = jmsMessageReceiver.receive(m_oDad.millisToWait());
+ } catch (JMSException oJ) {
+ logger.error("JMS error on receive. Attempting JMS Destination reconnect.", oJ);
+ for (int i1 = 0; i1 < 3; i1++)
+ try {
+ checkMyParms();
+ } // try to reconnect to the queue
+ catch (Exception e) {
+ logger.error("Reconnecting to Queue", e);
+ try {
+ Thread.sleep(m_iSleepForThreads);
+ } catch (InterruptedException e1) { // Just return
+ logger.error("Unexpected thread interupt exception.", e);
+ return null;
+ }
+ }
+ }
+ if (null == jmsMessage) {
+ // REVIEW: Can this really happen i.e. the JMS
+ continue;
+ }
+
+ if (jmsMessage instanceof ObjectMessage) {
+ try {
+ return new Object[] {((ObjectMessage)jmsMessage).getObject()};
+ } catch (JMSException e) {
+ logger.error("Failed to read Serialized Object from JMS message.", e);
+ }
+ } else if (jmsMessage instanceof TextMessage) {
+ try {
+ return new Object[] {((TextMessage)jmsMessage).getText()};
+ } catch (JMSException e) {
+ logger.error("Failed to read Serialized Object from JMS message.", e);
+ }
+ } else {
+ logger.error("Unsupported JMS message type: " + jmsMessage.getClass().getName());
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#close()
+ */
+ @Override
+ protected void close() {
+ if (null != m_oQsess) {
+ try {
+ m_oQsess.close();
+ } catch (Exception e1) {/* Tried my best - Just continue */
+ }
+ }
+ if (null != m_oQconn) {
+ try {
+ m_oQconn.close();
+ } catch (Exception e2) {/* Tried my best - Just continue */
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#processingError(java.lang.Object, org.jboss.soa.esb.actions.ActionProcessor, java.lang.Throwable)
+ */
+ @Override
+ protected void processingError(Object initialMessage, ActionProcessor processor, Throwable error) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#processingComplete(java.lang.Object)
+ */
+ @Override
+ protected void processingComplete(Object initialMessage) {
+ }
+}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/RemoteDirectoryPoller.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/RemoteDirectoryPoller.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/RemoteDirectoryPoller.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/RemoteDirectoryPoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,284 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY 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 along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+
+package org.jboss.soa.esb.listeners.old;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.jboss.soa.esb.actions.ActionDefinitionFactory;
+import org.jboss.soa.esb.actions.ActionProcessor;
+import org.jboss.soa.esb.helpers.DomElement;
+import org.jboss.soa.esb.helpers.KeyValuePair;
+import org.jboss.soa.esb.util.FtpClientUtil;
+import org.jboss.soa.esb.util.Util;
+
+public class RemoteDirectoryPoller extends AbstractPoller
+{
+ public static final String FILE_INPUT_DIR = "inputDir";
+ public static final String FILE_INPUT_SFX = "inputSuffix";
+ public static final String FILE_WORK_SFX = "workSuffix";
+ public static final String FILE_ERROR_DIR = "errorDir";
+ public static final String FILE_ERROR_SFX = "errorSuffix";
+ public static final String FILE_POST_DIR = "postDir";
+ public static final String FILE_POST_SFX = "postSuffix";
+ public static final String FILE_POST_DEL = "postDelete";
+
+ private DomElement _params;
+ private Logger _logger = Logger.getLogger(this.getClass());
+ FtpClientUtil _ftpClient;
+
+ public RemoteDirectoryPoller(GpListener p_oDad, DomElement p_oParms,ActionDefinitionFactory actionDF)
+ throws Exception
+ {
+ super(p_oDad,p_oParms,actionDF);
+ _params = p_oParms;
+ checkMyParms();
+ } //__________________________________
+
+
+ protected File m_oInpDir ,m_oErrorDir ,m_oPostDir;
+ protected String m_sInpSfx ,m_sWrkSfx ,m_sErrSfx ,m_sPostSfx;
+ protected boolean m_bPostDel;
+ private List <KeyValuePair> m_ftpProps = new ArrayList<KeyValuePair>();
+
+ /**
+ *
+ * @param p_o Object - Must be a File representing the file that has to be processed
+ * @return Object - an instance of the internal WorkingFile class
+ */
+ @Override
+ public Object preProcess(Object p_o)
+ {
+ if (!(p_o instanceof File))
+ return null;
+ File oF = (File)p_o;
+ WorkingFile oCurr = new WorkingFile(oF,m_sWrkSfx,m_bPostDel);
+ oCurr.errorFile = new File (m_oErrorDir ,oF.getName()+m_sErrSfx);
+ oCurr.outputFile = new File (m_oPostDir ,oF.getName()+m_sPostSfx);
+ oCurr.setFtpProps(m_ftpProps);
+
+ try
+ {
+ _ftpClient = new FtpClientUtil(_params,true);
+ _ftpClient.remoteRename(oF,oCurr);
+ }
+ catch (Exception e)
+ {
+ _logger.error("Can't FTP rename",e);
+ return null;
+ }
+ finally
+ {
+ if (null!=_ftpClient)
+ _ftpClient.quit();
+ _ftpClient = null;
+ }
+
+ return oCurr;
+ } //________________________________
+
+ @Override
+ protected List<Object> pollForCandidates()
+ {
+ List<Object> oRet = new ArrayList<Object>();
+ FtpClientUtil _ftpClient = null;
+ try
+ {
+ _ftpClient = new FtpClientUtil(_params,true);
+ _ftpClient.setRemoteDir(FtpClientUtil.fileToFtpString(m_oInpDir));
+ String[] sa = _ftpClient.getFileListFromRemoteDir(m_sInpSfx);
+ if (null!=sa)
+ for (String sCurr : sa)
+ oRet.add(new File(m_oInpDir,sCurr));
+ }
+ catch (Exception e)
+ {
+ _logger.error("Problems with FTP",e);
+ }
+ finally
+ {
+ if (null!=_ftpClient)
+ _ftpClient.quit();
+ _ftpClient = null;
+ }
+ return oRet;
+
+ } //________________________________
+
+ protected void checkMyParms() throws Exception
+ {
+ // INPUT directory and suffix (used for FileFilter)
+ String sInpDir = GpListener.obtainAtt(_params,FILE_INPUT_DIR,null);
+ m_oInpDir = new File(sInpDir);
+
+ m_sInpSfx = GpListener.obtainAtt(_params,FILE_INPUT_SFX,null);
+ m_sInpSfx = m_sInpSfx.trim();
+ if (m_sInpSfx.length()<1)
+ throw new Exception ("Invalid "+FILE_INPUT_SFX+" attribute");
+
+ // WORK suffix (will rename in input directory)
+ m_sWrkSfx = GpListener.obtainAtt(_params,FILE_WORK_SFX,".esbWork").trim();
+ if (m_sWrkSfx.length()<1)
+ throw new Exception ("Invalid "+FILE_WORK_SFX+" attribute");
+ if (m_sInpSfx.equals(m_sWrkSfx))
+ throw new Exception("Work suffix must differ from input suffix <"+m_sWrkSfx+">");
+
+ // ERROR directory and suffix (defaults to input dir and ".esbError" suffix)
+ String sErrDir = GpListener.obtainAtt(_params,FILE_ERROR_DIR,sInpDir);
+ m_oErrorDir = new File(sErrDir);
+
+ m_sErrSfx = GpListener.obtainAtt(_params,FILE_ERROR_SFX,".esbError").trim();
+ if (m_sErrSfx.length()<1)
+ throw new Exception ("Invalid "+FILE_ERROR_SFX+" attribute");
+ if (m_oErrorDir.equals(m_oInpDir) && m_sInpSfx.equals(m_sErrSfx))
+ throw new Exception("Error suffix must differ from input suffix <"+m_sErrSfx+">");
+
+
+ // Do users wish to delete files that were processed OK ?
+ String sPostDel = GpListener.obtainAtt(_params,FILE_POST_DEL,"false").trim();
+ m_bPostDel = Boolean.parseBoolean(sPostDel);
+ if (m_bPostDel)
+ return;
+
+ // POST (done) directory and suffix (defaults to input dir and ".esbDone" suffix)
+ String sPostDir = GpListener.obtainAtt(_params,FILE_POST_DIR,sInpDir);
+ m_oPostDir = new File(sPostDir);
+ m_sPostSfx = GpListener.obtainAtt(_params,FILE_POST_SFX,".esbDone").trim();
+ if (m_oPostDir.equals(m_oInpDir))
+ { if (m_sPostSfx.length()<1)
+ throw new Exception ("Invalid "+FILE_POST_SFX+" attribute");
+ if (m_sPostSfx.equals(m_sInpSfx))
+ throw new Exception("Post process suffix must differ from input suffix <"+m_sPostSfx+">");
+ }
+
+
+ FtpClientUtil _ftpClient = new FtpClientUtil(_params,false);
+ _ftpClient.quit();
+
+ // Copy FTP parameters to be passed to the action class (inside the WorkingFile class)
+ // This is a kludge - we have to get back to this (ES)
+ String[] sa = new String[]
+ {FtpClientUtil.PARMS_FTP_SERVER
+ ,FtpClientUtil.PARMS_USER
+ ,FtpClientUtil.PARMS_PASSWD
+ ,FtpClientUtil.PARMS_PASSIVE
+ ,FtpClientUtil.PARMS_PORT
+ };
+ for (String sProp : sa)
+ {
+ String sVal = _params.getAttr(sProp);
+ if (!Util.isNullString(sVal))
+ m_ftpProps.add(new KeyValuePair(sProp,sVal));
+ }
+
+ } //________________________________
+
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#close()
+ */
+ @Override
+ protected void close() { }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#processingError(java.lang.Object, org.jboss.soa.esb.actions.ActionProcessor, java.lang.Throwable)
+ */
+ @Override
+ protected void processingError(Object initialMessage, ActionProcessor processor, Throwable error)
+ {
+ @SuppressWarnings("unused")
+ WorkingFile workingFile = (WorkingFile) initialMessage;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#processingComplete(java.lang.Object)
+ */
+ @Override
+ protected void processingComplete(Object initialMessage)
+ {
+ @SuppressWarnings("unused")
+ WorkingFile workingFile = (WorkingFile) initialMessage;
+ }
+
+ /**
+ * Working file.
+ * <p/>
+ * Once the remote directory poller picks up on an input file, it immediately tries to rename
+ * it to a working file in order to avoid a situation where the file gets processed again.
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ * @since Version 4.0
+ */
+ public static class WorkingFile extends File
+ {
+ private static final long serialVersionUID = 1L;
+
+ private boolean postDelete;
+ private File inputFile, errorFile, outputFile;
+ private List <KeyValuePair> ftpProps;
+ public void setFtpProps(List <KeyValuePair>props) {ftpProps = props; }
+ public List <KeyValuePair >getFtpProps() {return ftpProps; }
+
+ private WorkingFile(File pFile,String pWrkSfx, boolean pPostDelete)
+ {
+ super(pFile.getParentFile(), pFile.getName() + pWrkSfx);
+ inputFile = pFile;
+ }
+ /**
+ * Get the File instance representing the original input file.
+ * @return Original input file.
+ */
+ public File getInputFile() { return inputFile; }
+ /**
+ * is this working file to be deleted after successful processing ?
+ * @return boolean - true if this file can be deleted
+ */
+ public boolean isPostDelete() { return postDelete; }
+
+ public boolean localRenameToInput() { return super.renameTo(inputFile); }
+ public void remoteRenameToInput(FtpClientUtil util) throws Exception
+ {
+ util.remoteRename(this,inputFile);
+ }
+
+ public boolean localRenameToError() { return super.renameTo(errorFile); }
+ public void remoteRenameToError(FtpClientUtil util) throws Exception
+ {
+ util.remoteRename(this,errorFile);
+ }
+
+ public boolean localRenameToOutput() { return renameTo(outputFile); }
+ public void remoteRenameToOutput(FtpClientUtil util) throws Exception
+ {
+ util.remoteRename(this,outputFile);
+ }
+
+ public boolean localDelete() {return delete(); }
+ public void remoteDelete(FtpClientUtil util) throws Exception
+ {util.deleteRemoteFile(this.toString()); }
+
+ }
+} //____________________________________________________________________________
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/SqlTablePoller.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/SqlTablePoller.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/SqlTablePoller.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/old/SqlTablePoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,505 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY 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 along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+
+package org.jboss.soa.esb.listeners.old;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.sql.DataSource;
+
+import org.jboss.soa.esb.actions.ActionDefinitionFactory;
+import org.jboss.soa.esb.actions.ActionProcessor;
+import org.jboss.soa.esb.helpers.DomElement;
+import org.jboss.soa.esb.helpers.persist.JdbcCleanConn;
+import org.jboss.soa.esb.helpers.persist.SimpleDataSource;
+import org.jboss.soa.esb.util.Util;
+
+/**
+ * SqlTablePoller class
+ *
+ * The SQL table that is polled should have
+ * 1) a unique key (see "keyFields" parameter) that will be used to update status
+ * 2) a column to indicate the "processing status" of this trigger row (see ROW_STATE enum)
+ *
+ * Each retrieved row (see OPTIONAL_ATT.whereCondition) should be considered as a trigger
+ * that is intended to instantiate an object of "actionClass". The new instance will
+ * receive the full DomElement (level 1 for each child group)
+ *
+ * @author Esteban Schifman
+ */
+public class SqlTablePoller extends AbstractPoller
+{
+/* ___________________ Example XML configuration file for a SqlTablePoller_______________
+ *
+<DocumentElementName>
+ <ExampleListenChapter
+ maxThreads="2"
+ listenerClass="org.jboss.soa.esb.listeners.SqlTablePoller"
+ actionClass="org.jboss.soa.esb.actions.templates.MockSqlRowAction"
+
+ driver-class="org.postgresql.Driver"
+ connection-url="jdbc:postgresql://myhost:5432/myDB"
+ user-name="postgres"
+ password=""
+
+ tableName="test_notif_table"
+ selectFields="oid,ref,msg"
+ keyFields="oid,ref"
+ inProcessField="statusCol"
+ whereCondition="src='pepe'"
+ orderBy="oid desc"
+ >
+ <NotificationList type="OK">
+ <target class="NotifyFiles">
+ <file URI="file:///tmp/jbossEsb/notifyDir/ListenOnNotifTable.notifOK"
+ append="true"
+ />
+ </target>
+ </NotificationList>
+
+ <NotificationList type="err">
+ <target class="NotifyFiles">
+ <file URI="file:///tmp/jbossEsb/notifyDir/ListenOnNotifTable.notifErr"
+ append="true"
+ />
+ </target>
+ </NotificationList>
+ </ExampleListenChapter>
+</DocumentElementName>
+ *
+ */
+
+ /**
+ * Mandatory attributes needed for SqlTablePoller
+ * 1) Table name
+ * 2) Comma separated list of fields needed in the ResultSet
+ * 3) Comma separated list of fields that constitute a unique ID of the working row
+ * all fields in this list MUST also be in the "selectFields" list
+ * these fields will be used in the "where" clause of update statements
+ * 4) Name of table field used as indicator/semaphore to avoid concurrent update
+ *
+ */
+ public static enum TABLE_ATT
+ {
+ tableName
+ ,selectFields
+ ,keyFields
+ ,inProcessField
+ };
+
+ /**
+ * Optional fields that can be included in your parameter tree as attributes in the
+ * upper Element
+ * 1) 4 character long String that indicate status of each row for this poller
+ * 1st: Character that indicates "Pending" state = available for processing
+ * 2nd: "Working" : some poller is working on the row (or ab-ended while working)
+ * 3rd: "Error" : some poller tried to process, and found an error during processing
+ * 4th: "Done" : this row has already been processed successfully
+ * 2) if you wish to further filter your ResultSet, you can add an optional list of
+ * conditions that will be included in the "scan" SQL statement (without "where")
+ * 3) Comma separated list of fields to order ResultSet (without "order by")
+ *
+ */
+ public static enum OPTIONAL_ATT
+ {
+ inProcessVals
+ ,whereCondition
+ ,orderBy
+ };
+
+ /**
+ * First character of these values are the default states of a table row trigger
+ * the "inProcessVals" parameter can override these (if that were ever necessary)
+ * this is why the default value for that parameter is "PWED" (see below)
+ * The poller will only process rows that have the "inProcessField" first character
+ * equal to the first character of whatever the "Pending" state is (typically "P")
+ *
+ */
+ public static enum ROW_STATE
+ {Pending
+ ,Working
+ ,Error
+ ,Done
+ };
+ public static final String DEFAULT_STATES = "PWED";
+
+ protected Map<String,String> m_oVals = new HashMap<String,String>();
+ protected String[] m_saCols ,m_saKeys;
+ protected String m_sUpdStates;
+
+ /**
+ * In this constructor you can override default values for the following protected base class values:
+ * <br/>
+ * <p/>m_iMinPollMillis : minimum polling interval (default 3000)
+ * <br/>m_iDfltPollMillis : default polling interval (default 20000)
+ * <br/>m_iSleepForThreads : how long to sleep if all configured threads are in use (default 3000)
+ * <br/>m_iUpperThreadLimit : max number of threads allowed (default 10)
+ * @param p_oDad GpListener - The controlling process
+ * @param p_oParms DomElement - Sub tree that corresponds to this instance
+ * @throws Exception
+ */
+ public SqlTablePoller(GpListener p_oDad, DomElement p_oParms, ActionDefinitionFactory actionDefinitionFactory) throws Exception
+ {
+ super(p_oDad, p_oParms, actionDefinitionFactory);
+ try { checkMyParms(); }
+ catch (Exception e)
+ {
+ logger.error("checkMyParms() FAILED",e);
+ throw e;
+ }
+ } //__________________________________
+
+ private void checkAndStoreAtt(DomElement p_oP, String p_sName, String p_sDflt)
+ throws Exception
+ {
+ m_oVals.put(p_sName,GpListener.obtainAtt(p_oP,p_sName,p_sDflt));
+ } //________________________________
+
+ protected void checkMyParms() throws Exception
+ {
+ checkAndStoreAtt(listenerConfig,SimpleDataSource.DRIVER ,null);
+ checkAndStoreAtt(listenerConfig,SimpleDataSource.URL ,null);
+ checkAndStoreAtt(listenerConfig,SimpleDataSource.USER ,"");
+ checkAndStoreAtt(listenerConfig,SimpleDataSource.PASSWORD ,"");
+
+ for (TABLE_ATT oCurr : TABLE_ATT.values())
+ checkAndStoreAtt(listenerConfig,oCurr.toString(),null);
+
+ checkAndStoreAtt(listenerConfig,OPTIONAL_ATT.whereCondition.toString(),"");
+ checkAndStoreAtt(listenerConfig,OPTIONAL_ATT.orderBy.toString(),"");
+
+ String sAtt = OPTIONAL_ATT.inProcessVals.toString();
+ checkAndStoreAtt(listenerConfig,sAtt,DEFAULT_STATES);
+ m_sUpdStates = m_oVals.get(sAtt);
+ if (m_sUpdStates.length()<4)
+ throw new Exception("Parameter <"+sAtt+"> must be at least 4 characters long (PWED)");
+
+ StringTokenizer ST = new StringTokenizer
+ (m_oVals.get(TABLE_ATT.selectFields.toString()),",");
+ m_saCols = new String[ST.countTokens()];
+ Set<String> oSelFlds = new HashSet<String>();
+ int iCurr = 0;
+ while (ST.hasMoreElements())
+ {
+ String sColName = ST.nextToken().trim();
+ m_saCols[iCurr++] = sColName;
+ oSelFlds.add(sColName);
+ }
+
+ ST = new StringTokenizer
+ (m_oVals.get(TABLE_ATT.keyFields.toString()),",");
+ m_saKeys = new String[ST.countTokens()];
+ if (m_saKeys.length < 1)
+ throw new Exception("Empty list of keyFields");
+
+ for (iCurr = 0; ST.hasMoreTokens(); iCurr++)
+ { String sKeyCol = ST.nextToken().trim();
+ if (! oSelFlds.contains(sKeyCol))
+ throw new Exception("Key field <"+ sKeyCol + "> must also be in select list");
+ m_saKeys[iCurr] = sKeyCol;
+ }
+
+ } //________________________________
+
+ @Override
+ protected Object preProcess(Object p_o)
+ {
+ return p_o;
+ } //________________________________
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected List<Object> pollForCandidates()
+ {
+ String sSel4U = selectForUpdStatement();
+ String sUpdStmt = updateStatement();
+ JdbcCleanConn oConn = null;
+ List<Object> oResults = new ArrayList<Object>();
+ try
+ {
+ oConn = newDbConn();
+ String sScan = scanStatement();
+
+ PreparedStatement PS = oConn.prepareStatement(sScan);
+ ResultSet RS = oConn.execQueryWait(PS,1);
+ while (RS.next()) {
+ SQLPollResult rowParams = new SQLPollResult(sSel4U, sUpdStmt);
+ int iCurr = 0;
+
+ for (String sColName : m_saCols) {
+ rowParams.put(sColName,RS.getObject(++iCurr));
+ }
+
+ // Set up the parameter object for the SqlRowAction
+ rowParams.sUpdStates = m_sUpdStates;
+ rowParams.saKeys = m_saKeys;
+ rowParams.sSel4Upd = sSel4U;
+ rowParams.sUpdate = sUpdStmt;
+
+ // Mark the row as "working"...
+ rowParams.changeStatusToWorking();
+
+ oResults.add(rowParams);
+ }
+ }
+ catch (Exception e)
+ {
+ logger.warn("Some triggers might not have been returned",e);
+ }
+ finally
+ {
+ if (null!=oConn)
+ oConn.release();
+ }
+
+ logger.info("Returning " + oResults.size() + " rows.");
+ return oResults;
+ } //________________________________
+
+ /**
+ * Obtain a new database connection with parameter info
+ * @return A new connection
+ * @throws Exception - if problems are encountered
+ */
+ protected JdbcCleanConn newDbConn() throws Exception
+ { DataSource oDS = new SimpleDataSource
+ (m_oVals.get(SimpleDataSource.DRIVER)
+ ,m_oVals.get(SimpleDataSource.URL)
+ ,m_oVals.get(SimpleDataSource.USER)
+ ,m_oVals.get(SimpleDataSource.PASSWORD)
+ );
+ return new JdbcCleanConn(oDS);
+ } //________________________________
+
+ /**
+ * Assemble the SQL statement to scan (poll) the table
+ * @return - The resulting SQL statement
+ */
+ protected String scanStatement()
+ {
+ StringBuilder sb = new StringBuilder ()
+ .append("select ").append(m_oVals.get(TABLE_ATT.selectFields.toString()))
+ .append(" from ") .append(m_oVals.get(TABLE_ATT.tableName.toString()));
+
+ String sAux = m_oVals.get(OPTIONAL_ATT.whereCondition.toString());
+ boolean bWhere = ! Util.isNullString(sAux);
+ if (bWhere)
+ sb.append(" where ").append(sAux);
+ sb.append((bWhere) ? " and " : " where ");
+
+ String sLike = m_oVals.get(OPTIONAL_ATT.inProcessVals.toString())
+ .substring(0,1).toUpperCase();
+ sb.append(" upper(").append(m_oVals.get(TABLE_ATT.inProcessField.toString()))
+ .append(") like '").append(sLike).append("%'");
+
+
+ sAux = m_oVals.get(OPTIONAL_ATT.orderBy);
+ if (! Util.isNullString(sAux))
+ sb.append(" order by ").append(sAux);
+ return sb.toString();
+ } //________________________________
+
+ /**
+ * Assemble the SQL statement to update the field
+ * in the "inProcessField" parameter
+ *
+ * in the table row uniquely identified by the list of fields
+ * in the "keyFields" parameter
+ *
+ * @return - The resulting SQL statement
+ */
+ protected String updateStatement()
+ {
+ StringBuilder sb = new StringBuilder ()
+ .append("update ").append(m_oVals.get(TABLE_ATT.tableName.toString()))
+ .append(" set ") .append(m_oVals.get(TABLE_ATT.inProcessField.toString()))
+ .append(" = ? where ")
+ ;
+ int iCurr = 0;
+ for(String sCurr : m_saKeys)
+ { if (iCurr++ > 0)
+ sb.append(" and ");
+ sb.append(sCurr).append(" = ?");
+ }
+ return sb.toString();
+ } //________________________________
+
+ /**
+ * Assemble the SQL "select for update" statement
+ * for the "inProcessField" parameter
+ *
+ * in the table row uniquely identified by the list of fields
+ * in the "keyFields" parameter
+ *
+ * @return - The resulting SQL statement
+ */
+ protected String selectForUpdStatement()
+ {
+ StringBuilder sb = new StringBuilder ()
+ .append("select ").append(m_oVals.get(TABLE_ATT.inProcessField.toString()))
+ .append(" from ") .append(m_oVals.get(TABLE_ATT.tableName.toString()))
+ .append(" where ")
+ ;
+ int iCurr = 0;
+ for(String sCurr : m_saKeys)
+ { if (iCurr++ > 0)
+ sb.append(" and ");
+ sb.append(sCurr).append(" = ?");
+ }
+ return sb.append(" for update").toString();
+ } //________________________________
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#close()
+ */
+ @Override
+ protected void close() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#processingError(java.lang.Object, org.jboss.soa.esb.actions.ActionProcessor, java.lang.Throwable)
+ */
+ @Override
+ protected void processingError(Object initialMessage, ActionProcessor processor, Throwable error) {
+ // Mark the row as "error"...
+ ((SQLPollResult)initialMessage).changeStatusToError();
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.listeners.AbstractListener#processingComplete(java.lang.Object)
+ */
+ @Override
+ protected void processingComplete(Object initialMessage) {
+ // Mark the row as "working"...
+ ((SQLPollResult)initialMessage).changeStatusToDone();
+ }
+
+ private class SQLPollResult extends LinkedHashMap implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String sUpdStates;
+
+ private String[] saKeys;
+
+ private String sSel4Upd, sUpdate;
+
+ private SQLPollResult(String sSel4Upd, String sUpdate) throws Exception {
+ this.sSel4Upd = sSel4Upd;
+ this.sUpdate = sUpdate;
+ }
+
+ private String getStatus(ROW_STATE p_oState) {
+ int iPos = p_oState.ordinal();
+ return sUpdStates.substring(iPos, ++iPos);
+ }
+
+ private boolean changeStatusToWorking() {
+ return changeStatus(ROW_STATE.Pending, ROW_STATE.Working);
+ }
+
+ private boolean changeStatusToDone() {
+ return changeStatus(ROW_STATE.Working, ROW_STATE.Done);
+ }
+
+ private boolean changeStatusToError() {
+ return changeStatus(ROW_STATE.Working, ROW_STATE.Error);
+ }
+
+ private boolean changeStatus(ROW_STATE fromState, ROW_STATE toState) {
+ JdbcCleanConn dbConnection = null;
+
+ try {
+ // This is expensive at the moment but will be OK once we get proper connection pooling enabled!
+ dbConnection = newDbConn();
+ } catch (Exception e) {
+ logger.error("Unable to get DB connection.", e);
+ throw new IllegalStateException("Unable to get DB connection.", e);
+ }
+
+ try {
+ PreparedStatement m_PSsel4U;
+ PreparedStatement m_PSupd;
+
+ m_PSsel4U = dbConnection.prepareStatement(sSel4Upd);
+ m_PSupd = dbConnection.prepareStatement(sUpdate);
+
+ int iParm=1;
+ for (String sColName : saKeys) {
+ Object oVal = get(sColName);
+ m_PSsel4U.setObject (iParm ,oVal);
+ // parameters are +1 in update statement
+ // autoincrement leaves things ready for next SQL parameter
+ m_PSupd.setObject (++iParm,oVal);
+ }
+
+ try {
+ ResultSet resultSet = dbConnection.execQueryWait(m_PSsel4U, 5);
+
+ if (resultSet.next()) {
+ String sOldStatus = resultSet.getString(1).substring(0, 1);
+
+ if (sOldStatus.equalsIgnoreCase(getStatus(fromState))) {
+ m_PSupd.setString(1, getStatus(toState));
+ dbConnection.execUpdWait(m_PSupd, 5);
+ dbConnection.commit();
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("Successfully changed row state from " + fromState + " to " + toState + ".");
+ }
+
+ return true;
+ } else {
+ logger.warn("Cannot change row state from " + fromState + " to " + toState + ". Row not in state " + fromState);
+ return false;
+ }
+ }
+ logger.error("Row status change to " + toState + " has failed. Rolling back!!");
+ } catch(Exception e) {
+ logger.error("Row status change to " + toState + " has failed. Rolling back!!", e);
+ }
+
+ try {
+ dbConnection.rollback();
+ } catch (Exception e) {
+ logger.error("Unable to rollback row status change to " + fromState.name(), e);
+ }
+ } catch (Exception e) {
+ logger.error("Unexpected exception.", e);
+ } finally {
+ dbConnection.release();
+ }
+
+ return false;
+ }
+ }
+}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListenerUnitTest.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListenerUnitTest.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListenerUnitTest.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,196 +0,0 @@
-/*
- * 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-2006,
- * @author JBoss Inc.
- */
-
-package org.jboss.soa.esb.listeners;
-
-import org.jboss.soa.esb.actions.ActionDefinition;
-import org.jboss.soa.esb.actions.ActionDefinitionFactory;
-import org.jboss.soa.esb.actions.ActionProcessingException;
-import org.jboss.soa.esb.actions.ActionUtils;
-import org.jboss.soa.esb.actions.BaseTestActionProcessor;
-import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.format.MessageFactory;
-import org.jboss.soa.esb.util.MockNonblockingListener;
-
-import junit.framework.TestCase;
-
-/**
- * AbstractListener tests.
- * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
- */
-public class AbstractListenerUnitTest extends TestCase {
-
- private MockGpListener gpListener;
- private ActionDefinitionFactory factory;
- private DomElement listenerConfig;
- private ActionDefinition action_ActionA;
- private ActionDefinition action_ActionB;
- private ActionDefinition action_ActionC;
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception {
- gpListener = new MockGpListener();
- listenerConfig = new DomElement("listenerConfig");
-
- DomElement config = DomElement.fromInputStream(getClass().getResourceAsStream("AbstractListener_ActionConfig.xml"));
- factory = new ActionDefinitionFactory(config);
- action_ActionA = factory.getInstance("ActionA");
- action_ActionB = factory.getInstance("ActionB");
- action_ActionC = factory.getInstance("ActionC");
- assertNotNull(action_ActionA);
- assertNotNull(action_ActionB);
- assertNotNull(action_ActionC);
- }
-
- public void test_BadActionsConfig() throws Exception {
- // Not action config of any description...
- assertActionsConfigException("message1", "No actions configuration specified either on the listener or as a Message attachement [MESSAGE_PROCESSING_ACTIONS_LIST]. Aborting message processing.");
-
- // Bad actions config as an override attachment - wrong type...
- Message message = MessageFactory.getInstance().getMessage();
- message.getAttachment().put(AbstractListener.MESSAGE_PROCESSING_ACTIONS_LIST, new Long(1));
- assertActionsConfigException(message, "Message attachement [MESSAGE_PROCESSING_ACTIONS_LIST] must be of type java.lang.String. Received [java.lang.Long]. Aborting message processing.");
-
- // Bad actions config as an override attachment - empty...
- message = MessageFactory.getInstance().getMessage();
- message.getAttachment().put(AbstractListener.MESSAGE_PROCESSING_ACTIONS_LIST, " ");
- assertActionsConfigException(message, "Message attachement [MESSAGE_PROCESSING_ACTIONS_LIST] was specified but with an empty value. Aborting message processing.");
-
- // Bad actions config as an override attachment - unknown action...
- listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionX");
- assertActionsConfigException("message1", "Bad Listener Configuration. No 'Actions/Action' definition for action [ActionX].");
- }
-
- public void test_ActionsListenerConfig() throws Exception {
- listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB");
-
- // Run the listener and check that the proper actions were run...
- runListener("message1", null);
- assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
- assertEquals(1, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
- assertEquals(0, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
- }
-
- public void test_ActionsOverrideConfig() throws Exception {
- Message message = MessageFactory.getInstance().getMessage();
-
- // Set the actions on both the listener config and on the message as an attachment...
- listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB");
- message.getAttachment().put(AbstractListener.MESSAGE_PROCESSING_ACTIONS_LIST, "ActionA, ActionC");
- ActionUtils.setTaskObject(message, "message1");
-
- // Run the listener and check that it was the attachment actions config that was used...
- runListener(message, null);
- assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
- assertEquals(0, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
- assertEquals(1, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
- }
-
- public void test_PrematureTermination_By_Exception() throws Exception {
- listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB, ActionC");
-
- ((BaseTestActionProcessor)action_ActionB.getProcessor()).exception = new ActionProcessingException("Premature termination by Exception!");
-
- // Run the listener and check that it failed and raised an appropriate error on the listener...
- runListener("message1", "Premature termination by Exception!");
- assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
- assertEquals(0, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
- assertEquals(0, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
- }
-
- public void test_PrematureTermination_By_Null() throws Exception {
- listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB, ActionC");
-
- ((BaseTestActionProcessor)action_ActionB.getProcessor()).returnNull = true;
-
- // Run the listener and check that it failed and raised an appropriate error on the listener...
- runListener("message1", "Premature termination of action processing pipeline [[ActionA, ActionB, ActionC]]. ActionProcessor [org.jboss.soa.esb.actions.TestActionProcessor1] returned a null message result on processing of action [ActionB].");
- assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
- assertEquals(1, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
- assertEquals(0, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
- }
-
- public void test_Last_Action_Returning_Null_OK() throws Exception {
- listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB, ActionC");
-
- ((BaseTestActionProcessor)action_ActionC.getProcessor()).returnNull = true;
-
- runListener("message1", null);
- assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
- assertEquals(1, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
- assertEquals(1, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
- }
-
- private void assertActionsConfigException(Object message, String expectedException) throws Exception {
- MockNonblockingListener listener = new MockNonblockingListener(gpListener, listenerConfig, factory);
-
- listener.messages = new Object[] {message};
- gpListener.continueLooping = true;
- listener.run();
-
- assertEquals(0, listener.messagesCompleted.size());
- assertEquals(1, listener.messagesInError.size());
- assertEquals(message, listener.messagesInError.get(0).initialMsg);
- assertEquals(null, listener.messagesInError.get(0).processor);
- assertEquals(expectedException, listener.messagesInError.get(0).error.getMessage());
- }
-
- private MockNonblockingListener runListener(Object message, String expectedException) throws Exception {
- MockNonblockingListener listener = new MockNonblockingListener(gpListener, listenerConfig, factory);
-
- listener.messages = new Object[] {message};
- gpListener.continueLooping = true;
- listener.run();
-
- if(expectedException == null) {
- assertEquals(1, listener.messagesCompleted.size());
- assertEquals(0, listener.messagesInError.size());
- assertEquals(message, listener.messagesCompleted.get(0));
- } else {
- assertEquals(0, listener.messagesCompleted.size());
- assertEquals(1, listener.messagesInError.size());
- assertEquals(message, listener.messagesInError.get(0).initialMsg);
- assertEquals(expectedException, listener.messagesInError.get(0).error.getMessage());
- }
-
- return listener;
- }
-
- /**
- * Overriding the GpListener to get control over the continueLooping method.
- * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
- */
- private class MockGpListener extends GpListener {
- private boolean continueLooping = true;
-
- public boolean continueLooping() {
- try {
- return continueLooping;
- } finally {
- continueLooping = false;
- }
- }
- }
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListener_ActionConfig.xml
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListener_ActionConfig.xml 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListener_ActionConfig.xml 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,11 +0,0 @@
- <Actions>
- <Action name="ActionA" processor="Processor1" />
- <Action name="ActionB" processor="Processor2" />
- <Action name="ActionC" processor="Processor3" />
-
- <ProcessorAliases>
- <Alias name="Processor1" class="org.jboss.soa.esb.actions.TestActionProcessor1" />
- <Alias name="Processor2" class="org.jboss.soa.esb.actions.TestActionProcessor1" />
- <Alias name="Processor3" class="org.jboss.soa.esb.actions.TestActionProcessor1" />
- </ProcessorAliases>
- </Actions>
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/DirectoryPollerUnitTest.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/DirectoryPollerUnitTest.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/DirectoryPollerUnitTest.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,57 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY 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 along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.soa.esb.listeners;
-
-import org.jboss.soa.esb.common.tests.BaseTest;
-
-/**
- * Test the DirectoryPoller
- *
- * @author <a href="mailto:arvinder.singh at indigo-logic.com">Arvinder Singh</a>
- * @version <tt>$Revision:$</tt>
- * $Id:$
- */
-public class DirectoryPollerUnitTest extends BaseTest {
-
-
- /**
- * Basic construction test
- * @throws Exception
- */
- public void test_Empty_Construction() throws Exception {
- log.info("Constructing instance of DirectoryPoller");
- // This should fail
- try {
- @SuppressWarnings("unused")
- DirectoryPoller dirPoller = new DirectoryPoller(null,null, null);
- fail("GpListener should fail with empty constructor string");
- } catch (Exception e) {
- }
- }
-
-
-
-
-
-
-
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListener-Config-01.xml
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListener-Config-01.xml 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListener-Config-01.xml 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,31 +0,0 @@
-<EsbConfig
- command-queue-class="org.jboss.internal.soa.esb.command.InMemoryCommandQueue"
- command-queue-name="test-queue"
->
-
- <ListenerConfig
- listenerClass="org.jboss.soa.esb.util.MockPoller"
- actions="String-To-Long, Long-To-Date, Route-To-Nowhere"
- maxThreads="1"
- >
- </ListenerConfig>
-
- <Actions>
- <!--
- Under the new architecture I think these will be equivalent to "Contracts Definitions"?
- -->
- <Action name="String-To-Long" processor="StringToLongConverter" />
- <Action name="Long-To-Date" processor="LongToDateConverter" />
- <Action name="Route-To-Nowhere" processor="ToNowhereRouter" />
-
- <ProcessorAliases>
- <!--
- Under the new architecture I think these will be equivalent to "Services"? The alias "name" being like the Service URN.
- -->
- <Alias name="StringToLongConverter" class="org.jboss.soa.esb.actions.converters.StringToLongConverter" />
- <Alias name="LongToDateConverter" class="org.jboss.soa.esb.actions.converters.LongToDateConverter" />
- <Alias name="ToNowhereRouter" class="org.jboss.soa.esb.actions.ToNowhereRouter" />
- </ProcessorAliases>
- </Actions>
-
-</EsbConfig>
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListenerUnitTest.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListenerUnitTest.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListenerUnitTest.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,91 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY 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 along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.soa.esb.listeners;
-
-import java.util.Date;
-
-import org.jboss.internal.soa.esb.command.InMemoryCommandQueue;
-import org.jboss.soa.esb.actions.ToNowhereRouter;
-import org.jboss.soa.esb.common.tests.BaseTest;
-import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.util.ListenersManagerExecThread;
-import org.jboss.soa.esb.util.MockPoller;
-
-/**
- * Test the GpListener
- *
- * @author <a href="mailto:arvinder.singh at indigo-logic.com">Arvinder Singh</a>
- * @version <tt>$Revision:$</tt>
- * $Id:$
- */
-public class GpListenerUnitTest extends BaseTest {
-
-
- /**
- * Basic construction test
- * @throws Exception
- */
- public void test_Empty_Construction() throws Exception {
- log.info("Constructing instance of GpListener");
- // This should fail
- @SuppressWarnings("unused")
- GpListener gpListener = null;
- try {
- gpListener = new GpListener("");
- fail("GpListener should fail with empty constructor string");
- } catch (Exception e) {
- }
- }
-
-
-
- public void test_newGpListener() throws Exception {
- DomElement config = DomElement.fromInputStream(getClass().getResourceAsStream("GpListener-Config-01.xml"));
- GpListener listenerManager = new GpListener(config);
- ListenersManagerExecThread execThread = new ListenersManagerExecThread(listenerManager);
- long currentTimeInMillis = System.currentTimeMillis();
-
- // Clear the routing processor at the end of the pipeline...
- ToNowhereRouter.objects.clear();
-
- // Start the GpListener command thread...
- execThread.start();
-
- // Stick the current time into the poller as a String...
- MockPoller.addToQueue("" + currentTimeInMillis);
-
- // The message has been pulled from the poller in-queue at this stage because MockPoller.addToQueue blocks.
- // Wait for a few milliseconds to allow the processor pipeline do it's thing...
- Thread.sleep(200);
-
- // Check did the "payload" get processed. The String containing the time should have been processed down the
- // pileline and into a Date object in the ToNowhereRouter (mock routing processor) at the end of the pipeline...
- assertEquals(1, ToNowhereRouter.objects.size());
- Object date = ToNowhereRouter.objects.get(0);
- assertTrue(date instanceof Date);
- assertEquals(new Date(currentTimeInMillis), date);
-
- // Send a shutdown command to the GpListener...
- InMemoryCommandQueue.getQueue("test-queue").addCommand("shutdown");
- execThread.assertShutdownOK(10000);
- }
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,73 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY 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 along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.soa.esb.listeners;
-
-import org.jboss.soa.esb.common.tests.BaseTest;
-
-/**
- * Test the SqlTablePoller
- *
- * @author <a href="mailto:arvinder.singh at indigo-logic.com">Arvinder Singh</a>
- * @version <tt>$Revision:$</tt>
- * $Id:$
- */
-public class SqlTablePollerUnitTest extends BaseTest {
-
- /**
- * Test basic construction.
- * @throws Exception
- */
- public void test_Empty_Construction() throws Exception {
- log.info("Constructing instance of SqlTablePoller");
- // This should fail
- @SuppressWarnings("unused")
- SqlTablePoller sqlPoller = null;
- try {
- sqlPoller = new SqlTablePoller(null, null, null);
- fail("SqlTablePoller should fail with empty constructor string");
- } catch (Exception e) {
- }
- }
-
-
- /*
- public void test_Construction() throws Exception {
-
- DomElement domElement = DomElement.fromInputStream(
- getClass().getResourceAsStream("SqlTablePollerUnitTest.xml"));
-
-
- log.info("Loaded - " + domElement.toXml());
- }
- */
-
-
-
-
-
-
-
-
-
-
-
-}
Deleted: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.xml
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.xml 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.xml 2006-10-20 16:27:02 UTC (rev 6962)
@@ -1,35 +0,0 @@
-<DocumentElementName>
- <ExampleListenChapter
- maxThreads="2"
- listenerClass="org.jboss.soa.esb.listeners.SqlTablePoller"
- actionClass="org.jboss.soa.esb.actions.templates.MockSqlRowAction"
-
- driver-class="org.hsqldb.jdbcDriver"
- connection-url="jdbc:hsqldb:."
- user-name="sa"
- password=""
-
- tableName="test_notif_table"
- selectFields="oid,ref,msg"
- keyFields="oid,ref"
- inProcessField="statusCol"
- whereCondition="src='pepe'"
- orderBy="oid desc"
- >
- <NotificationList type="OK">
- <target class="NotifyFiles">
- <file URI="file:///tmp/jbossEsb/notifyDir/ListenOnNotifTable.notifOK"
- append="true"
- />
- </target>
- </NotificationList>
-
- <NotificationList type="err">
- <target class="NotifyFiles">
- <file URI="file:///tmp/jbossEsb/notifyDir/ListenOnNotifTable.notifErr"
- append="true"
- />
- </target>
- </NotificationList>
- </ExampleListenChapter>
-</DocumentElementName>
\ No newline at end of file
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/AbstractListenerUnitTest.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListenerUnitTest.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListenerUnitTest.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/AbstractListenerUnitTest.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,198 @@
+/*
+ * 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-2006,
+ * @author JBoss Inc.
+ */
+
+package org.jboss.soa.esb.listeners.old;
+
+import org.jboss.soa.esb.actions.ActionDefinition;
+import org.jboss.soa.esb.actions.ActionDefinitionFactory;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.actions.ActionUtils;
+import org.jboss.soa.esb.actions.BaseTestActionProcessor;
+import org.jboss.soa.esb.helpers.DomElement;
+import org.jboss.soa.esb.listeners.old.AbstractListener;
+import org.jboss.soa.esb.listeners.old.GpListener;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.util.MockNonblockingListener;
+
+import junit.framework.TestCase;
+
+/**
+ * AbstractListener tests.
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class AbstractListenerUnitTest extends TestCase {
+
+ private MockGpListener gpListener;
+ private ActionDefinitionFactory factory;
+ private DomElement listenerConfig;
+ private ActionDefinition action_ActionA;
+ private ActionDefinition action_ActionB;
+ private ActionDefinition action_ActionC;
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ gpListener = new MockGpListener();
+ listenerConfig = new DomElement("listenerConfig");
+
+ DomElement config = DomElement.fromInputStream(getClass().getResourceAsStream("AbstractListener_ActionConfig.xml"));
+ factory = new ActionDefinitionFactory(config);
+ action_ActionA = factory.getInstance("ActionA");
+ action_ActionB = factory.getInstance("ActionB");
+ action_ActionC = factory.getInstance("ActionC");
+ assertNotNull(action_ActionA);
+ assertNotNull(action_ActionB);
+ assertNotNull(action_ActionC);
+ }
+
+ public void test_BadActionsConfig() throws Exception {
+ // Not action config of any description...
+ assertActionsConfigException("message1", "No actions configuration specified either on the listener or as a Message attachement [MESSAGE_PROCESSING_ACTIONS_LIST]. Aborting message processing.");
+
+ // Bad actions config as an override attachment - wrong type...
+ Message message = MessageFactory.getInstance().getMessage();
+ message.getAttachment().put(AbstractListener.MESSAGE_PROCESSING_ACTIONS_LIST, new Long(1));
+ assertActionsConfigException(message, "Message attachement [MESSAGE_PROCESSING_ACTIONS_LIST] must be of type java.lang.String. Received [java.lang.Long]. Aborting message processing.");
+
+ // Bad actions config as an override attachment - empty...
+ message = MessageFactory.getInstance().getMessage();
+ message.getAttachment().put(AbstractListener.MESSAGE_PROCESSING_ACTIONS_LIST, " ");
+ assertActionsConfigException(message, "Message attachement [MESSAGE_PROCESSING_ACTIONS_LIST] was specified but with an empty value. Aborting message processing.");
+
+ // Bad actions config as an override attachment - unknown action...
+ listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionX");
+ assertActionsConfigException("message1", "Bad Listener Configuration. No 'Actions/Action' definition for action [ActionX].");
+ }
+
+ public void test_ActionsListenerConfig() throws Exception {
+ listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB");
+
+ // Run the listener and check that the proper actions were run...
+ runListener("message1", null);
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
+ assertEquals(0, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
+ }
+
+ public void test_ActionsOverrideConfig() throws Exception {
+ Message message = MessageFactory.getInstance().getMessage();
+
+ // Set the actions on both the listener config and on the message as an attachment...
+ listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB");
+ message.getAttachment().put(AbstractListener.MESSAGE_PROCESSING_ACTIONS_LIST, "ActionA, ActionC");
+ ActionUtils.setTaskObject(message, "message1");
+
+ // Run the listener and check that it was the attachment actions config that was used...
+ runListener(message, null);
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
+ assertEquals(0, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
+ }
+
+ public void test_PrematureTermination_By_Exception() throws Exception {
+ listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB, ActionC");
+
+ ((BaseTestActionProcessor)action_ActionB.getProcessor()).exception = new ActionProcessingException("Premature termination by Exception!");
+
+ // Run the listener and check that it failed and raised an appropriate error on the listener...
+ runListener("message1", "Premature termination by Exception!");
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
+ assertEquals(0, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
+ assertEquals(0, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
+ }
+
+ public void test_PrematureTermination_By_Null() throws Exception {
+ listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB, ActionC");
+
+ ((BaseTestActionProcessor)action_ActionB.getProcessor()).returnNull = true;
+
+ // Run the listener and check that it failed and raised an appropriate error on the listener...
+ runListener("message1", "Premature termination of action processing pipeline [[ActionA, ActionB, ActionC]]. ActionProcessor [org.jboss.soa.esb.actions.TestActionProcessor1] returned a null message result on processing of action [ActionB].");
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
+ assertEquals(0, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
+ }
+
+ public void test_Last_Action_Returning_Null_OK() throws Exception {
+ listenerConfig.setAttr(GpListener.PARM_ACTIONS, "ActionA, ActionB, ActionC");
+
+ ((BaseTestActionProcessor)action_ActionC.getProcessor()).returnNull = true;
+
+ runListener("message1", null);
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionA.getProcessor()).processedMessages.size());
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionB.getProcessor()).processedMessages.size());
+ assertEquals(1, ((BaseTestActionProcessor)action_ActionC.getProcessor()).processedMessages.size());
+ }
+
+ private void assertActionsConfigException(Object message, String expectedException) throws Exception {
+ MockNonblockingListener listener = new MockNonblockingListener(gpListener, listenerConfig, factory);
+
+ listener.messages = new Object[] {message};
+ gpListener.continueLooping = true;
+ listener.run();
+
+ assertEquals(0, listener.messagesCompleted.size());
+ assertEquals(1, listener.messagesInError.size());
+ assertEquals(message, listener.messagesInError.get(0).initialMsg);
+ assertEquals(null, listener.messagesInError.get(0).processor);
+ assertEquals(expectedException, listener.messagesInError.get(0).error.getMessage());
+ }
+
+ private MockNonblockingListener runListener(Object message, String expectedException) throws Exception {
+ MockNonblockingListener listener = new MockNonblockingListener(gpListener, listenerConfig, factory);
+
+ listener.messages = new Object[] {message};
+ gpListener.continueLooping = true;
+ listener.run();
+
+ if(expectedException == null) {
+ assertEquals(1, listener.messagesCompleted.size());
+ assertEquals(0, listener.messagesInError.size());
+ assertEquals(message, listener.messagesCompleted.get(0));
+ } else {
+ assertEquals(0, listener.messagesCompleted.size());
+ assertEquals(1, listener.messagesInError.size());
+ assertEquals(message, listener.messagesInError.get(0).initialMsg);
+ assertEquals(expectedException, listener.messagesInError.get(0).error.getMessage());
+ }
+
+ return listener;
+ }
+
+ /**
+ * Overriding the GpListener to get control over the continueLooping method.
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+ private class MockGpListener extends GpListener {
+ private boolean continueLooping = true;
+
+ public boolean continueLooping() {
+ try {
+ return continueLooping;
+ } finally {
+ continueLooping = false;
+ }
+ }
+ }
+}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/AbstractListener_ActionConfig.xml (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/AbstractListener_ActionConfig.xml)
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/DirectoryPollerUnitTest.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/DirectoryPollerUnitTest.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/DirectoryPollerUnitTest.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/DirectoryPollerUnitTest.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,58 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY 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 along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.soa.esb.listeners.old;
+
+import org.jboss.soa.esb.common.tests.BaseTest;
+import org.jboss.soa.esb.listeners.old.DirectoryPoller;
+
+/**
+ * Test the DirectoryPoller
+ *
+ * @author <a href="mailto:arvinder.singh at indigo-logic.com">Arvinder Singh</a>
+ * @version <tt>$Revision:$</tt>
+ * $Id:$
+ */
+public class DirectoryPollerUnitTest extends BaseTest {
+
+
+ /**
+ * Basic construction test
+ * @throws Exception
+ */
+ public void test_Empty_Construction() throws Exception {
+ log.info("Constructing instance of DirectoryPoller");
+ // This should fail
+ try {
+ @SuppressWarnings("unused")
+ DirectoryPoller dirPoller = new DirectoryPoller(null,null, null);
+ fail("GpListener should fail with empty constructor string");
+ } catch (Exception e) {
+ }
+ }
+
+
+
+
+
+
+
+}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/GpListener-Config-01.xml (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListener-Config-01.xml)
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/GpListenerUnitTest.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListenerUnitTest.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/GpListenerUnitTest.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/GpListenerUnitTest.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,92 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY 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 along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.soa.esb.listeners.old;
+
+import java.util.Date;
+
+import org.jboss.internal.soa.esb.command.InMemoryCommandQueue;
+import org.jboss.soa.esb.actions.ToNowhereRouter;
+import org.jboss.soa.esb.common.tests.BaseTest;
+import org.jboss.soa.esb.helpers.DomElement;
+import org.jboss.soa.esb.listeners.old.GpListener;
+import org.jboss.soa.esb.util.ListenersManagerExecThread;
+import org.jboss.soa.esb.util.MockPoller;
+
+/**
+ * Test the GpListener
+ *
+ * @author <a href="mailto:arvinder.singh at indigo-logic.com">Arvinder Singh</a>
+ * @version <tt>$Revision:$</tt>
+ * $Id:$
+ */
+public class GpListenerUnitTest extends BaseTest {
+
+
+ /**
+ * Basic construction test
+ * @throws Exception
+ */
+ public void test_Empty_Construction() throws Exception {
+ log.info("Constructing instance of GpListener");
+ // This should fail
+ @SuppressWarnings("unused")
+ GpListener gpListener = null;
+ try {
+ gpListener = new GpListener("");
+ fail("GpListener should fail with empty constructor string");
+ } catch (Exception e) {
+ }
+ }
+
+
+
+ public void test_newGpListener() throws Exception {
+ DomElement config = DomElement.fromInputStream(getClass().getResourceAsStream("GpListener-Config-01.xml"));
+ GpListener listenerManager = new GpListener(config);
+ ListenersManagerExecThread execThread = new ListenersManagerExecThread(listenerManager);
+ long currentTimeInMillis = System.currentTimeMillis();
+
+ // Clear the routing processor at the end of the pipeline...
+ ToNowhereRouter.objects.clear();
+
+ // Start the GpListener command thread...
+ execThread.start();
+
+ // Stick the current time into the poller as a String...
+ MockPoller.addToQueue("" + currentTimeInMillis);
+
+ // The message has been pulled from the poller in-queue at this stage because MockPoller.addToQueue blocks.
+ // Wait for a few milliseconds to allow the processor pipeline do it's thing...
+ Thread.sleep(200);
+
+ // Check did the "payload" get processed. The String containing the time should have been processed down the
+ // pileline and into a Date object in the ToNowhereRouter (mock routing processor) at the end of the pipeline...
+ assertEquals(1, ToNowhereRouter.objects.size());
+ Object date = ToNowhereRouter.objects.get(0);
+ assertTrue(date instanceof Date);
+ assertEquals(new Date(currentTimeInMillis), date);
+
+ // Send a shutdown command to the GpListener...
+ InMemoryCommandQueue.getQueue("test-queue").addCommand("shutdown");
+ execThread.assertShutdownOK(10000);
+ }
+}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/SqlTablePollerUnitTest.java (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.java)
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.java 2006-10-19 12:58:18 UTC (rev 6909)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/SqlTablePollerUnitTest.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -0,0 +1,74 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY 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 along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.soa.esb.listeners.old;
+
+import org.jboss.soa.esb.common.tests.BaseTest;
+import org.jboss.soa.esb.listeners.old.SqlTablePoller;
+
+/**
+ * Test the SqlTablePoller
+ *
+ * @author <a href="mailto:arvinder.singh at indigo-logic.com">Arvinder Singh</a>
+ * @version <tt>$Revision:$</tt>
+ * $Id:$
+ */
+public class SqlTablePollerUnitTest extends BaseTest {
+
+ /**
+ * Test basic construction.
+ * @throws Exception
+ */
+ public void test_Empty_Construction() throws Exception {
+ log.info("Constructing instance of SqlTablePoller");
+ // This should fail
+ @SuppressWarnings("unused")
+ SqlTablePoller sqlPoller = null;
+ try {
+ sqlPoller = new SqlTablePoller(null, null, null);
+ fail("SqlTablePoller should fail with empty constructor string");
+ } catch (Exception e) {
+ }
+ }
+
+
+ /*
+ public void test_Construction() throws Exception {
+
+ DomElement domElement = DomElement.fromInputStream(
+ getClass().getResourceAsStream("SqlTablePollerUnitTest.xml"));
+
+
+ log.info("Loaded - " + domElement.toXml());
+ }
+ */
+
+
+
+
+
+
+
+
+
+
+
+}
Copied: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/old/SqlTablePollerUnitTest.xml (from rev 6909, labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/listeners/SqlTablePollerUnitTest.xml)
Modified: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/AbstractMockListner.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/AbstractMockListner.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/AbstractMockListner.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -28,8 +28,8 @@
import org.jboss.soa.esb.actions.ActionDefinitionFactory;
import org.jboss.soa.esb.actions.ActionProcessor;
import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.listeners.AbstractListener;
-import org.jboss.soa.esb.listeners.GpListener;
+import org.jboss.soa.esb.listeners.old.AbstractListener;
+import org.jboss.soa.esb.listeners.old.GpListener;
/**
* Abstract Mock Listener implementation.
Modified: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/ListenersManagerExecThread.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/ListenersManagerExecThread.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/ListenersManagerExecThread.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -3,7 +3,7 @@
import junit.framework.TestCase;
import org.apache.log4j.Logger;
-import org.jboss.soa.esb.listeners.GpListener;
+import org.jboss.soa.esb.listeners.old.GpListener;
public class ListenersManagerExecThread extends Thread {
Modified: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/MockNonblockingListener.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/MockNonblockingListener.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/MockNonblockingListener.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -23,7 +23,7 @@
import org.jboss.soa.esb.actions.ActionDefinitionFactory;
import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.listeners.GpListener;
+import org.jboss.soa.esb.listeners.old.GpListener;
/**
* Non blocking mock Listener implementation.
Modified: labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/MockPoller.java
===================================================================
--- labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/MockPoller.java 2006-10-20 16:15:45 UTC (rev 6961)
+++ labs/jbossesb/workspace/eschifman/trunk/product/core/listeners/tests/src/org/jboss/soa/esb/util/MockPoller.java 2006-10-20 16:27:02 UTC (rev 6962)
@@ -9,11 +9,11 @@
import org.jboss.soa.esb.actions.ActionDefinitionFactory;
import org.jboss.soa.esb.actions.ActionProcessor;
import org.jboss.soa.esb.helpers.DomElement;
-import org.jboss.soa.esb.listeners.AbstractPoller;
-import org.jboss.soa.esb.listeners.GpListener;
+import org.jboss.soa.esb.listeners.old.AbstractPoller;
+import org.jboss.soa.esb.listeners.old.GpListener;
/**
- * Simple Mock {@link org.jboss.soa.esb.listeners.AbstractPoller} implementation that can be used for testing.
+ * Simple Mock {@link org.jboss.soa.esb.listeners.old.AbstractPoller} implementation that can be used for testing.
* <p/>
* Maintains a static in-memory queue into which objects can be dropped for processing by the configured action handler.
* @author tfennelly
More information about the jboss-svn-commits
mailing list