[jboss-cvs] JBoss Messaging SVN: r6299 - in trunk: src/main/org/jboss/messaging/core/server/cluster and 6 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Apr 3 10:12:53 EDT 2009


Author: timfox
Date: 2009-04-03 10:12:53 -0400 (Fri, 03 Apr 2009)
New Revision: 6299

Added:
   trunk/src/main/org/jboss/messaging/jms/bridge/JMSBridge.java
   trunk/src/main/org/jboss/messaging/jms/bridge/impl/JMSBridgeImpl.java
   trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java
   trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/JMSBridgeTest.java
   trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/JMSBridgeImplTest.java
Removed:
   trunk/src/main/org/jboss/messaging/jms/bridge/Bridge.java
   trunk/src/main/org/jboss/messaging/jms/bridge/impl/BridgeImpl.java
   trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeReconnectionTest.java
   trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeTest.java
   trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/BridgeImplTest.java
Modified:
   trunk/src/main/org/jboss/messaging/core/management/ObjectNames.java
   trunk/src/main/org/jboss/messaging/core/server/cluster/Bridge.java
   trunk/src/main/org/jboss/messaging/core/server/cluster/impl/BridgeImpl.java
   trunk/src/main/org/jboss/messaging/jms/bridge/BridgeService.java
   trunk/tests/src/org/jboss/messaging/tests/integration/cluster/bridge/BridgeStartTest.java
   trunk/tests/src/org/jboss/messaging/tests/integration/cluster/bridge/BridgeTest.java
Log:
renamed JMS bridge to JMSBridge

Modified: trunk/src/main/org/jboss/messaging/core/management/ObjectNames.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/management/ObjectNames.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/src/main/org/jboss/messaging/core/management/ObjectNames.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -93,7 +93,7 @@
 
    public static ObjectName getBridgeObjectName(final String name) throws Exception
    {
-      return createObjectName(CORE_MODULE, "Bridge", name);
+      return createObjectName(CORE_MODULE, "JMSBridge", name);
    }
    
    public static ObjectName getClusterConnectionObjectName(String name) throws Exception

Modified: trunk/src/main/org/jboss/messaging/core/server/cluster/Bridge.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/cluster/Bridge.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/src/main/org/jboss/messaging/core/server/cluster/Bridge.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -30,7 +30,7 @@
 
 
 /**
- * A Bridge
+ * A JMSBridge
  *
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * 

Modified: trunk/src/main/org/jboss/messaging/core/server/cluster/impl/BridgeImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/server/cluster/impl/BridgeImpl.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/src/main/org/jboss/messaging/core/server/cluster/impl/BridgeImpl.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -86,7 +86,7 @@
 import org.jboss.messaging.utils.UUID;
 
 /**
- * A BridgeImpl
+ * A JMSBridgeImpl
  *
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * 
@@ -709,7 +709,7 @@
       }
       catch (Exception e)
       {
-         log.warn("Unable to connect. Bridge is now disabled.", e);
+         log.warn("Unable to connect. JMSBridge is now disabled.", e);
 
          return false;
       }

Deleted: trunk/src/main/org/jboss/messaging/jms/bridge/Bridge.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/bridge/Bridge.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/src/main/org/jboss/messaging/jms/bridge/Bridge.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -1,111 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * 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.messaging.jms.bridge;
-
-import javax.transaction.TransactionManager;
-
-import org.jboss.messaging.core.server.MessagingComponent;
-
-/**
- * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
- * 
- * @version <tt>$Revision$</tt>
- * 
- */
-public interface Bridge extends MessagingComponent
-{
-   void pause() throws Exception;
-
-   void resume() throws Exception;
-
-   DestinationFactory getSourceDestinationFactory();
-
-   void setSourceDestinationFactory(DestinationFactory dest);
-
-   DestinationFactory getTargetDestinationFactory();
-
-   void setTargetDestinationFactory(DestinationFactory dest);
-
-   String getSourceUsername();
-
-   void setSourceUsername(String name);
-
-   String getSourcePassword();
-
-   void setSourcePassword(String pwd);
-
-   String getTargetUsername();
-
-   void setTargetUsername(String name);
-
-   String getTargetPassword();
-
-   void setTargetPassword(String pwd);
-
-   String getSelector();
-
-   void setSelector(String selector);
-
-   long getFailureRetryInterval();
-
-   void setFailureRetryInterval(long interval);
-
-   int getMaxRetries();
-
-   void setMaxRetries(int retries);
-
-   QualityOfServiceMode getQualityOfServiceMode();
-
-   void setQualityOfServiceMode(QualityOfServiceMode mode);
-
-   int getMaxBatchSize();
-
-   void setMaxBatchSize(int size);
-
-   long getMaxBatchTime();
-
-   void setMaxBatchTime(long time);
-
-   String getSubscriptionName();
-
-   void setSubscriptionName(String subname);
-
-   String getClientID();
-
-   void setClientID(String clientID);
-
-   boolean isAddMessageIDInHeader();
-
-   void setAddMessageIDInHeader(boolean value);
-
-   boolean isPaused();
-
-   boolean isFailed();
-
-   void setSourceConnectionFactoryFactory(ConnectionFactoryFactory cff);
-
-   void setTargetConnectionFactoryFactory(ConnectionFactoryFactory cff);
-
-   void setTransactionManager(TransactionManager tm);
-
-}
\ No newline at end of file

Modified: trunk/src/main/org/jboss/messaging/jms/bridge/BridgeService.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/bridge/BridgeService.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/src/main/org/jboss/messaging/jms/bridge/BridgeService.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -26,7 +26,7 @@
 
 import org.jboss.messaging.core.logging.Logger;
 import org.jboss.messaging.core.server.MessagingComponent;
-import org.jboss.messaging.jms.bridge.impl.BridgeImpl;
+import org.jboss.messaging.jms.bridge.impl.JMSBridgeImpl;
 
 /**
  * A BridgeService
@@ -40,7 +40,7 @@
 public class BridgeService implements BridgeMBean
 {
    private static final Logger log = Logger.getLogger(BridgeService.class);
-   private Bridge bridge;
+   private JMSBridge bridge;
    
    private String sourceDestinationLookup;
    
@@ -53,7 +53,7 @@
       
    public BridgeService()
    {
-      bridge = new BridgeImpl();
+      bridge = new JMSBridgeImpl();
    }
    
    // JMX attributes ----------------------------------------------------------------

Copied: trunk/src/main/org/jboss/messaging/jms/bridge/JMSBridge.java (from rev 6295, trunk/src/main/org/jboss/messaging/jms/bridge/Bridge.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/bridge/JMSBridge.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/jms/bridge/JMSBridge.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -0,0 +1,113 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.messaging.jms.bridge;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.messaging.core.server.MessagingComponent;
+
+/**
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
+ * 
+ * @version <tt>$Revision$</tt>
+ * 
+ */
+public interface JMSBridge extends MessagingComponent
+{
+   void pause() throws Exception;
+
+   void resume() throws Exception;
+
+   DestinationFactory getSourceDestinationFactory();
+
+   void setSourceDestinationFactory(DestinationFactory dest);
+
+   DestinationFactory getTargetDestinationFactory();
+
+   void setTargetDestinationFactory(DestinationFactory dest);
+
+   String getSourceUsername();
+
+   void setSourceUsername(String name);
+
+   String getSourcePassword();
+
+   void setSourcePassword(String pwd);
+
+   String getTargetUsername();
+
+   void setTargetUsername(String name);
+
+   String getTargetPassword();
+
+   void setTargetPassword(String pwd);
+
+   String getSelector();
+
+   void setSelector(String selector);
+
+   long getFailureRetryInterval();
+
+   void setFailureRetryInterval(long interval);
+
+   int getMaxRetries();
+
+   void setMaxRetries(int retries);
+
+   QualityOfServiceMode getQualityOfServiceMode();
+
+   void setQualityOfServiceMode(QualityOfServiceMode mode);
+
+   int getMaxBatchSize();
+
+   void setMaxBatchSize(int size);
+
+   long getMaxBatchTime();
+
+   void setMaxBatchTime(long time);
+
+   String getSubscriptionName();
+
+   void setSubscriptionName(String subname);
+
+   String getClientID();
+
+   void setClientID(String clientID);
+
+   boolean isAddMessageIDInHeader();
+
+   void setAddMessageIDInHeader(boolean value);
+
+   boolean isPaused();
+
+   boolean isFailed();
+
+   void setSourceConnectionFactoryFactory(ConnectionFactoryFactory cff);
+
+   void setTargetConnectionFactoryFactory(ConnectionFactoryFactory cff);
+
+   void setTransactionManager(TransactionManager tm);
+
+}
\ No newline at end of file

Deleted: trunk/src/main/org/jboss/messaging/jms/bridge/impl/BridgeImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/bridge/impl/BridgeImpl.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/src/main/org/jboss/messaging/jms/bridge/impl/BridgeImpl.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -1,1602 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
- * 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.messaging.jms.bridge.impl;
-
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.Topic;
-import javax.jms.XAConnection;
-import javax.jms.XAConnectionFactory;
-import javax.jms.XASession;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.xa.XAResource;
-
-import org.jboss.messaging.core.client.ClientSession;
-import org.jboss.messaging.core.logging.Logger;
-import org.jboss.messaging.core.server.MessagingComponent;
-import org.jboss.messaging.jms.bridge.Bridge;
-import org.jboss.messaging.jms.bridge.ConnectionFactoryFactory;
-import org.jboss.messaging.jms.bridge.DestinationFactory;
-import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
-import org.jboss.messaging.jms.client.JBossMessage;
-import org.jboss.messaging.jms.client.JBossSession;
-import org.jboss.tm.TransactionManagerLocator;
-
-/**
- * 
- * A Bridge
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision:4566 $</tt>
- *
- * $Id:Bridge.java 4566 2008-06-24 08:01:35Z jmesnil $
- *
- */
-public class BridgeImpl implements MessagingComponent, Bridge
-{
-   private static final Logger log;
-   
-   private static boolean trace;
-   
-   static
-   {
-      log = Logger.getLogger(BridgeImpl.class);
-      
-      trace = log.isTraceEnabled();
-   }
-
-   private static final int TEN_YEARS = 60 * 60 * 24 * 365 * 10; // in ms
-
-   private final Object lock = new Object();
-   
-   private String sourceUsername;
-   
-   private String sourcePassword;
-   
-   private String targetUsername;
-   
-   private String targetPassword;
-   
-   private TransactionManager tm;
-   
-   private String selector;
-   
-   private long failureRetryInterval;
-   
-   private int maxRetries;
-   
-   private QualityOfServiceMode qualityOfServiceMode;
-   
-   private int maxBatchSize;
-   
-   private long maxBatchTime;
-   
-   private String subName;
-   
-   private String clientID;
-   
-   private volatile boolean addMessageIDInHeader;
-   
-   private boolean started;
-   
-   private LinkedList<Message> messages;
-   
-   private ConnectionFactoryFactory sourceCff;
-   
-   private ConnectionFactoryFactory targetCff;
-   
-   private DestinationFactory sourceDestinationFactory;
-   
-   private DestinationFactory targetDestinationFactory;
-   
-   private Connection sourceConn; 
-   
-   private Connection targetConn;
-   
-   private Destination sourceDestination;
-   
-   private Destination targetDestination;
-   
-   private Session sourceSession;
-   
-   private Session targetSession;
-   
-   private MessageConsumer sourceConsumer;
-   
-   private MessageProducer targetProducer;
-        
-   private BatchTimeChecker timeChecker;
-   
-   private Thread checkerThread;
-   
-   private long batchExpiryTime;
-   
-   private boolean paused;         
-   
-   private Transaction tx;  
-   
-   private boolean failed;
-   
-   private int forwardMode;
-   
-   private static final int FORWARD_MODE_XA = 0;
-   
-   private static final int FORWARD_MODE_LOCALTX = 1;
-   
-   private static final int FORWARD_MODE_NONTX = 2;
-   
-   /*
-    * Constructor for MBean
-    */
-   public BridgeImpl()
-   {      
-      this.messages = new LinkedList<Message>();      
-   }
-   
-   public BridgeImpl(ConnectionFactoryFactory sourceCff, ConnectionFactoryFactory targetCff,
-                 DestinationFactory sourceDestinationFactory, DestinationFactory targetDestinationFactory,         
-                 String sourceUsername, String sourcePassword,
-                 String targetUsername, String targetPassword,
-                 String selector, long failureRetryInterval,
-                 int maxRetries,
-                 QualityOfServiceMode qosMode,
-                 int maxBatchSize, long maxBatchTime,
-                 String subName, String clientID,
-                 boolean addMessageIDInHeader)
-   {            
-      this();
-      
-      this.sourceCff = sourceCff;
-      
-      this.targetCff = targetCff;
-      
-      this.sourceDestinationFactory = sourceDestinationFactory;
-      
-      this.targetDestinationFactory = targetDestinationFactory;
-      
-      this.sourceUsername = sourceUsername;
-      
-      this.sourcePassword = sourcePassword;
-      
-      this.targetUsername = targetUsername;
-      
-      this.targetPassword = targetPassword;
-      
-      this.selector = selector;
-      
-      this.failureRetryInterval = failureRetryInterval;
-      
-      this.maxRetries = maxRetries;
-      
-      this.qualityOfServiceMode = qosMode;
-      
-      this.maxBatchSize = maxBatchSize;
-      
-      this.maxBatchTime = maxBatchTime;
-      
-      this.subName = subName;
-      
-      this.clientID = clientID;
-      
-      this.addMessageIDInHeader = addMessageIDInHeader;
-              
-      checkParams();
-      
-      if (trace)
-      {
-         log.trace("Created " + this);
-      }
-   }
-         
-   // MessagingComponent overrides --------------------------------------------------
-        
-   public synchronized void start() throws Exception
-   {      
-      if (started)
-      {
-         log.warn("Attempt to start, but is already started");
-         return;
-      }
-      
-      if (trace) { log.trace("Starting " + this); }         
-      
-      checkParams();
-      
-      TransactionManager tm = getTm();
-      
-      //There may already be a JTA transaction associated to the thread
-      
-      boolean ok;
-      
-      Transaction toResume = null;
-      try
-      {
-         toResume = tm.suspend();
-         
-         ok = setupJMSObjects();
-      }
-      finally
-      {
-         if (toResume != null)
-         {
-            tm.resume(toResume);
-         }
-      }
-      
-      if (ok)
-      {         
-         //start the source connection
-         
-         sourceConn.start();
-         
-         started = true;
-         
-         if (maxBatchTime != -1)
-         {
-            if (trace) { log.trace("Starting time checker thread"); }
-                     
-            timeChecker = new BatchTimeChecker();
-            
-            checkerThread = new Thread(timeChecker);
-            
-            batchExpiryTime = System.currentTimeMillis() + maxBatchTime;
-            
-            checkerThread.start();
-            
-            if (trace) { log.trace("Started time checker thread"); }
-         }            
-         
-         if (trace) { log.trace("Started " + this); }
-      }
-      else
-      {
-         log.warn("Failed to start bridge");
-         handleFailureOnStartup();
-      }
-   }
-   
-   public synchronized void stop() throws Exception
-   {
-      if (!started)
-      {
-         log.warn("Attempt to stop, but is already stopped");
-         return;
-      }
-      
-      if (trace) { log.trace("Stopping " + this); }
-      
-      synchronized (lock)
-      {
-         started = false;          
-         
-         //This must be inside sync block
-         if (checkerThread != null)
-         {
-            checkerThread.interrupt();
-         }
-      }
-            
-      //This must be outside sync block
-      if (checkerThread != null)
-      {  
-         if (trace) { log.trace("Waiting for checker thread to finish");}
-         
-         checkerThread.join();
-         
-         if (trace) { log.trace("Checker thread has finished"); }
-      }
-      
-      if (tx != null)
-      {
-         //Terminate any transaction
-         if (trace) { log.trace("Rolling back remaining tx"); }
-         
-         try
-         {
-            tx.rollback();
-         }
-         catch (Exception ignore)
-         {
-            if (trace) { log.trace("Failed to rollback", ignore); }
-         }
-         
-         if (trace) { log.trace("Rolled back remaining tx"); }
-      }
-      
-      try
-      {
-         sourceConn.close();
-      }
-      catch (Exception ignore)
-      {
-         if (trace) { log.trace("Failed to close source conn", ignore); }
-      }
-      
-      if (targetConn != null)
-      {
-         try
-         {
-            targetConn.close();
-         }
-         catch (Exception ignore)
-         {
-            if (trace) { log.trace("Failed to close target conn", ignore); }
-         }
-      }
-            
-      if (trace) { log.trace("Stopped " + this); }
-   }
-   
-   public synchronized boolean isStarted()
-   {
-      return started;
-   }
-
-   // Bridge implementation ------------------------------------------------------------
-
-   public synchronized void pause() throws Exception
-   {
-      if (trace) { log.trace("Pausing " + this); }
-      
-      synchronized (lock)
-      {
-         paused = true;
-         
-         sourceConn.stop();
-      }
-      
-      if (trace) { log.trace("Paused " + this); }
-   }
-   
-   public synchronized void resume() throws Exception
-   {
-      if (trace) { log.trace("Resuming " + this); }
-      
-      synchronized (lock)
-      {
-         paused = false;
-         
-         sourceConn.start();
-      }
-      
-      if (trace) { log.trace("Resumed " + this); }
-   }
-      
-   public DestinationFactory getSourceDestinationFactory()
-   {
-   	return sourceDestinationFactory;
-   }
-
-   public void setSourceDestinationFactory(DestinationFactory dest)
-   {
-      checkBridgeNotStarted();
-   	checkNotNull(dest, "TargetDestinationFactory");
-   	
-   	sourceDestinationFactory = dest;
-   }
-   
-   public DestinationFactory getTargetDestinationFactory()
-   {
-   	return targetDestinationFactory;
-   }
-
-   public void setTargetDestinationFactory(DestinationFactory dest)
-   {
-      checkBridgeNotStarted();
-      checkNotNull(dest, "TargetDestinationFactory");
-      
-   	targetDestinationFactory = dest;
-   }
-   
-   public String getSourceUsername()
-   {
-      return sourceUsername;
-   }
-   
-   public synchronized void setSourceUsername(String name)
-   {
-      checkBridgeNotStarted();
-      
-      sourceUsername = name;
-   }
-   
-   public synchronized String getSourcePassword()
-   {
-      return sourcePassword;
-   }
-   
-   public synchronized void setSourcePassword(String pwd)
-   {
-      checkBridgeNotStarted();
-      
-      sourcePassword = pwd;
-   }
-      
-   public synchronized String getTargetUsername()
-   {
-      return targetUsername;
-   }
-   
-   public synchronized void setTargetUsername(String name)
-   {
-      checkBridgeNotStarted();
-      
-      this.targetUsername = name;
-   }
-   
-   public synchronized String getTargetPassword()
-   {
-      return this.targetPassword;
-   }
-   
-   public synchronized void setTargetPassword(String pwd)
-   {
-      checkBridgeNotStarted();
-      
-      this.targetPassword = pwd;
-   }
-
-   public synchronized String getSelector()
-   {
-      return selector;
-   }
-   
-   public synchronized void setSelector(String selector)
-   {
-      checkBridgeNotStarted();
-      
-      this.selector = selector;
-   }
-   
-   public synchronized long getFailureRetryInterval()
-   {
-      return failureRetryInterval;
-   }
-   
-   public synchronized void setFailureRetryInterval(long interval)
-   {
-      checkBridgeNotStarted();
-      checkValidValue(interval, "FailureRetryInterval");
-      
-      this.failureRetryInterval = interval;
-   }  
-   
-   public synchronized int getMaxRetries()
-   {
-      return maxRetries;
-   }
-   
-   public synchronized void setMaxRetries(int retries)
-   {
-      checkBridgeNotStarted();
-      checkValidValue(retries, "MaxRetries");
-      
-      this.maxRetries = retries;
-   }
-      
-   public synchronized QualityOfServiceMode getQualityOfServiceMode()
-   {
-      return qualityOfServiceMode;
-   }
-   
-   public synchronized void setQualityOfServiceMode(QualityOfServiceMode mode)
-   {
-      checkBridgeNotStarted();
-      checkNotNull(mode, "QualityOfServiceMode");
-      
-      qualityOfServiceMode = mode;
-   }   
-   
-   public synchronized int getMaxBatchSize()
-   {
-      return maxBatchSize;
-   }
-   
-   public synchronized void setMaxBatchSize(int size)
-   {
-      checkBridgeNotStarted();
-      checkMaxBatchSize(size);
-      
-      maxBatchSize = size;
-   }
-   
-   public synchronized long getMaxBatchTime()
-   {
-      return maxBatchTime;
-   }
-   
-   public synchronized void setMaxBatchTime(long time)
-   {
-      checkBridgeNotStarted();
-      checkValidValue(time, "MaxBatchTime");
-      
-      maxBatchTime = time;
-   }
-      
-   public synchronized String getSubscriptionName()
-   {
-      return this.subName;
-   }
-   
-   public synchronized void setSubscriptionName(String subname)
-   {
-      checkBridgeNotStarted();
-      this.subName = subname; 
-   }
-      
-   public synchronized String getClientID()
-   {
-      return clientID;
-   }
-   
-   public synchronized void setClientID(String clientID)
-   {
-      checkBridgeNotStarted();
-      
-      this.clientID = clientID; 
-   }
-   
-   public boolean isAddMessageIDInHeader()
-   {
-   	return this.addMessageIDInHeader;
-   }
-   
-   public void setAddMessageIDInHeader(boolean value)
-   {
-   	this.addMessageIDInHeader = value;
-   }
-      
-   public synchronized boolean isPaused()
-   {
-      return paused;
-   }
-   
-   public synchronized boolean isFailed()
-   {
-      return failed;
-   }
-
-   public synchronized void setSourceConnectionFactoryFactory(ConnectionFactoryFactory cff)
-   {
-      checkBridgeNotStarted();
-      checkNotNull(cff, "SourceConnectionFactoryFactory");
-      
-      this.sourceCff = cff;
-   }
-   
-   public synchronized void setTargetConnectionFactoryFactory(ConnectionFactoryFactory cff)
-   {
-      checkBridgeNotStarted();
-      checkNotNull(cff, "TargetConnectionFactoryFactory");
-
-      this.targetCff = cff;
-   }
-   
-   public void setTransactionManager(TransactionManager tm)
-   {
-      this.tm = tm;
-   }
-
-   // Public ---------------------------------------------------------------------------
-   
-   // Private -------------------------------------------------------------------
-
-   private void checkParams()
-   {
-      checkNotNull(sourceCff, "sourceCff");
-      checkNotNull(targetCff, "targetCff");
-      checkNotNull(sourceDestinationFactory, "sourceDestinationFactory");
-      checkNotNull(targetDestinationFactory, "targetDestinationFactory");
-      checkValidValue(failureRetryInterval, "failureRetryInterval");
-      checkValidValue(maxRetries, "maxRetries");
-      if (failureRetryInterval == -1 && maxRetries > 0)
-      {
-         throw new IllegalArgumentException("If failureRetryInterval == -1 maxRetries must be set to -1");
-      }
-      checkMaxBatchSize(maxBatchSize);
-      checkValidValue(maxBatchTime, "maxBatchTime");
-      checkNotNull(qualityOfServiceMode, "qualityOfServiceMode");
-   }
-
-   /**
-    * Check the object is not null
-    * 
-    * @throws IllegalArgumentException if the object is null
-    */
-   private static void checkNotNull(Object obj, String name)
-   {
-      if (obj == null)
-      {
-         throw new IllegalArgumentException(name + " cannot be null");
-      }
-   }
-   
-   /**
-    * Check the bridge is not started
-    * 
-    * @throws IllegalStateException if the bridge is started
-    */
-   private void checkBridgeNotStarted()
-   {
-      if (started)
-      {
-         throw new IllegalStateException("Cannot set bridge attributes while it is started");
-      }
-   }
-   
-   /**
-    * Check that value is either equals to -1 or greater than 0
-    * 
-    * @throws IllegalArgumentException if the value is not valid
-    */
-   private static void checkValidValue(long value, String name)
-   {
-      if (!(value == -1 || value > 0))
-      {
-         throw new IllegalArgumentException(name + " must be > 0 or -1");
-      }
-   }  
-   
-   private static void checkMaxBatchSize(int size)
-   {
-      if (!(size >= 1))
-      {
-         throw new IllegalArgumentException("maxBatchSize must be >= 1");
-      }
-   }
-
-   private void enlistResources(Transaction tx) throws Exception
-   {
-      if (trace) { log.trace("Enlisting resources in tx"); }
-      
-      XAResource resSource = ((XASession)sourceSession).getXAResource();
-      
-      tx.enlistResource(resSource);
-      
-      XAResource resDest = ((XASession)targetSession).getXAResource();
-      
-      tx.enlistResource(resDest);
-      
-      if (trace) { log.trace("Enlisted resources in tx"); }
-   }
-   
-   private void delistResources(Transaction tx)
-   {
-      if (trace) { log.trace("Delisting resources from tx"); }
-      
-      XAResource resSource = ((XASession)sourceSession).getXAResource();
-
-      try
-      {
-         tx.delistResource(resSource, XAResource.TMSUCCESS);
-      }
-      catch (Exception e)
-      {
-         if (trace) { log.trace("Failed to delist source resource", e); }
-      }
-
-      
-      XAResource resDest = ((XASession)targetSession).getXAResource();
-      
-      try
-      {
-         tx.delistResource(resDest, XAResource.TMSUCCESS);
-      }
-      catch (Exception e)
-      {
-         if (trace) { log.trace("Failed to delist target resource", e); }
-      }
-      
-      if (trace) { log.trace("Delisted resources from tx"); }
-   }
-   
-   private Transaction startTx() throws Exception
-   {
-      if (trace) { log.trace("Starting JTA transaction"); }
-      
-      TransactionManager tm = getTm();
-      
-      //Set timeout to a large value since we do not want to time out while waiting for messages
-      //to arrive - 10 years should be enough
-      tm.setTransactionTimeout(TEN_YEARS);
-      
-      tm.begin();
-         
-      Transaction tx = tm.getTransaction();
-      
-      //Remove the association between current thread - we don't want it
-      //we will be committing /rolling back directly on the transaction object
-      
-      tm.suspend();
-      
-      if (trace) { log.trace("Started JTA transaction"); }
-      
-      return tx;
-   }
-   
-   private TransactionManager getTm()
-   {
-      if (tm == null)
-      {
-         tm = TransactionManagerLocator.getInstance().locate();
-         
-         if (tm == null)
-         {
-            throw new IllegalStateException("Cannot locate a transaction manager");
-         }         
-      }
-      
-      return tm;
-   }
-         
-   private Connection createConnection(String username, String password, ConnectionFactoryFactory cff)
-      throws Exception
-   {
-      Connection conn;
-      
-      ConnectionFactory cf = cff.createConnectionFactory();
-      
-      if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE &&
-          !(cf instanceof XAConnectionFactory))
-      {
-         throw new IllegalArgumentException("Connection factory must be XAConnectionFactory");
-      }
-      
-      if (username == null)
-      {
-         if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE)
-         {
-            if (trace) { log.trace("Creating an XA connection"); }
-            conn = ((XAConnectionFactory)cf).createXAConnection();
-         }
-         else
-         {
-            if (trace) { log.trace("Creating a non XA connection"); }
-            conn = cf.createConnection();            
-         }
-      }
-      else
-      {
-         if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE)
-         {
-            if (trace) { log.trace("Creating an XA connection"); }
-            conn = ((XAConnectionFactory)cf).createXAConnection(username, password);
-         }
-         else
-         {
-            if (trace) { log.trace("Creating a non XA connection"); }
-            conn = cf.createConnection(username, password);            
-         }  
-      }
-      
-      return conn;
-   }
-    
-   /*
-    * Source and target on same server
-    * --------------------------------
-    * If the source and target destinations are on the same server (same resource manager) then,
-    * in order to get ONCE_AND_ONLY_ONCE, we simply need to consuming and send in a single
-    * local JMS transaction.
-    * 
-    * We actually use a single local transacted session for the other QoS modes too since this
-    * is more performant than using DUPS_OK_ACKNOWLEDGE or AUTO_ACKNOWLEDGE session ack modes, so effectively
-    * the QoS is upgraded.
-    * 
-    * Source and target on different server
-    * -------------------------------------
-    * If the source and target destinations are on a different servers (different resource managers) then:
-    * 
-    * If desired QoS is ONCE_AND_ONLY_ONCE, then we start a JTA transaction and enlist the consuming and sending
-    * XAResources in that.
-    * 
-    * If desired QoS is DUPLICATES_OK then, we use CLIENT_ACKNOWLEDGE for the consuming session and
-    * AUTO_ACKNOWLEDGE (this is ignored) for the sending session if the maxBatchSize == 1, otherwise we
-    * use a local transacted session for the sending session where maxBatchSize > 1, since this is more performant
-    * When bridging a batch, we make sure to manually acknowledge the consuming session, if it is CLIENT_ACKNOWLEDGE
-    * *after* the batch has been sent
-    * 
-    * If desired QoS is AT_MOST_ONCE then, if maxBatchSize == 1, we use AUTO_ACKNOWLEDGE for the consuming session,
-    * and AUTO_ACKNOWLEDGE for the sending session.
-    * If maxBatchSize > 1, we use CLIENT_ACKNOWLEDGE for the consuming session and a local transacted session for the
-    * sending session.
-    * 
-    * When bridging a batch, we make sure to manually acknowledge the consuming session, if it is CLIENT_ACKNOWLEDGE
-    * *before* the batch has been sent
-    * 
-    */
-   private boolean setupJMSObjects()
-   {
-      try
-      {  
-         if (sourceCff == targetCff)
-         {
-            //Source and target destinations are on the server - we can get once and only once
-            //just using a local transacted session
-         	//everything becomes once and only once
-         	
-         	forwardMode = FORWARD_MODE_LOCALTX;
-         }
-         else
-         {
-         	//Different servers
-         	if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE)
-         	{
-         		//Use XA
-         		
-         		forwardMode = FORWARD_MODE_XA;
-         	}
-         	else
-         	{
-         		forwardMode = FORWARD_MODE_NONTX;
-         	}
-         }
-         
-      	//Lookup the destinations
-      	sourceDestination = sourceDestinationFactory.createDestination();
-      	
-      	targetDestination = targetDestinationFactory.createDestination();      	      
-         
-         sourceConn = createConnection(sourceUsername, sourcePassword, sourceCff);
-         
-         if (forwardMode != FORWARD_MODE_LOCALTX)
-         {
-            targetConn = createConnection(targetUsername, targetPassword, targetCff);
-            
-            targetConn.setExceptionListener(new BridgeExceptionListener());            
-         }
-                  
-         if (clientID != null)
-         {
-            sourceConn.setClientID(clientID);
-         }
-         
-         sourceConn.setExceptionListener(new BridgeExceptionListener());         
-          
-         Session sess;
-         
-         if (forwardMode == FORWARD_MODE_LOCALTX)
-         {
-            //We simply use a single local transacted session for consuming and sending      
-            
-            sourceSession = sourceConn.createSession(true, Session.SESSION_TRANSACTED);
-            
-            sess = sourceSession;
-         }
-         else
-         {
-            if (forwardMode == FORWARD_MODE_XA)
-            {
-               //Create an XASession for consuming from the source
-               if (trace) { log.trace("Creating XA source session"); }
-               
-               sourceSession = ((XAConnection)sourceConn).createXASession();
-               
-               sess = ((XASession)sourceSession).getSession();
-            }
-            else
-            {
-               if (trace) { log.trace("Creating non XA source session"); }
-               
-               //Create a standard session for consuming from the source
-               
-               //We use ack mode client ack
-                              
-               sourceSession = sourceConn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-               
-               sess = sourceSession;
-            }
-         }
-         
-         if (forwardMode == FORWARD_MODE_XA && sourceSession instanceof JBossSession)
-         {
-         	JBossSession jsession = (JBossSession)sourceSession;
-
-         	ClientSession clientSession = jsession.getCoreSession();
-            
-         	//clientSession.setTreatAsNonTransactedWhenNotEnlisted(false);
-         }
-            
-         if (subName == null)
-         {
-            if (selector == null)
-            {
-               sourceConsumer = sess.createConsumer(sourceDestination);
-            }
-            else
-            {
-               sourceConsumer = sess.createConsumer(sourceDestination, selector, false);
-            }
-         }
-         else
-         {
-            //Durable subscription
-            if (selector == null)
-            {
-               sourceConsumer = sess.createDurableSubscriber((Topic)sourceDestination, subName);
-            }
-            else
-            {
-               sourceConsumer = sess.createDurableSubscriber((Topic)sourceDestination, subName, selector, false);
-            }
-         }
-         
-         //Now the sending session
-         
-         
-         if (forwardMode != FORWARD_MODE_LOCALTX)
-         {            
-            if (forwardMode == FORWARD_MODE_XA)
-            {
-               if (trace) { log.trace("Creating XA dest session"); }
-               
-               //Create an XA sesion for sending to the destination
-               
-               targetSession = ((XAConnection)targetConn).createXASession();
-               
-               sess = ((XASession)targetSession).getSession();
-            }
-            else
-            {
-               if (trace) { log.trace("Creating non XA dest session"); }
-               
-               //Create a standard session for sending to the target
-                                             
-               //If batch size > 1 we use a transacted session since is more efficient
-               
-               boolean transacted = maxBatchSize > 1;
-               
-               targetSession = targetConn.createSession(transacted, transacted ? Session.SESSION_TRANSACTED : Session.AUTO_ACKNOWLEDGE);
-               
-               sess = targetSession;
-            }       
-         }
-         
-         if (forwardMode == FORWARD_MODE_XA)
-         {
-            if (trace) { log.trace("Starting JTA transaction"); }
-            
-            tx = startTx();
-            
-            enlistResources(tx);                  
-         }
-         
-         targetProducer = sess.createProducer(null);
-                          
-         sourceConsumer.setMessageListener(new SourceListener());
-         
-         return true;
-      }
-      catch (Exception e)
-      {
-         log.warn("Failed to set up bridge connections");
-         
-         //If this fails we should attempt to cleanup or we might end up in some weird state
-         
-         cleanup();
-         
-         return false;
-      }
-   }
-   
-   private void cleanup()
-   {
-      //Stop the source connection
-      try
-      {
-         sourceConn.stop();
-      }
-      catch (Throwable ignore)
-      {            
-         if (trace) { log.trace("Failed to stop source connection", ignore); }
-      }
-      
-      if (tx != null)
-      {
-         try
-         {
-            delistResources(tx);
-         }
-         catch (Throwable ignore)
-         {
-         	if (trace) { log.trace("Failed to delist resources", ignore); }
-         } 
-         try
-         {
-            //Terminate the tx
-            tx.rollback();
-         }
-         catch (Throwable ignore)
-         {
-         	if (trace) { log.trace("Failed to rollback", ignore); }
-         } 
-      }
-      
-      //Close the old objects
-      try
-      {
-         sourceConn.close();
-      }
-      catch (Throwable ignore)
-      {            
-         if (trace) { log.trace("Failed to close source connection", ignore); }
-      }
-      try
-      {
-         if (targetConn != null)
-         {
-            targetConn.close();
-         }
-      }
-      catch (Throwable ignore)
-      {    
-         if (trace) { log.trace("Failed to close target connection", ignore); }
-      }
-   }
-   
-   private void pause(long interval)
-   {
-      long start = System.currentTimeMillis();
-      while (System.currentTimeMillis() - start < failureRetryInterval)
-      {
-         try
-         {
-            Thread.sleep(failureRetryInterval);
-         }
-         catch (InterruptedException ex)
-         {                  
-         }
-      }
-   }
-   
-   private boolean setupJMSObjectsWithRetry()
-   {
-      if (trace) { log.trace("Setting up connections"); }
-      
-      int count = 0;
-      
-      while (true)
-      {
-         boolean ok = setupJMSObjects();
-         
-         if (ok)
-         {
-            return true;
-         }
-         
-         count++;
-         
-         if (maxRetries != -1 && count == maxRetries)
-         {
-            break;
-         }
-         
-         log.warn("Failed to set up connections, will retry after a pause of " + failureRetryInterval + " ms");
-         
-         pause(failureRetryInterval);
-      }
-      
-      //If we get here then we exceed maxRetries
-      return false;      
-   }
-      
-   
-   private void sendBatch() 
-   {
-      if (trace) { log.trace("Sending batch of " + messages.size() + " messages"); }
-        
-      if (paused)
-      {
-         //Don't send now
-         if (trace) { log.trace("Paused, so not sending now"); }
-         
-         return;            
-      }
-      
-      if (forwardMode == FORWARD_MODE_LOCALTX)
-      {
-         sendBatchLocalTx();
-      }
-      else if (forwardMode == FORWARD_MODE_XA)        
-      {
-         sendBatchXA();
-      }
-      else
-      {
-         sendBatchNonTransacted();
-      }
-   }
-   
-   private void sendBatchNonTransacted()
-   {
-   	try
-      {         
-   		if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE)
-   		{
-   			//We client ack before sending
-   			
-            if (trace) { log.trace("Client acking source session"); }
-               			
-            ((Message)messages.getLast()).acknowledge();
-            
-            if (trace) { log.trace("Client acked source session"); }            
-   		}
-   		   		
-         sendMessages();
-         
-         if (maxBatchSize > 1)
-         {
-         	//The sending session is transacted - we need to commit it
-         	
-            if (trace) { log.trace("Committing target session"); }
-                     	
-         	targetSession.commit();
-         	
-            if (trace) { log.trace("Committed source session"); }            
-         }
-         
-         if (qualityOfServiceMode == QualityOfServiceMode.DUPLICATES_OK)
-   		{
-   			//We client ack after sending
-         	
-         	//Note we could actually use Session.DUPS_OK_ACKNOWLEDGE here
-         	//For a slightly less strong delivery guarantee
-   		
-            if (trace) { log.trace("Client acking source session"); }
-               			
-            messages.getLast().acknowledge();
-            
-            if (trace) { log.trace("Client acked source session"); }            
-   		}
-                                         
-         //Clear the messages
-         messages.clear();            
-      }
-      catch (Exception e)
-      {
-         log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
-      
-         handleFailureOnSend();                                                 
-      }	
-   }
-   
-   private void sendBatchXA()
-   {
-   	try
-      {         
-         sendMessages();
-         
-         //Commit the JTA transaction and start another
-                                 
-         delistResources(tx);
-            
-         if (trace) { log.trace("Committing JTA transaction"); }
-         
-         tx.commit();
-
-         if (trace) { log.trace("Committed JTA transaction"); }
-         
-         tx = startTx();  
-         
-         enlistResources(tx);
-                  
-         //Clear the messages
-         messages.clear();            
-      }
-      catch (Exception e)
-      {
-         log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
-      
-         handleFailureOnSend();                                                 
-      }
-   }
-   
-   private void sendBatchLocalTx()
-   {
-   	try
-      {         
-         sendMessages();
-                     
-         if (trace) { log.trace("Committing source session"); }
-         
-         sourceSession.commit();
-         
-         if (trace) { log.trace("Committed source session"); }     
-         
-         //Clear the messages
-         messages.clear();           
-      }
-      catch (Exception e)
-      {
-         log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
-      
-         handleFailureOnSend();                                                 
-      }
-   }
-   
-   private void sendMessages() throws Exception
-   {
-      Iterator iter = messages.iterator();
-      
-      Message msg = null;
-      
-      while (iter.hasNext())
-      {
-      	msg = (Message)iter.next();
-      	
-      	if (addMessageIDInHeader)
-         {
-         	addMessageIDInHeader(msg);            	
-         }
-         
-         if (trace) { log.trace("Sending message " + msg); }
-         
-         //Make sure the correct time to live gets propagated
-         
-         long timeToLive = msg.getJMSExpiration();
-         
-   		if (timeToLive != 0)
-   		{
-   			timeToLive -=  System.currentTimeMillis();
-   			
-   			if (timeToLive <= 0)
-   			{
-   				timeToLive = 1; //Should have already expired - set to 1 so it expires when it is consumed or delivered
-   			}
-   		}
-         
-   		targetProducer.send(targetDestination, msg, msg.getJMSDeliveryMode(), msg.getJMSPriority(), timeToLive);
-   		
-         if (trace) { log.trace("Sent message " + msg); }     
-      }
-   }
-   
-   private void handleFailureOnSend()
-   {
-      handleFailure(new FailureHandler());
-   }
-   
-   private void handleFailureOnStartup()
-   {
-      handleFailure(new StartupFailureHandler());
-   }
-   
-   private void handleFailure(Runnable failureHandler)
-   {
-      failed = true;
-
-      //Failure must be handled on a separate thread to the calling thread (either onMessage or start).
-      //In the case of onMessage we can't close the connection from inside the onMessage method
-      //since it will block waiting for onMessage to complete. In the case of start we want to return
-      //from the call before the connections are reestablished so that the caller is not blocked unnecessarily.
-      Thread t = new Thread(failureHandler);
-      
-      t.start();         
-   }
-   
-   private void addMessageIDInHeader(Message msg) throws Exception
-   {
-   	//We concatenate the old message id as a header in the message
-   	//This allows the target to then use this as the JMSCorrelationID of any response message
-   	//thus enabling a distributed request-response pattern.
-   	//Each bridge (if there are more than one) in the chain can concatenate the message id
-   	//So in the case of multiple bridges having routed the message this can be used in a multi-hop
-   	//distributed request/response
-   	if (trace) { log.trace("Adding old message id in Message header"); }
-   	
-   	copyProperties(msg);
-
-   	String val = null;
-   	
-   	val = msg.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
-   	
-   	if (val == null)
-   	{
-   		val = msg.getJMSMessageID();
-   	}
-   	else
-   	{
-   		StringBuffer sb = new StringBuffer(val);
-   		
-   		sb.append(",").append(msg.getJMSMessageID());
-   		
-   		val = sb.toString();
-   	}
-   	
-   	msg.setStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST, val);            	   
-   }
-
-   
-   /*
-    * JMS does not let you add a property on received message without first
-    * calling clearProperties, so we need to save and re-add all the old properties so we
-    * don't lose them!!
-    */
-   private static void copyProperties(Message msg) throws JMSException
-   {   	
-   	Enumeration en = msg.getPropertyNames();
-   	
-   	Map<String, Object> oldProps = null;
-   	
-   	while (en.hasMoreElements())
-   	{
-   		String propName = (String)en.nextElement();
-   		
-   		if (oldProps == null)
-   		{
-   			oldProps = new HashMap<String, Object>();
-   		}
-   		
-   		oldProps.put(propName, msg.getObjectProperty(propName));
-   	}
-   	            	
-   	msg.clearProperties();
-   	
-   	if (oldProps != null)
-   	{
-   		Iterator oldPropsIter = oldProps.entrySet().iterator();
-   		
-   		while (oldPropsIter.hasNext())
-   		{
-   			Map.Entry entry = (Map.Entry)oldPropsIter.next();
-
-   			String propName = (String)entry.getKey();
-
-   			msg.setObjectProperty(propName, entry.getValue());   			
-   		}
-   	}
-   }
-   
-   // Inner classes ---------------------------------------------------------------
-   
-   private class FailureHandler implements Runnable
-   {
-      /**
-       * Start the source connection - note the source connection must not be started before
-       * otherwise messages will be received and ignored
-       */
-      protected void startSourceConnection()
-      {
-         try
-         {
-            sourceConn.start();
-         }
-         catch (JMSException e)
-         {
-            log.error("Failed to start source connection", e);
-         }
-      }
-
-      protected void succeeded()
-      {
-         log.info("Succeeded in reconnecting to servers");
-         
-         synchronized (lock)
-         {
-            failed = false;
-
-            startSourceConnection();
-         }
-      }
-      
-      protected void failed()
-      {
-         //We haven't managed to recreate connections or maxRetries = 0
-         log.warn("Unable to set up connections, bridge will be stopped");
-         
-         try
-         {                  
-            stop();
-         }
-         catch (Exception ignore)
-         {                  
-         }
-      }
-
-      public void run()
-      {
-      	if (trace) { log.trace("Failure handler running"); }
-      	
-         // Clear the messages
-         messages.clear();
-
-         cleanup();
-         
-         boolean ok = false;
-         
-         if (maxRetries > 0 || maxRetries == -1)
-         {
-            log.warn("Will retry after a pause of " + failureRetryInterval + " ms");
-            
-            pause(failureRetryInterval);
-            
-            //Now we try
-            ok = setupJMSObjectsWithRetry();
-         }
-         
-         if (!ok)
-         {
-            failed();
-         }
-         else
-         {
-            succeeded();
-         }    
-      }
-   }
-   
-   private class StartupFailureHandler extends FailureHandler
-   {
-      protected void failed()
-      {
-         // Don't call super
-         log.warn("Unable to set up connections, bridge will not be started");
-      }
-      
-      protected void succeeded()
-      {
-         // Don't call super - a bit ugly in this case but better than taking the lock twice.
-         log.info("Succeeded in connecting to servers");
-         
-         synchronized (lock)
-         {
-            failed = false;
-            started = true;
-            
-            //Start the source connection - note the source connection must not be started before
-            //otherwise messages will be received and ignored
-            
-            try
-            {
-               sourceConn.start();
-            }
-            catch (JMSException e)
-            {
-               log.error("Failed to start source connection", e);
-            }
-         }
-      }
-   }
-   
-   private class BatchTimeChecker implements Runnable
-   {
-      public void run()
-      {
-         if (trace) { log.trace(this + " running"); }
-         
-         synchronized (lock)
-         {
-            while (started)
-            {
-               long toWait = batchExpiryTime - System.currentTimeMillis();
-               
-               if (toWait <= 0)
-               {
-                  if (trace) { log.trace(this + " waited enough"); }
-                  
-                  synchronized (lock)
-                  {              
-                     if (!failed && !messages.isEmpty())
-                     {
-                        if (trace) { log.trace(this + " got some messages so sending batch"); }
-                        
-                        sendBatch();                     
-                        
-                        if (trace) { log.trace(this + " sent batch"); }
-                     }
-                  }
-                  
-                  batchExpiryTime = System.currentTimeMillis() + maxBatchTime;
-               }
-               else
-               {                    
-                  try
-                  {
-                     if (trace) { log.trace(this + " waiting for " + toWait); }
-                     
-                     lock.wait(toWait);
-                     
-                     if (trace) { log.trace(this + " woke up"); }
-                  }
-                  catch (InterruptedException e)
-                  {
-                     //Ignore
-                     if (trace) { log.trace(this + " thread was interrupted"); }
-                  }
-                  
-               }
-            }        
-         }
-      }      
-   }  
-   
-   private class SourceListener implements MessageListener
-   {
-      public void onMessage(Message msg)
-      {
-         synchronized (lock)
-         {
-            if (failed)
-            {
-               //Ignore the message
-               if (trace) { log.trace("Bridge has failed so ignoring message"); }
-                              
-               return;
-            }
-            
-            if (trace) { log.trace(this + " received message " + msg); }
-            
-            messages.add(msg);
-            
-            batchExpiryTime = System.currentTimeMillis() + maxBatchTime;            
-            
-            if (trace) { log.trace(this + " rescheduled batchExpiryTime to " + batchExpiryTime); }
-            
-            if (maxBatchSize != -1 && messages.size() >= maxBatchSize)
-            {
-               if (trace) { log.trace(this + " maxBatchSize has been reached so sending batch"); }
-               
-               sendBatch();
-               
-               if (trace) { log.trace(this + " sent batch"); }
-            }                        
-         }
-      }      
-   }   
-   
-   private class BridgeExceptionListener implements ExceptionListener
-   {
-		public void onException(JMSException e)
-		{
-			log.warn("Detected failure on bridge connection");
-			
-			synchronized (lock)
-			{
-				if (failed)
-				{
-					//The failure has already been detected and is being handled
-					if (trace) { log.trace("Failure recovery already in progress"); }
-				}
-				else
-			   {				
-					handleFailure(new FailureHandler());
-			   }
-			}
-		}   	
-   }   
-}

Copied: trunk/src/main/org/jboss/messaging/jms/bridge/impl/JMSBridgeImpl.java (from rev 6295, trunk/src/main/org/jboss/messaging/jms/bridge/impl/BridgeImpl.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/bridge/impl/JMSBridgeImpl.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/jms/bridge/impl/JMSBridgeImpl.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -0,0 +1,1602 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * 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.messaging.jms.bridge.impl;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.jms.XAConnection;
+import javax.jms.XAConnectionFactory;
+import javax.jms.XASession;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.messaging.core.client.ClientSession;
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.server.MessagingComponent;
+import org.jboss.messaging.jms.bridge.JMSBridge;
+import org.jboss.messaging.jms.bridge.ConnectionFactoryFactory;
+import org.jboss.messaging.jms.bridge.DestinationFactory;
+import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
+import org.jboss.messaging.jms.client.JBossMessage;
+import org.jboss.messaging.jms.client.JBossSession;
+import org.jboss.tm.TransactionManagerLocator;
+
+/**
+ * 
+ * A JMSBridge
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision:4566 $</tt>
+ *
+ * $Id:JMSBridge.java 4566 2008-06-24 08:01:35Z jmesnil $
+ *
+ */
+public class JMSBridgeImpl implements MessagingComponent, JMSBridge
+{
+   private static final Logger log;
+   
+   private static boolean trace;
+   
+   static
+   {
+      log = Logger.getLogger(JMSBridgeImpl.class);
+      
+      trace = log.isTraceEnabled();
+   }
+
+   private static final int TEN_YEARS = 60 * 60 * 24 * 365 * 10; // in ms
+
+   private final Object lock = new Object();
+   
+   private String sourceUsername;
+   
+   private String sourcePassword;
+   
+   private String targetUsername;
+   
+   private String targetPassword;
+   
+   private TransactionManager tm;
+   
+   private String selector;
+   
+   private long failureRetryInterval;
+   
+   private int maxRetries;
+   
+   private QualityOfServiceMode qualityOfServiceMode;
+   
+   private int maxBatchSize;
+   
+   private long maxBatchTime;
+   
+   private String subName;
+   
+   private String clientID;
+   
+   private volatile boolean addMessageIDInHeader;
+   
+   private boolean started;
+   
+   private LinkedList<Message> messages;
+   
+   private ConnectionFactoryFactory sourceCff;
+   
+   private ConnectionFactoryFactory targetCff;
+   
+   private DestinationFactory sourceDestinationFactory;
+   
+   private DestinationFactory targetDestinationFactory;
+   
+   private Connection sourceConn; 
+   
+   private Connection targetConn;
+   
+   private Destination sourceDestination;
+   
+   private Destination targetDestination;
+   
+   private Session sourceSession;
+   
+   private Session targetSession;
+   
+   private MessageConsumer sourceConsumer;
+   
+   private MessageProducer targetProducer;
+        
+   private BatchTimeChecker timeChecker;
+   
+   private Thread checkerThread;
+   
+   private long batchExpiryTime;
+   
+   private boolean paused;         
+   
+   private Transaction tx;  
+   
+   private boolean failed;
+   
+   private int forwardMode;
+   
+   private static final int FORWARD_MODE_XA = 0;
+   
+   private static final int FORWARD_MODE_LOCALTX = 1;
+   
+   private static final int FORWARD_MODE_NONTX = 2;
+   
+   /*
+    * Constructor for MBean
+    */
+   public JMSBridgeImpl()
+   {      
+      this.messages = new LinkedList<Message>();      
+   }
+   
+   public JMSBridgeImpl(ConnectionFactoryFactory sourceCff, ConnectionFactoryFactory targetCff,
+                 DestinationFactory sourceDestinationFactory, DestinationFactory targetDestinationFactory,         
+                 String sourceUsername, String sourcePassword,
+                 String targetUsername, String targetPassword,
+                 String selector, long failureRetryInterval,
+                 int maxRetries,
+                 QualityOfServiceMode qosMode,
+                 int maxBatchSize, long maxBatchTime,
+                 String subName, String clientID,
+                 boolean addMessageIDInHeader)
+   {            
+      this();
+      
+      this.sourceCff = sourceCff;
+      
+      this.targetCff = targetCff;
+      
+      this.sourceDestinationFactory = sourceDestinationFactory;
+      
+      this.targetDestinationFactory = targetDestinationFactory;
+      
+      this.sourceUsername = sourceUsername;
+      
+      this.sourcePassword = sourcePassword;
+      
+      this.targetUsername = targetUsername;
+      
+      this.targetPassword = targetPassword;
+      
+      this.selector = selector;
+      
+      this.failureRetryInterval = failureRetryInterval;
+      
+      this.maxRetries = maxRetries;
+      
+      this.qualityOfServiceMode = qosMode;
+      
+      this.maxBatchSize = maxBatchSize;
+      
+      this.maxBatchTime = maxBatchTime;
+      
+      this.subName = subName;
+      
+      this.clientID = clientID;
+      
+      this.addMessageIDInHeader = addMessageIDInHeader;
+              
+      checkParams();
+      
+      if (trace)
+      {
+         log.trace("Created " + this);
+      }
+   }
+         
+   // MessagingComponent overrides --------------------------------------------------
+        
+   public synchronized void start() throws Exception
+   {      
+      if (started)
+      {
+         log.warn("Attempt to start, but is already started");
+         return;
+      }
+      
+      if (trace) { log.trace("Starting " + this); }         
+      
+      checkParams();
+      
+      TransactionManager tm = getTm();
+      
+      //There may already be a JTA transaction associated to the thread
+      
+      boolean ok;
+      
+      Transaction toResume = null;
+      try
+      {
+         toResume = tm.suspend();
+         
+         ok = setupJMSObjects();
+      }
+      finally
+      {
+         if (toResume != null)
+         {
+            tm.resume(toResume);
+         }
+      }
+      
+      if (ok)
+      {         
+         //start the source connection
+         
+         sourceConn.start();
+         
+         started = true;
+         
+         if (maxBatchTime != -1)
+         {
+            if (trace) { log.trace("Starting time checker thread"); }
+                     
+            timeChecker = new BatchTimeChecker();
+            
+            checkerThread = new Thread(timeChecker);
+            
+            batchExpiryTime = System.currentTimeMillis() + maxBatchTime;
+            
+            checkerThread.start();
+            
+            if (trace) { log.trace("Started time checker thread"); }
+         }            
+         
+         if (trace) { log.trace("Started " + this); }
+      }
+      else
+      {
+         log.warn("Failed to start bridge");
+         handleFailureOnStartup();
+      }
+   }
+   
+   public synchronized void stop() throws Exception
+   {
+      if (!started)
+      {
+         log.warn("Attempt to stop, but is already stopped");
+         return;
+      }
+      
+      if (trace) { log.trace("Stopping " + this); }
+      
+      synchronized (lock)
+      {
+         started = false;          
+         
+         //This must be inside sync block
+         if (checkerThread != null)
+         {
+            checkerThread.interrupt();
+         }
+      }
+            
+      //This must be outside sync block
+      if (checkerThread != null)
+      {  
+         if (trace) { log.trace("Waiting for checker thread to finish");}
+         
+         checkerThread.join();
+         
+         if (trace) { log.trace("Checker thread has finished"); }
+      }
+      
+      if (tx != null)
+      {
+         //Terminate any transaction
+         if (trace) { log.trace("Rolling back remaining tx"); }
+         
+         try
+         {
+            tx.rollback();
+         }
+         catch (Exception ignore)
+         {
+            if (trace) { log.trace("Failed to rollback", ignore); }
+         }
+         
+         if (trace) { log.trace("Rolled back remaining tx"); }
+      }
+      
+      try
+      {
+         sourceConn.close();
+      }
+      catch (Exception ignore)
+      {
+         if (trace) { log.trace("Failed to close source conn", ignore); }
+      }
+      
+      if (targetConn != null)
+      {
+         try
+         {
+            targetConn.close();
+         }
+         catch (Exception ignore)
+         {
+            if (trace) { log.trace("Failed to close target conn", ignore); }
+         }
+      }
+            
+      if (trace) { log.trace("Stopped " + this); }
+   }
+   
+   public synchronized boolean isStarted()
+   {
+      return started;
+   }
+
+   // JMSBridge implementation ------------------------------------------------------------
+
+   public synchronized void pause() throws Exception
+   {
+      if (trace) { log.trace("Pausing " + this); }
+      
+      synchronized (lock)
+      {
+         paused = true;
+         
+         sourceConn.stop();
+      }
+      
+      if (trace) { log.trace("Paused " + this); }
+   }
+   
+   public synchronized void resume() throws Exception
+   {
+      if (trace) { log.trace("Resuming " + this); }
+      
+      synchronized (lock)
+      {
+         paused = false;
+         
+         sourceConn.start();
+      }
+      
+      if (trace) { log.trace("Resumed " + this); }
+   }
+      
+   public DestinationFactory getSourceDestinationFactory()
+   {
+   	return sourceDestinationFactory;
+   }
+
+   public void setSourceDestinationFactory(DestinationFactory dest)
+   {
+      checkBridgeNotStarted();
+   	checkNotNull(dest, "TargetDestinationFactory");
+   	
+   	sourceDestinationFactory = dest;
+   }
+   
+   public DestinationFactory getTargetDestinationFactory()
+   {
+   	return targetDestinationFactory;
+   }
+
+   public void setTargetDestinationFactory(DestinationFactory dest)
+   {
+      checkBridgeNotStarted();
+      checkNotNull(dest, "TargetDestinationFactory");
+      
+   	targetDestinationFactory = dest;
+   }
+   
+   public String getSourceUsername()
+   {
+      return sourceUsername;
+   }
+   
+   public synchronized void setSourceUsername(String name)
+   {
+      checkBridgeNotStarted();
+      
+      sourceUsername = name;
+   }
+   
+   public synchronized String getSourcePassword()
+   {
+      return sourcePassword;
+   }
+   
+   public synchronized void setSourcePassword(String pwd)
+   {
+      checkBridgeNotStarted();
+      
+      sourcePassword = pwd;
+   }
+      
+   public synchronized String getTargetUsername()
+   {
+      return targetUsername;
+   }
+   
+   public synchronized void setTargetUsername(String name)
+   {
+      checkBridgeNotStarted();
+      
+      this.targetUsername = name;
+   }
+   
+   public synchronized String getTargetPassword()
+   {
+      return this.targetPassword;
+   }
+   
+   public synchronized void setTargetPassword(String pwd)
+   {
+      checkBridgeNotStarted();
+      
+      this.targetPassword = pwd;
+   }
+
+   public synchronized String getSelector()
+   {
+      return selector;
+   }
+   
+   public synchronized void setSelector(String selector)
+   {
+      checkBridgeNotStarted();
+      
+      this.selector = selector;
+   }
+   
+   public synchronized long getFailureRetryInterval()
+   {
+      return failureRetryInterval;
+   }
+   
+   public synchronized void setFailureRetryInterval(long interval)
+   {
+      checkBridgeNotStarted();
+      checkValidValue(interval, "FailureRetryInterval");
+      
+      this.failureRetryInterval = interval;
+   }  
+   
+   public synchronized int getMaxRetries()
+   {
+      return maxRetries;
+   }
+   
+   public synchronized void setMaxRetries(int retries)
+   {
+      checkBridgeNotStarted();
+      checkValidValue(retries, "MaxRetries");
+      
+      this.maxRetries = retries;
+   }
+      
+   public synchronized QualityOfServiceMode getQualityOfServiceMode()
+   {
+      return qualityOfServiceMode;
+   }
+   
+   public synchronized void setQualityOfServiceMode(QualityOfServiceMode mode)
+   {
+      checkBridgeNotStarted();
+      checkNotNull(mode, "QualityOfServiceMode");
+      
+      qualityOfServiceMode = mode;
+   }   
+   
+   public synchronized int getMaxBatchSize()
+   {
+      return maxBatchSize;
+   }
+   
+   public synchronized void setMaxBatchSize(int size)
+   {
+      checkBridgeNotStarted();
+      checkMaxBatchSize(size);
+      
+      maxBatchSize = size;
+   }
+   
+   public synchronized long getMaxBatchTime()
+   {
+      return maxBatchTime;
+   }
+   
+   public synchronized void setMaxBatchTime(long time)
+   {
+      checkBridgeNotStarted();
+      checkValidValue(time, "MaxBatchTime");
+      
+      maxBatchTime = time;
+   }
+      
+   public synchronized String getSubscriptionName()
+   {
+      return this.subName;
+   }
+   
+   public synchronized void setSubscriptionName(String subname)
+   {
+      checkBridgeNotStarted();
+      this.subName = subname; 
+   }
+      
+   public synchronized String getClientID()
+   {
+      return clientID;
+   }
+   
+   public synchronized void setClientID(String clientID)
+   {
+      checkBridgeNotStarted();
+      
+      this.clientID = clientID; 
+   }
+   
+   public boolean isAddMessageIDInHeader()
+   {
+   	return this.addMessageIDInHeader;
+   }
+   
+   public void setAddMessageIDInHeader(boolean value)
+   {
+   	this.addMessageIDInHeader = value;
+   }
+      
+   public synchronized boolean isPaused()
+   {
+      return paused;
+   }
+   
+   public synchronized boolean isFailed()
+   {
+      return failed;
+   }
+
+   public synchronized void setSourceConnectionFactoryFactory(ConnectionFactoryFactory cff)
+   {
+      checkBridgeNotStarted();
+      checkNotNull(cff, "SourceConnectionFactoryFactory");
+      
+      this.sourceCff = cff;
+   }
+   
+   public synchronized void setTargetConnectionFactoryFactory(ConnectionFactoryFactory cff)
+   {
+      checkBridgeNotStarted();
+      checkNotNull(cff, "TargetConnectionFactoryFactory");
+
+      this.targetCff = cff;
+   }
+   
+   public void setTransactionManager(TransactionManager tm)
+   {
+      this.tm = tm;
+   }
+
+   // Public ---------------------------------------------------------------------------
+   
+   // Private -------------------------------------------------------------------
+
+   private void checkParams()
+   {
+      checkNotNull(sourceCff, "sourceCff");
+      checkNotNull(targetCff, "targetCff");
+      checkNotNull(sourceDestinationFactory, "sourceDestinationFactory");
+      checkNotNull(targetDestinationFactory, "targetDestinationFactory");
+      checkValidValue(failureRetryInterval, "failureRetryInterval");
+      checkValidValue(maxRetries, "maxRetries");
+      if (failureRetryInterval == -1 && maxRetries > 0)
+      {
+         throw new IllegalArgumentException("If failureRetryInterval == -1 maxRetries must be set to -1");
+      }
+      checkMaxBatchSize(maxBatchSize);
+      checkValidValue(maxBatchTime, "maxBatchTime");
+      checkNotNull(qualityOfServiceMode, "qualityOfServiceMode");
+   }
+
+   /**
+    * Check the object is not null
+    * 
+    * @throws IllegalArgumentException if the object is null
+    */
+   private static void checkNotNull(Object obj, String name)
+   {
+      if (obj == null)
+      {
+         throw new IllegalArgumentException(name + " cannot be null");
+      }
+   }
+   
+   /**
+    * Check the bridge is not started
+    * 
+    * @throws IllegalStateException if the bridge is started
+    */
+   private void checkBridgeNotStarted()
+   {
+      if (started)
+      {
+         throw new IllegalStateException("Cannot set bridge attributes while it is started");
+      }
+   }
+   
+   /**
+    * Check that value is either equals to -1 or greater than 0
+    * 
+    * @throws IllegalArgumentException if the value is not valid
+    */
+   private static void checkValidValue(long value, String name)
+   {
+      if (!(value == -1 || value > 0))
+      {
+         throw new IllegalArgumentException(name + " must be > 0 or -1");
+      }
+   }  
+   
+   private static void checkMaxBatchSize(int size)
+   {
+      if (!(size >= 1))
+      {
+         throw new IllegalArgumentException("maxBatchSize must be >= 1");
+      }
+   }
+
+   private void enlistResources(Transaction tx) throws Exception
+   {
+      if (trace) { log.trace("Enlisting resources in tx"); }
+      
+      XAResource resSource = ((XASession)sourceSession).getXAResource();
+      
+      tx.enlistResource(resSource);
+      
+      XAResource resDest = ((XASession)targetSession).getXAResource();
+      
+      tx.enlistResource(resDest);
+      
+      if (trace) { log.trace("Enlisted resources in tx"); }
+   }
+   
+   private void delistResources(Transaction tx)
+   {
+      if (trace) { log.trace("Delisting resources from tx"); }
+      
+      XAResource resSource = ((XASession)sourceSession).getXAResource();
+
+      try
+      {
+         tx.delistResource(resSource, XAResource.TMSUCCESS);
+      }
+      catch (Exception e)
+      {
+         if (trace) { log.trace("Failed to delist source resource", e); }
+      }
+
+      
+      XAResource resDest = ((XASession)targetSession).getXAResource();
+      
+      try
+      {
+         tx.delistResource(resDest, XAResource.TMSUCCESS);
+      }
+      catch (Exception e)
+      {
+         if (trace) { log.trace("Failed to delist target resource", e); }
+      }
+      
+      if (trace) { log.trace("Delisted resources from tx"); }
+   }
+   
+   private Transaction startTx() throws Exception
+   {
+      if (trace) { log.trace("Starting JTA transaction"); }
+      
+      TransactionManager tm = getTm();
+      
+      //Set timeout to a large value since we do not want to time out while waiting for messages
+      //to arrive - 10 years should be enough
+      tm.setTransactionTimeout(TEN_YEARS);
+      
+      tm.begin();
+         
+      Transaction tx = tm.getTransaction();
+      
+      //Remove the association between current thread - we don't want it
+      //we will be committing /rolling back directly on the transaction object
+      
+      tm.suspend();
+      
+      if (trace) { log.trace("Started JTA transaction"); }
+      
+      return tx;
+   }
+   
+   private TransactionManager getTm()
+   {
+      if (tm == null)
+      {
+         tm = TransactionManagerLocator.getInstance().locate();
+         
+         if (tm == null)
+         {
+            throw new IllegalStateException("Cannot locate a transaction manager");
+         }         
+      }
+      
+      return tm;
+   }
+         
+   private Connection createConnection(String username, String password, ConnectionFactoryFactory cff)
+      throws Exception
+   {
+      Connection conn;
+      
+      ConnectionFactory cf = cff.createConnectionFactory();
+      
+      if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE &&
+          !(cf instanceof XAConnectionFactory))
+      {
+         throw new IllegalArgumentException("Connection factory must be XAConnectionFactory");
+      }
+      
+      if (username == null)
+      {
+         if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE)
+         {
+            if (trace) { log.trace("Creating an XA connection"); }
+            conn = ((XAConnectionFactory)cf).createXAConnection();
+         }
+         else
+         {
+            if (trace) { log.trace("Creating a non XA connection"); }
+            conn = cf.createConnection();            
+         }
+      }
+      else
+      {
+         if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE)
+         {
+            if (trace) { log.trace("Creating an XA connection"); }
+            conn = ((XAConnectionFactory)cf).createXAConnection(username, password);
+         }
+         else
+         {
+            if (trace) { log.trace("Creating a non XA connection"); }
+            conn = cf.createConnection(username, password);            
+         }  
+      }
+      
+      return conn;
+   }
+    
+   /*
+    * Source and target on same server
+    * --------------------------------
+    * If the source and target destinations are on the same server (same resource manager) then,
+    * in order to get ONCE_AND_ONLY_ONCE, we simply need to consuming and send in a single
+    * local JMS transaction.
+    * 
+    * We actually use a single local transacted session for the other QoS modes too since this
+    * is more performant than using DUPS_OK_ACKNOWLEDGE or AUTO_ACKNOWLEDGE session ack modes, so effectively
+    * the QoS is upgraded.
+    * 
+    * Source and target on different server
+    * -------------------------------------
+    * If the source and target destinations are on a different servers (different resource managers) then:
+    * 
+    * If desired QoS is ONCE_AND_ONLY_ONCE, then we start a JTA transaction and enlist the consuming and sending
+    * XAResources in that.
+    * 
+    * If desired QoS is DUPLICATES_OK then, we use CLIENT_ACKNOWLEDGE for the consuming session and
+    * AUTO_ACKNOWLEDGE (this is ignored) for the sending session if the maxBatchSize == 1, otherwise we
+    * use a local transacted session for the sending session where maxBatchSize > 1, since this is more performant
+    * When bridging a batch, we make sure to manually acknowledge the consuming session, if it is CLIENT_ACKNOWLEDGE
+    * *after* the batch has been sent
+    * 
+    * If desired QoS is AT_MOST_ONCE then, if maxBatchSize == 1, we use AUTO_ACKNOWLEDGE for the consuming session,
+    * and AUTO_ACKNOWLEDGE for the sending session.
+    * If maxBatchSize > 1, we use CLIENT_ACKNOWLEDGE for the consuming session and a local transacted session for the
+    * sending session.
+    * 
+    * When bridging a batch, we make sure to manually acknowledge the consuming session, if it is CLIENT_ACKNOWLEDGE
+    * *before* the batch has been sent
+    * 
+    */
+   private boolean setupJMSObjects()
+   {
+      try
+      {  
+         if (sourceCff == targetCff)
+         {
+            //Source and target destinations are on the server - we can get once and only once
+            //just using a local transacted session
+         	//everything becomes once and only once
+         	
+         	forwardMode = FORWARD_MODE_LOCALTX;
+         }
+         else
+         {
+         	//Different servers
+         	if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE)
+         	{
+         		//Use XA
+         		
+         		forwardMode = FORWARD_MODE_XA;
+         	}
+         	else
+         	{
+         		forwardMode = FORWARD_MODE_NONTX;
+         	}
+         }
+         
+      	//Lookup the destinations
+      	sourceDestination = sourceDestinationFactory.createDestination();
+      	
+      	targetDestination = targetDestinationFactory.createDestination();      	      
+         
+         sourceConn = createConnection(sourceUsername, sourcePassword, sourceCff);
+         
+         if (forwardMode != FORWARD_MODE_LOCALTX)
+         {
+            targetConn = createConnection(targetUsername, targetPassword, targetCff);
+            
+            targetConn.setExceptionListener(new BridgeExceptionListener());            
+         }
+                  
+         if (clientID != null)
+         {
+            sourceConn.setClientID(clientID);
+         }
+         
+         sourceConn.setExceptionListener(new BridgeExceptionListener());         
+          
+         Session sess;
+         
+         if (forwardMode == FORWARD_MODE_LOCALTX)
+         {
+            //We simply use a single local transacted session for consuming and sending      
+            
+            sourceSession = sourceConn.createSession(true, Session.SESSION_TRANSACTED);
+            
+            sess = sourceSession;
+         }
+         else
+         {
+            if (forwardMode == FORWARD_MODE_XA)
+            {
+               //Create an XASession for consuming from the source
+               if (trace) { log.trace("Creating XA source session"); }
+               
+               sourceSession = ((XAConnection)sourceConn).createXASession();
+               
+               sess = ((XASession)sourceSession).getSession();
+            }
+            else
+            {
+               if (trace) { log.trace("Creating non XA source session"); }
+               
+               //Create a standard session for consuming from the source
+               
+               //We use ack mode client ack
+                              
+               sourceSession = sourceConn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+               
+               sess = sourceSession;
+            }
+         }
+         
+         if (forwardMode == FORWARD_MODE_XA && sourceSession instanceof JBossSession)
+         {
+         	JBossSession jsession = (JBossSession)sourceSession;
+
+         	ClientSession clientSession = jsession.getCoreSession();
+            
+         	//clientSession.setTreatAsNonTransactedWhenNotEnlisted(false);
+         }
+            
+         if (subName == null)
+         {
+            if (selector == null)
+            {
+               sourceConsumer = sess.createConsumer(sourceDestination);
+            }
+            else
+            {
+               sourceConsumer = sess.createConsumer(sourceDestination, selector, false);
+            }
+         }
+         else
+         {
+            //Durable subscription
+            if (selector == null)
+            {
+               sourceConsumer = sess.createDurableSubscriber((Topic)sourceDestination, subName);
+            }
+            else
+            {
+               sourceConsumer = sess.createDurableSubscriber((Topic)sourceDestination, subName, selector, false);
+            }
+         }
+         
+         //Now the sending session
+         
+         
+         if (forwardMode != FORWARD_MODE_LOCALTX)
+         {            
+            if (forwardMode == FORWARD_MODE_XA)
+            {
+               if (trace) { log.trace("Creating XA dest session"); }
+               
+               //Create an XA sesion for sending to the destination
+               
+               targetSession = ((XAConnection)targetConn).createXASession();
+               
+               sess = ((XASession)targetSession).getSession();
+            }
+            else
+            {
+               if (trace) { log.trace("Creating non XA dest session"); }
+               
+               //Create a standard session for sending to the target
+                                             
+               //If batch size > 1 we use a transacted session since is more efficient
+               
+               boolean transacted = maxBatchSize > 1;
+               
+               targetSession = targetConn.createSession(transacted, transacted ? Session.SESSION_TRANSACTED : Session.AUTO_ACKNOWLEDGE);
+               
+               sess = targetSession;
+            }       
+         }
+         
+         if (forwardMode == FORWARD_MODE_XA)
+         {
+            if (trace) { log.trace("Starting JTA transaction"); }
+            
+            tx = startTx();
+            
+            enlistResources(tx);                  
+         }
+         
+         targetProducer = sess.createProducer(null);
+                          
+         sourceConsumer.setMessageListener(new SourceListener());
+         
+         return true;
+      }
+      catch (Exception e)
+      {
+         log.warn("Failed to set up bridge connections");
+         
+         //If this fails we should attempt to cleanup or we might end up in some weird state
+         
+         cleanup();
+         
+         return false;
+      }
+   }
+   
+   private void cleanup()
+   {
+      //Stop the source connection
+      try
+      {
+         sourceConn.stop();
+      }
+      catch (Throwable ignore)
+      {            
+         if (trace) { log.trace("Failed to stop source connection", ignore); }
+      }
+      
+      if (tx != null)
+      {
+         try
+         {
+            delistResources(tx);
+         }
+         catch (Throwable ignore)
+         {
+         	if (trace) { log.trace("Failed to delist resources", ignore); }
+         } 
+         try
+         {
+            //Terminate the tx
+            tx.rollback();
+         }
+         catch (Throwable ignore)
+         {
+         	if (trace) { log.trace("Failed to rollback", ignore); }
+         } 
+      }
+      
+      //Close the old objects
+      try
+      {
+         sourceConn.close();
+      }
+      catch (Throwable ignore)
+      {            
+         if (trace) { log.trace("Failed to close source connection", ignore); }
+      }
+      try
+      {
+         if (targetConn != null)
+         {
+            targetConn.close();
+         }
+      }
+      catch (Throwable ignore)
+      {    
+         if (trace) { log.trace("Failed to close target connection", ignore); }
+      }
+   }
+   
+   private void pause(long interval)
+   {
+      long start = System.currentTimeMillis();
+      while (System.currentTimeMillis() - start < failureRetryInterval)
+      {
+         try
+         {
+            Thread.sleep(failureRetryInterval);
+         }
+         catch (InterruptedException ex)
+         {                  
+         }
+      }
+   }
+   
+   private boolean setupJMSObjectsWithRetry()
+   {
+      if (trace) { log.trace("Setting up connections"); }
+      
+      int count = 0;
+      
+      while (true)
+      {
+         boolean ok = setupJMSObjects();
+         
+         if (ok)
+         {
+            return true;
+         }
+         
+         count++;
+         
+         if (maxRetries != -1 && count == maxRetries)
+         {
+            break;
+         }
+         
+         log.warn("Failed to set up connections, will retry after a pause of " + failureRetryInterval + " ms");
+         
+         pause(failureRetryInterval);
+      }
+      
+      //If we get here then we exceed maxRetries
+      return false;      
+   }
+      
+   
+   private void sendBatch() 
+   {
+      if (trace) { log.trace("Sending batch of " + messages.size() + " messages"); }
+        
+      if (paused)
+      {
+         //Don't send now
+         if (trace) { log.trace("Paused, so not sending now"); }
+         
+         return;            
+      }
+      
+      if (forwardMode == FORWARD_MODE_LOCALTX)
+      {
+         sendBatchLocalTx();
+      }
+      else if (forwardMode == FORWARD_MODE_XA)        
+      {
+         sendBatchXA();
+      }
+      else
+      {
+         sendBatchNonTransacted();
+      }
+   }
+   
+   private void sendBatchNonTransacted()
+   {
+   	try
+      {         
+   		if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE)
+   		{
+   			//We client ack before sending
+   			
+            if (trace) { log.trace("Client acking source session"); }
+               			
+            ((Message)messages.getLast()).acknowledge();
+            
+            if (trace) { log.trace("Client acked source session"); }            
+   		}
+   		   		
+         sendMessages();
+         
+         if (maxBatchSize > 1)
+         {
+         	//The sending session is transacted - we need to commit it
+         	
+            if (trace) { log.trace("Committing target session"); }
+                     	
+         	targetSession.commit();
+         	
+            if (trace) { log.trace("Committed source session"); }            
+         }
+         
+         if (qualityOfServiceMode == QualityOfServiceMode.DUPLICATES_OK)
+   		{
+   			//We client ack after sending
+         	
+         	//Note we could actually use Session.DUPS_OK_ACKNOWLEDGE here
+         	//For a slightly less strong delivery guarantee
+   		
+            if (trace) { log.trace("Client acking source session"); }
+               			
+            messages.getLast().acknowledge();
+            
+            if (trace) { log.trace("Client acked source session"); }            
+   		}
+                                         
+         //Clear the messages
+         messages.clear();            
+      }
+      catch (Exception e)
+      {
+         log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
+      
+         handleFailureOnSend();                                                 
+      }	
+   }
+   
+   private void sendBatchXA()
+   {
+   	try
+      {         
+         sendMessages();
+         
+         //Commit the JTA transaction and start another
+                                 
+         delistResources(tx);
+            
+         if (trace) { log.trace("Committing JTA transaction"); }
+         
+         tx.commit();
+
+         if (trace) { log.trace("Committed JTA transaction"); }
+         
+         tx = startTx();  
+         
+         enlistResources(tx);
+                  
+         //Clear the messages
+         messages.clear();            
+      }
+      catch (Exception e)
+      {
+         log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
+      
+         handleFailureOnSend();                                                 
+      }
+   }
+   
+   private void sendBatchLocalTx()
+   {
+   	try
+      {         
+         sendMessages();
+                     
+         if (trace) { log.trace("Committing source session"); }
+         
+         sourceSession.commit();
+         
+         if (trace) { log.trace("Committed source session"); }     
+         
+         //Clear the messages
+         messages.clear();           
+      }
+      catch (Exception e)
+      {
+         log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
+      
+         handleFailureOnSend();                                                 
+      }
+   }
+   
+   private void sendMessages() throws Exception
+   {
+      Iterator iter = messages.iterator();
+      
+      Message msg = null;
+      
+      while (iter.hasNext())
+      {
+      	msg = (Message)iter.next();
+      	
+      	if (addMessageIDInHeader)
+         {
+         	addMessageIDInHeader(msg);            	
+         }
+         
+         if (trace) { log.trace("Sending message " + msg); }
+         
+         //Make sure the correct time to live gets propagated
+         
+         long timeToLive = msg.getJMSExpiration();
+         
+   		if (timeToLive != 0)
+   		{
+   			timeToLive -=  System.currentTimeMillis();
+   			
+   			if (timeToLive <= 0)
+   			{
+   				timeToLive = 1; //Should have already expired - set to 1 so it expires when it is consumed or delivered
+   			}
+   		}
+         
+   		targetProducer.send(targetDestination, msg, msg.getJMSDeliveryMode(), msg.getJMSPriority(), timeToLive);
+   		
+         if (trace) { log.trace("Sent message " + msg); }     
+      }
+   }
+   
+   private void handleFailureOnSend()
+   {
+      handleFailure(new FailureHandler());
+   }
+   
+   private void handleFailureOnStartup()
+   {
+      handleFailure(new StartupFailureHandler());
+   }
+   
+   private void handleFailure(Runnable failureHandler)
+   {
+      failed = true;
+
+      //Failure must be handled on a separate thread to the calling thread (either onMessage or start).
+      //In the case of onMessage we can't close the connection from inside the onMessage method
+      //since it will block waiting for onMessage to complete. In the case of start we want to return
+      //from the call before the connections are reestablished so that the caller is not blocked unnecessarily.
+      Thread t = new Thread(failureHandler);
+      
+      t.start();         
+   }
+   
+   private void addMessageIDInHeader(Message msg) throws Exception
+   {
+   	//We concatenate the old message id as a header in the message
+   	//This allows the target to then use this as the JMSCorrelationID of any response message
+   	//thus enabling a distributed request-response pattern.
+   	//Each bridge (if there are more than one) in the chain can concatenate the message id
+   	//So in the case of multiple bridges having routed the message this can be used in a multi-hop
+   	//distributed request/response
+   	if (trace) { log.trace("Adding old message id in Message header"); }
+   	
+   	copyProperties(msg);
+
+   	String val = null;
+   	
+   	val = msg.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
+   	
+   	if (val == null)
+   	{
+   		val = msg.getJMSMessageID();
+   	}
+   	else
+   	{
+   		StringBuffer sb = new StringBuffer(val);
+   		
+   		sb.append(",").append(msg.getJMSMessageID());
+   		
+   		val = sb.toString();
+   	}
+   	
+   	msg.setStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST, val);            	   
+   }
+
+   
+   /*
+    * JMS does not let you add a property on received message without first
+    * calling clearProperties, so we need to save and re-add all the old properties so we
+    * don't lose them!!
+    */
+   private static void copyProperties(Message msg) throws JMSException
+   {   	
+   	Enumeration en = msg.getPropertyNames();
+   	
+   	Map<String, Object> oldProps = null;
+   	
+   	while (en.hasMoreElements())
+   	{
+   		String propName = (String)en.nextElement();
+   		
+   		if (oldProps == null)
+   		{
+   			oldProps = new HashMap<String, Object>();
+   		}
+   		
+   		oldProps.put(propName, msg.getObjectProperty(propName));
+   	}
+   	            	
+   	msg.clearProperties();
+   	
+   	if (oldProps != null)
+   	{
+   		Iterator oldPropsIter = oldProps.entrySet().iterator();
+   		
+   		while (oldPropsIter.hasNext())
+   		{
+   			Map.Entry entry = (Map.Entry)oldPropsIter.next();
+
+   			String propName = (String)entry.getKey();
+
+   			msg.setObjectProperty(propName, entry.getValue());   			
+   		}
+   	}
+   }
+   
+   // Inner classes ---------------------------------------------------------------
+   
+   private class FailureHandler implements Runnable
+   {
+      /**
+       * Start the source connection - note the source connection must not be started before
+       * otherwise messages will be received and ignored
+       */
+      protected void startSourceConnection()
+      {
+         try
+         {
+            sourceConn.start();
+         }
+         catch (JMSException e)
+         {
+            log.error("Failed to start source connection", e);
+         }
+      }
+
+      protected void succeeded()
+      {
+         log.info("Succeeded in reconnecting to servers");
+         
+         synchronized (lock)
+         {
+            failed = false;
+
+            startSourceConnection();
+         }
+      }
+      
+      protected void failed()
+      {
+         //We haven't managed to recreate connections or maxRetries = 0
+         log.warn("Unable to set up connections, bridge will be stopped");
+         
+         try
+         {                  
+            stop();
+         }
+         catch (Exception ignore)
+         {                  
+         }
+      }
+
+      public void run()
+      {
+      	if (trace) { log.trace("Failure handler running"); }
+      	
+         // Clear the messages
+         messages.clear();
+
+         cleanup();
+         
+         boolean ok = false;
+         
+         if (maxRetries > 0 || maxRetries == -1)
+         {
+            log.warn("Will retry after a pause of " + failureRetryInterval + " ms");
+            
+            pause(failureRetryInterval);
+            
+            //Now we try
+            ok = setupJMSObjectsWithRetry();
+         }
+         
+         if (!ok)
+         {
+            failed();
+         }
+         else
+         {
+            succeeded();
+         }    
+      }
+   }
+   
+   private class StartupFailureHandler extends FailureHandler
+   {
+      protected void failed()
+      {
+         // Don't call super
+         log.warn("Unable to set up connections, bridge will not be started");
+      }
+      
+      protected void succeeded()
+      {
+         // Don't call super - a bit ugly in this case but better than taking the lock twice.
+         log.info("Succeeded in connecting to servers");
+         
+         synchronized (lock)
+         {
+            failed = false;
+            started = true;
+            
+            //Start the source connection - note the source connection must not be started before
+            //otherwise messages will be received and ignored
+            
+            try
+            {
+               sourceConn.start();
+            }
+            catch (JMSException e)
+            {
+               log.error("Failed to start source connection", e);
+            }
+         }
+      }
+   }
+   
+   private class BatchTimeChecker implements Runnable
+   {
+      public void run()
+      {
+         if (trace) { log.trace(this + " running"); }
+         
+         synchronized (lock)
+         {
+            while (started)
+            {
+               long toWait = batchExpiryTime - System.currentTimeMillis();
+               
+               if (toWait <= 0)
+               {
+                  if (trace) { log.trace(this + " waited enough"); }
+                  
+                  synchronized (lock)
+                  {              
+                     if (!failed && !messages.isEmpty())
+                     {
+                        if (trace) { log.trace(this + " got some messages so sending batch"); }
+                        
+                        sendBatch();                     
+                        
+                        if (trace) { log.trace(this + " sent batch"); }
+                     }
+                  }
+                  
+                  batchExpiryTime = System.currentTimeMillis() + maxBatchTime;
+               }
+               else
+               {                    
+                  try
+                  {
+                     if (trace) { log.trace(this + " waiting for " + toWait); }
+                     
+                     lock.wait(toWait);
+                     
+                     if (trace) { log.trace(this + " woke up"); }
+                  }
+                  catch (InterruptedException e)
+                  {
+                     //Ignore
+                     if (trace) { log.trace(this + " thread was interrupted"); }
+                  }
+                  
+               }
+            }        
+         }
+      }      
+   }  
+   
+   private class SourceListener implements MessageListener
+   {
+      public void onMessage(Message msg)
+      {
+         synchronized (lock)
+         {
+            if (failed)
+            {
+               //Ignore the message
+               if (trace) { log.trace("JMSBridge has failed so ignoring message"); }
+                              
+               return;
+            }
+            
+            if (trace) { log.trace(this + " received message " + msg); }
+            
+            messages.add(msg);
+            
+            batchExpiryTime = System.currentTimeMillis() + maxBatchTime;            
+            
+            if (trace) { log.trace(this + " rescheduled batchExpiryTime to " + batchExpiryTime); }
+            
+            if (maxBatchSize != -1 && messages.size() >= maxBatchSize)
+            {
+               if (trace) { log.trace(this + " maxBatchSize has been reached so sending batch"); }
+               
+               sendBatch();
+               
+               if (trace) { log.trace(this + " sent batch"); }
+            }                        
+         }
+      }      
+   }   
+   
+   private class BridgeExceptionListener implements ExceptionListener
+   {
+		public void onException(JMSException e)
+		{
+			log.warn("Detected failure on bridge connection");
+			
+			synchronized (lock)
+			{
+				if (failed)
+				{
+					//The failure has already been detected and is being handled
+					if (trace) { log.trace("Failure recovery already in progress"); }
+				}
+				else
+			   {				
+					handleFailure(new FailureHandler());
+			   }
+			}
+		}   	
+   }   
+}

Modified: trunk/tests/src/org/jboss/messaging/tests/integration/cluster/bridge/BridgeStartTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/cluster/bridge/BridgeStartTest.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/cluster/bridge/BridgeStartTest.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -460,7 +460,7 @@
       // Wait a bit
       Thread.sleep(1000);
 
-      // Bridge should be stopped since retries = 0
+      // JMSBridge should be stopped since retries = 0
 
       server1.start();
 

Modified: trunk/tests/src/org/jboss/messaging/tests/integration/cluster/bridge/BridgeTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/cluster/bridge/BridgeTest.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/cluster/bridge/BridgeTest.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -45,7 +45,7 @@
 import org.jboss.messaging.utils.SimpleString;
 
 /**
- * A BridgeTest
+ * A JMSBridgeTest
  *
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * 

Deleted: trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeReconnectionTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeReconnectionTest.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeReconnectionTest.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -1,302 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
- * 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.messaging.tests.integration.jms.bridge;
-
-import org.jboss.messaging.core.logging.Logger;
-import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
-import org.jboss.messaging.jms.bridge.impl.BridgeImpl;
-import org.jboss.messaging.jms.server.impl.JMSServerManagerImpl;
-import org.jboss.messaging.tests.unit.util.InVMContext;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class BridgeReconnectionTest extends BridgeTestBase
-{
-   private static final Logger log = Logger.getLogger(BridgeReconnectionTest.class);
-
-   // Crash and reconnect
-   
-   // Once and only once
-   
-   public void testCrashAndReconnectDestBasic_OnceAndOnlyOnce_P() throws Exception
-   {
-      testCrashAndReconnectDestBasic(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
-   }
-   
-   public void testCrashAndReconnectDestBasic_OnceAndOnlyOnce_NP() throws Exception
-   {
-      testCrashAndReconnectDestBasic(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
-   }
-
-   // dups ok
-
-   public void testCrashAndReconnectDestBasic_DuplicatesOk_P() throws Exception
-   {
-      testCrashAndReconnectDestBasic(QualityOfServiceMode.DUPLICATES_OK, true);
-   }
-
-   public void testCrashAndReconnectDestBasic_DuplicatesOk_NP() throws Exception
-   {
-      testCrashAndReconnectDestBasic(QualityOfServiceMode.DUPLICATES_OK, false);
-   }
-
-   // At most once
-
-   public void testCrashAndReconnectDestBasic_AtMostOnce_P() throws Exception
-   {
-      testCrashAndReconnectDestBasic(QualityOfServiceMode.AT_MOST_ONCE, true);
-   }
-
-   public void testCrashAndReconnectDestBasic_AtMostOnce_NP() throws Exception
-   {
-      testCrashAndReconnectDestBasic(QualityOfServiceMode.AT_MOST_ONCE, false);
-   }
-
-   // Crash tests specific to XA transactions
-
-   public void testCrashAndReconnectDestCrashBeforePrepare_P() throws Exception
-   {
-      testCrashAndReconnectDestCrashBeforePrepare(true);
-   }
-
-   public void testCrashAndReconnectDestCrashBeforePrepare_NP() throws Exception
-   {
-      testCrashAndReconnectDestCrashBeforePrepare(false);
-   }
-   
-   // Crash before bridge is started
-
-   public void testRetryConnectionOnStartup() throws Exception
-   {
-      server1.stop();
-
-      BridgeImpl bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-            null, null, null, null,
-            null, 1000, -1, QualityOfServiceMode.DUPLICATES_OK,
-            10, -1,
-            null, null, false);
-      bridge.setTransactionManager(newTransactionManager());
-
-      try
-      {
-         bridge.start();
-         assertFalse(bridge.isStarted());
-         assertTrue(bridge.isFailed());
-
-         //Restart the server         
-         server1.start();
-         
-         context1 = new InVMContext();
-         jmsServer1 = JMSServerManagerImpl.newJMSServerManagerImpl(server1);
-         jmsServer1.start();
-         jmsServer1.setContext(context1);
-
-         createQueue("targetQueue", 1);
-         setUpAdministeredObjects();
-         
-         Thread.sleep(3000);
-         
-         assertTrue(bridge.isStarted());
-         assertFalse(bridge.isFailed());
-      }
-      finally
-      {
-         try
-         {
-            bridge.stop();
-         }
-         catch (Exception e)
-         {
-            log.error("Failed to stop bridge", e);
-         }
-      }
-   }
-
-   /*
-    * Send some messages
-    * Crash the destination server
-    * Bring the destination server back up
-    * Send some more messages
-    * Verify all messages are received
-    */
-   private void testCrashAndReconnectDestBasic(QualityOfServiceMode qosMode, boolean persistent) throws Exception
-   {
-      BridgeImpl bridge = null;
-         
-      try
-      {   
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 1000, -1, qosMode,
-                  10, -1,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-         bridge.start();
-            
-         final int NUM_MESSAGES = 10;
-         
-         //Send some messages
-         
-         sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2 , persistent);
-         
-         //Verify none are received
-         
-         checkEmpty(targetQueue, 1);
-         
-         //Now crash the dest server
-         
-         log.info("About to crash server");
-         
-         server1.stop();
-         
-         //Wait a while before starting up to simulate the dest being down for a while
-         log.info("Waiting 5 secs before bringing server back up");
-         Thread.sleep(10000);
-         log.info("Done wait");
-         
-         //Restart the server
-         
-         log.info("Restarting server");
-         
-         server1.start();
-         
-         context1 = new InVMContext();
-         jmsServer1 = JMSServerManagerImpl.newJMSServerManagerImpl(server1);
-         jmsServer1.start();
-         jmsServer1.setContext(context1);
-
-         createQueue("targetQueue", 1);
-         
-         setUpAdministeredObjects();
-         
-         //Send some more messages
-         
-         log.info("Sending more messages");
-         
-         sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent);
-         
-         log.info("Sent messages");
-         
-         checkMessagesReceived(cf1, targetQueue, qosMode, NUM_MESSAGES, false);                  
-      }
-      finally
-      {      
-
-         if (bridge != null)
-         {
-            try
-            {
-               bridge.stop();
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to stop bridge", e);
-            }
-         }         
-      }                  
-   }
-
-   /*
-    * Send some messages
-    * Crash the destination server
-    * Set the max batch time such that it will attempt to send the batch while the dest server is down
-    * Bring up the destination server
-    * Send some more messages
-    * Verify all messages are received
-    */
-   private void testCrashAndReconnectDestCrashBeforePrepare(boolean persistent) throws Exception
-   {   
-      BridgeImpl bridge = null;
-            
-      try
-      {
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 1000, -1, QualityOfServiceMode.ONCE_AND_ONLY_ONCE,
-                  10, 5000,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-         
-         final int NUM_MESSAGES = 10;            
-         //Send some messages
-         
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent);
-                  
-         //verify none are received
-         
-         checkEmpty(targetQueue, 1);
-                  
-         //Now crash the dest server
-         
-         log.info("About to crash server");
-         
-         server1.stop();
-         
-         //Wait a while before starting up to simulate the dest being down for a while
-         log.info("Waiting 5 secs before bringing server back up");
-         Thread.sleep(10000);
-         log.info("Done wait");
-         
-         //Restart the server         
-         server1.start();
-         
-         context1 = new InVMContext();
-         jmsServer1 = JMSServerManagerImpl.newJMSServerManagerImpl(server1);
-         jmsServer1.start();
-         jmsServer1.setContext(context1);
-
-         createQueue("targetQueue", 1);
-         
-         setUpAdministeredObjects();
-         
-         sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent);
-                           
-         checkMessagesReceived(cf1, targetQueue, QualityOfServiceMode.ONCE_AND_ONLY_ONCE, NUM_MESSAGES, false);         
-      }
-      finally
-      {      
-                 
-         if (bridge != null)
-         {
-            try
-            {
-               bridge.stop();
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to stop bridge", e);
-            }
-         }
-         
-      }                  
-   }
-   
-   // Inner classes -------------------------------------------------------------------
-   
-}

Deleted: trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeTest.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeTest.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -1,1590 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
- * 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.messaging.tests.integration.jms.bridge;
-
-import org.jboss.messaging.core.logging.Logger;
-import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
-import org.jboss.messaging.jms.bridge.impl.BridgeImpl;
-import org.jboss.messaging.jms.client.JBossMessage;
-
-import javax.jms.Connection;
-import javax.jms.DeliveryMode;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A BridgeTest
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- *
- */
-public class BridgeTest extends BridgeTestBase
-{
-   private static final Logger log = Logger.getLogger(BridgeTest.class);
-   
-   // MaxBatchSize but no MaxBatchTime
-   
-   public void testNoMaxBatchTime_AtMostOnce_P() throws Exception
-   {
-      testNoMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, true);
-   }
-   
-   public void testNoMaxBatchTime_DuplicatesOk_P() throws Exception
-   {
-      testNoMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, true);
-   }
-   
-   public void testNoMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
-   {
-      testNoMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
-   }
-   
-   public void testNoMaxBatchTime_AtMostOnce_NP() throws Exception
-   {
-      testNoMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, false);
-   }
-   
-   public void testNoMaxBatchTime_DuplicatesOk_NP() throws Exception
-   {
-      testNoMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, false);
-   }
-   
-   public void testNoMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
-   {
-      testNoMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
-   }
-   
-   //Same server
-   
-   // MaxBatchSize but no MaxBatchTime
-   
-   public void testNoMaxBatchTimeSameServer_AtMostOnce_P() throws Exception
-   {
-      testNoMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, true);
-   }
-   
-   public void testNoMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception
-   {
-      testNoMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, true);
-   }
-   
-   public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception
-   {
-      testNoMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
-   }
-   
-   public void testNoMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception
-   {
-      testNoMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, false);
-   }
-   
-   public void testNoMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception
-   {
-      testNoMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, false);
-   }
-   
-   public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception
-   {
-      testNoMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
-   }
-   
-   
-   // MaxBatchTime but no MaxBatchSize
-   
-   public void testMaxBatchTime_AtMostOnce_P() throws Exception
-   {
-      this.testMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, true);
-   }
-   
-   public void testMaxBatchTime_DuplicatesOk_P() throws Exception
-   {
-      this.testMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, true);
-   }
-   
-   public void testMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
-   {
-      testMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
-   }
-   
-   public void testMaxBatchTime_AtMostOnce_NP() throws Exception
-   {
-      this.testMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, false);
-   }
-   
-   public void testMaxBatchTime_DuplicatesOk_NP() throws Exception
-   {
-      this.testMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, false);
-   }
-   
-   public void testMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
-   {
-      testMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
-   }
-    
-   // Same server
-   
-   // MaxBatchTime but no MaxBatchSize
-   
-   public void testMaxBatchTimeSameServer_AtMostOnce_P() throws Exception
-   {
-      this.testMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, true);
-   }
-   
-   public void testMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception
-   {
-      this.testMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, true);
-   }
-   
-   public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception
-   {
-      testMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
-   }
-   
-   public void testMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception
-   {
-      this.testMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, false);
-   }
-   
-   public void testMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception
-   {
-      this.testMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, false);
-   }
-   
-   public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception
-   {
-      testMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
-   }
-   
-   // Stress with batch size of 50
-   
-   public void testStress_AtMostOnce_P_50() throws Exception
-   {
-      testStress(QualityOfServiceMode.AT_MOST_ONCE, true, 50);
-   }
-   
-   public void testStress_DuplicatesOk_P_50() throws Exception
-   {
-      testStress(QualityOfServiceMode.DUPLICATES_OK, true, 50);
-   }
-   
-   public void testStress_OnceAndOnlyOnce_P_50() throws Exception
-   {
-      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 50);
-   }
-   
-   public void testStress_AtMostOnce_NP_50() throws Exception
-   {
-      testStress(QualityOfServiceMode.AT_MOST_ONCE, false, 50);
-   }
-   
-   public void testStress_DuplicatesOk_NP_50() throws Exception
-   {
-      testStress(QualityOfServiceMode.DUPLICATES_OK, false, 50);
-   }
-   
-   public void testStress_OnceAndOnlyOnce_NP_50() throws Exception
-   {
-      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 50);
-   }
-   
-   // Stress with batch size of 1
-   
-   public void testStress_AtMostOnce_P_1() throws Exception
-   {
-      testStress(QualityOfServiceMode.AT_MOST_ONCE, true, 1);
-   }
-   
-   public void testStress_DuplicatesOk_P_1() throws Exception
-   {
-      testStress(QualityOfServiceMode.DUPLICATES_OK, true, 1);
-   }
-   
-   public void testStress_OnceAndOnlyOnce_P_1() throws Exception
-   {
-      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 1);
-   }
-   
-   public void testStress_AtMostOnce_NP_1() throws Exception
-   {
-      testStress(QualityOfServiceMode.AT_MOST_ONCE, false, 1);
-   }
-   
-   public void testStress_DuplicatesOk_NP_1() throws Exception
-   {
-      testStress(QualityOfServiceMode.DUPLICATES_OK, false, 1);
-   }
-   
-   public void testStress_OnceAndOnlyOnce_NP_1() throws Exception
-   {
-      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 1);
-   }
-   
-   // Max batch time
-   
-   public void testStressMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
-   {
-   	this.testStressBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 200);
-   }
-   
-   public void testStressMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
-   {
-   	this.testStressBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 200);
-   }
-   
-   
-   // Stress on same server
-   
-   // Stress with batch size of 50
-   
-   public void testStressSameServer_AtMostOnce_P_50() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, true, 50);
-   }
-   
-   public void testStressSameServer_DuplicatesOk_P_50() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, true, 50);
-   }
-   
-   public void testStressSameServer_OnceAndOnlyOnce_P_50() throws Exception
-   {
-      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 50);
-   }
-   
-   public void testStressSameServer_AtMostOnce_NP_50() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, false, 50);
-   }
-   
-   public void testStressSameServer_DuplicatesOk_NP_50() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, false, 50);
-   }
-   
-   public void testStressSameServer_OnceAndOnlyOnce_NP_50() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 50);
-   }
-   
-   // Stress with batch size of 1
-   
-   public void testStressSameServer_AtMostOnce_P_1() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, true, 1);
-   }
-   
-   public void testStressSameServer_DuplicatesOk_P_1() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, true, 1);
-   }
-   
-   public void testStressSameServer_OnceAndOnlyOnce_P_1() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 1);
-   }
-   
-   public void testStressSameServer_AtMostOnce_NP_1() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, false, 1);
-   }
-   
-   public void testStressSameServer_DuplicatesOk_NP_1() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, false, 1);
-   }
-   
-   public void testStressSameServer_OnceAndOnlyOnce_NP_1() throws Exception
-   {
-      testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 1);
-   }
-   
-   public void testParams() throws Exception
-   {
-      BridgeImpl bridge = null;
-      
-      try
-      {               
-         QualityOfServiceMode qosMode = QualityOfServiceMode.AT_MOST_ONCE;
-         
-         int batchSize = 10;
-         
-         int maxBatchTime = -1;
-         
-         String sourceUsername = null;
-         
-         String sourcePassword = null;
-         
-         String destUsername = null;
-         
-         String destPassword = null;
-         
-         String selector = null;
-         
-         long failureRetryInterval = 5000;
-         
-         int maxRetries = 10;
-         
-         String subName = null;
-         
-         String clientID = null;
-         
-         try
-         {
-            bridge= new BridgeImpl(null, cff1, sourceQueueFactory, targetQueueFactory,
-                               sourceUsername, sourcePassword, destUsername, destPassword,
-                               selector, failureRetryInterval, maxRetries, qosMode,
-                               batchSize, maxBatchTime,
-                               subName, clientID, false);
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-         
-         try
-         {
-            bridge= new BridgeImpl(cff0, null, sourceQueueFactory, targetQueueFactory,
-                               sourceUsername, sourcePassword, destUsername, destPassword,
-                               selector, failureRetryInterval, maxRetries, qosMode,
-                               batchSize, maxBatchTime,
-                               subName, clientID, false);
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-         
-         try
-         {
-            bridge= new BridgeImpl(cff0, cff1, null, targetQueueFactory,
-                               sourceUsername, sourcePassword, destUsername, destPassword,
-                               selector, failureRetryInterval, maxRetries, qosMode,
-                               batchSize, maxBatchTime,
-                               subName, clientID, false);
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-         
-         try
-         {
-            bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, null,
-                               sourceUsername, sourcePassword, destUsername, destPassword,
-                               selector, failureRetryInterval, maxRetries, qosMode,
-                               batchSize, maxBatchTime,
-                               subName, clientID, false);
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-         
-         try
-         {
-            bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                               sourceUsername, sourcePassword, destUsername, destPassword,
-                               selector, -2, maxRetries, qosMode,
-                               batchSize, maxBatchTime,
-                               subName, clientID, false);
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-         
-         try
-         {
-            bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                               sourceUsername, sourcePassword, destUsername, destPassword,
-                               selector, -1, 10, qosMode,
-                               batchSize, maxBatchTime,
-                               subName, clientID, false);
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-         
-         try
-         {
-            bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, null,
-                               sourceUsername, sourcePassword, destUsername, destPassword,
-                               selector, failureRetryInterval, maxRetries, qosMode,
-                               0, maxBatchTime,
-                               subName, clientID, false);
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-         
-         try
-         {
-            bridge= new BridgeImpl(cff0, cff1, sourceQueueFactory, null,
-                               sourceUsername, sourcePassword, destUsername, destPassword,
-                               selector, failureRetryInterval, maxRetries, qosMode,
-                               batchSize, -2,
-                               subName, clientID, false);
-         }
-         catch (IllegalArgumentException e)
-         {
-            //Ok
-         }
-      }
-      finally
-      {                      
-         if (bridge != null)
-         {
-            bridge.stop();
-         }
-      }         
-   }
-   
-   public void testSelector() throws Exception
-   {      
-      BridgeImpl bridge = null;
-      
-      Connection connSource = null;
-      
-      Connection connTarget = null;
-            
-      try
-      {
-         final int NUM_MESSAGES = 10;
-         
-         String selector = "vegetable='radish'";
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  selector, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
-                  1, -1,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         connSource = cf0.createConnection();
-         
-         Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageProducer prod = sessSend.createProducer(sourceQueue);
-         
-         for (int i = 0; i < NUM_MESSAGES; i++)
-         {
-            TextMessage tm = sessSend.createTextMessage("message" + i);
-            
-            if (i >= NUM_MESSAGES / 2)
-            {
-               tm.setStringProperty("vegetable", "radish");
-            }
-            else
-            {
-               tm.setStringProperty("vegetable", "cauliflower");
-            }
-            
-            prod.send(tm);
-         }
-         
-         connTarget = cf1.createConnection();
-         
-         Session sessRec = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageConsumer cons = sessRec.createConsumer(targetQueue);
-         
-         connTarget.start();
-                                 
-         for (int i = NUM_MESSAGES / 2 ; i < NUM_MESSAGES; i++)
-         {
-            TextMessage tm = (TextMessage)cons.receive(1000);
-            
-            assertNotNull(tm);
-            
-            assertEquals("message" + i, tm.getText());
-         }
-         
-         Message m = cons.receive(1000);
-         
-         assertNull(m);
-                       
-      }
-      finally
-      {      
-         if (connSource != null)
-         {
-            connSource.close();
-         }
-         
-         if (connTarget != null)
-         {
-            connTarget.close();
-         }
-         
-         if (bridge != null)
-         {
-            bridge.stop();
-         }
-         
-         removeAllMessages(sourceQueue.getQueueName(), 0);
-      }                  
-   }
-   
-   public void testStartBridgeWithJTATransactionAlreadyRunning() throws Exception
-   {  
-      BridgeImpl bridge = null;
-      
-      Transaction toResume = null;
-      
-      Transaction started = null;
-      
-      TransactionManager mgr = newTransactionManager();
-                  
-      try
-      {
-         
-         toResume = mgr.suspend();
-         
-         mgr.begin();
-         
-         started = mgr.getTransaction();         
-           
-         final int NUM_MESSAGES = 10;
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
-                  1, -1,
-                  null, null, false);
-         bridge.setTransactionManager(mgr);
-         bridge.start();
-         
-         this.sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, false);
-            
-         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);                          
-      }
-      finally
-      {      
-         if (started != null)
-         {
-            try
-            {
-               started.rollback();
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to rollback", e);
-            }
-         }
-         
-         if (toResume != null)
-         {
-            try
-            {
-               mgr.resume(toResume);
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to resume", e);
-            }
-         }         
-         if (bridge != null)
-         {
-            bridge.stop();
-         }     
-      }                  
-   }   
-   
-   public void testNonDurableSubscriber() throws Exception
-   { 
-      BridgeImpl bridge = null;
-            
-      try
-      {   
-         final int NUM_MESSAGES = 10;
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
-                  1, -1,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, false);
-         
-         checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);                    
-      }
-      finally
-      {                        
-         if (bridge != null)
-         {
-            bridge.stop();
-         }
-      }                  
-   }
-   
-   public void testDurableSubscriber() throws Exception
-   {
-      BridgeImpl bridge = null;
-            
-      try
-      {
-         final int NUM_MESSAGES = 10;
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
-                  1, -1,
-                  "subTest", "clientid123", false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, true);
-         
-         checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);              
-      }
-      finally
-      {                      
-         if (bridge != null)
-         {
-            bridge.stop();
-         }
-         
-         //Now unsubscribe
-         Connection conn = cf0.createConnection();
-         conn.setClientID("clientid123");
-         Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         sess.unsubscribe("subTest");
-         conn.close();         
-      }                  
-   }
-      
-   public void testMessageIDInHeaderOn() throws Exception
-   {
-   	messageIDInHeader(true);
-   }
-   
-   public void testMessageIDInHeaderOff() throws Exception
-   {
-   	messageIDInHeader(false);
-   }
-   
-   private void messageIDInHeader(boolean on) throws Exception
-   { 
-      BridgeImpl bridge = null;
-      
-      Connection connSource = null;
-      
-      Connection connTarget = null;
-            
-      try
-      {
-         final int NUM_MESSAGES = 10;
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
-                  1, -1,
-                  null, null, on);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-         
-         connSource = cf0.createConnection();
-         
-         connTarget = cf1.createConnection();
-                    
-         log.trace("Sending " + NUM_MESSAGES + " messages");
-         
-         List ids1 = new ArrayList();
-     
-         Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageProducer prod = sessSource.createProducer(sourceQueue);
-         
-         for (int i = 0; i < NUM_MESSAGES; i++)
-         {
-            TextMessage tm = sessSource.createTextMessage("message" + i);
-            
-            //We add some headers to make sure they get passed through ok
-            tm.setStringProperty("wib", "uhuh");
-            tm.setBooleanProperty("cheese", true);
-            tm.setIntProperty("Sausages", 23);
-            
-            //We add some JMSX ones too
-            
-            tm.setStringProperty("JMSXGroupID", "mygroup543");
-            tm.setIntProperty("JMSXGroupSeq", 777);
-            
-            prod.send(tm);
-            
-            ids1.add(tm.getJMSMessageID());
-         }
-
-         log.trace("Sent the first messages");
-         
-         Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageConsumer cons = sessTarget.createConsumer(targetQueue);
-         
-         connTarget.start();
-         
-         List msgs = new ArrayList();
-         
-         for (int i = 0; i < NUM_MESSAGES; i++)
-         {
-            TextMessage tm = (TextMessage)cons.receive(5000);
-            
-            assertNotNull(tm);
-            
-            assertEquals("message" + i, tm.getText());
-            
-            assertEquals("uhuh", tm.getStringProperty("wib"));
-            assertTrue(tm.getBooleanProperty("cheese"));
-            assertEquals(23, tm.getIntProperty("Sausages"));
-            
-            assertEquals("mygroup543", tm.getStringProperty("JMSXGroupID"));
-            assertEquals(777, tm.getIntProperty("JMSXGroupSeq"));
-            
-            if (on)
-            {            
-	            String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
-	            
-	            assertNotNull(header);
-	            
-	            assertEquals(ids1.get(i), header);
-	            
-	            msgs.add(tm);
-            }
-         }
-         
-         if (on)
-         {	         
-	         //Now we send them again back to the source
-	         
-	         Iterator iter = msgs.iterator();
-	         
-	         List ids2 = new ArrayList();
-	         
-	         while (iter.hasNext())
-	         {
-	         	Message msg = (Message)iter.next();
-	         	
-	         	prod.send(msg);
-	            
-	            ids2.add(msg.getJMSMessageID());
-	         }
-	                               
-	         //And consume them again
-	         
-	         for (int i = 0; i < NUM_MESSAGES; i++)
-	         {
-	            TextMessage tm = (TextMessage)cons.receive(5000);
-	            
-	            assertNotNull(tm);
-	            
-	            assertEquals("message" + i, tm.getText());
-	            
-	            assertEquals("uhuh", tm.getStringProperty("wib"));
-	            assertTrue(tm.getBooleanProperty("cheese"));
-	            assertEquals(23, tm.getIntProperty("Sausages"));
-	            
-	            assertEquals("mygroup543", tm.getStringProperty("JMSXGroupID"));
-	            assertEquals(777, tm.getIntProperty("JMSXGroupSeq"));            
-	            
-	            String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
-	            
-	            assertNotNull(header);
-	            
-	            assertEquals(ids1.get(i) + "," + ids2.get(i), header);
-	         }
-         }
-         
-      }
-      finally
-      {                        
-         if (bridge != null)
-         {
-            bridge.stop();
-         }
-         
-         if (connSource != null)
-         {
-            connSource.close();
-         }
-         
-         if (connTarget != null)
-         {
-            connTarget.close();
-         }
-      }                  
-   }
-   
-   
-   public void testPropertiesPreservedPOn() throws Exception
-   {
-   	propertiesPreserved(true, true);
-   }
-   
-   public void testPropertiesPreservedNPoff() throws Exception
-   {
-   	propertiesPreserved(false, true);
-   }
-   
-   public void testPropertiesPreservedNPOn() throws Exception
-   {
-   	propertiesPreserved(false, true);
-   }
-   
-   public void testPropertiesPreservedPoff() throws Exception
-   {
-   	propertiesPreserved(true, true);
-   }
-   
-   private void propertiesPreserved(boolean persistent, boolean messageIDInHeader) throws Exception
-   { 
-      BridgeImpl bridge = null;
-      
-      Connection connSource = null;
-      
-      Connection connTarget = null;
-            
-      try
-      {
-         final int NUM_MESSAGES = 10;
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
-                  1, -1,
-                  null, null, messageIDInHeader);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-         
-         connSource = cf0.createConnection();
-         
-         connTarget = cf1.createConnection();
-                    
-         log.trace("Sending " + NUM_MESSAGES + " messages");
-         
-         Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageConsumer cons = sessTarget.createConsumer(targetQueue);
-         
-         connTarget.start();
-         
-         MessageProducer prod = sessSource.createProducer(sourceQueue);
-         
-         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);  
-         
-         
-         
-         TextMessage tm = sessSource.createTextMessage("blahmessage");
-         
-         prod.setPriority(7);
-         
-         prod.setTimeToLive(1 * 60 * 60 * 1000);
-
-         prod.send(tm);
-         
-         long expiration = tm.getJMSExpiration();
-         
-         assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
-                                 
-         tm = (TextMessage)cons.receive(1000);
-         
-         assertNotNull(tm);
-         
-         assertEquals("blahmessage", tm.getText());
-
-         assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
-         
-         assertEquals(7, tm.getJMSPriority());
-        
-         assertTrue(Math.abs(expiration - tm.getJMSExpiration()) < 100);
-                  
-         Message m = cons.receive(5000);
-         
-         assertNull(m);
-         
-         
-         //Now do one with expiration = 0
-         
-         
-         tm = sessSource.createTextMessage("blahmessage2");
-         
-         prod.setPriority(7);
-         
-         prod.setTimeToLive(0);
-
-         prod.send(tm);
-         
-         assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
-                                 
-         tm = (TextMessage)cons.receive(1000);
-         
-         assertNotNull(tm);
-         
-         assertEquals("blahmessage2", tm.getText());
-
-         assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
-         
-         assertEquals(7, tm.getJMSPriority());
-        
-         assertEquals(0, tm.getJMSExpiration());
-                  
-         m = cons.receive(5000);
-         
-         assertNull(m);            
-         
-         tm = sessSource.createTextMessage("blahmessage3");
-
-         final boolean myBool = false;
-         final byte myByte = (byte)23;
-         final double myDouble = 17625765d;
-         final float myFloat = 87127.23f;
-         final int myInt = 123;
-         final long myLong = 81728712;
-         final short myShort = (short)88;
-         final String myString = "ojweodewj";
-         final String myJMSX = "aardvark";
-
-         tm.setBooleanProperty("mybool", myBool);
-         tm.setByteProperty("mybyte", myByte);
-         tm.setDoubleProperty("mydouble", myDouble);
-         tm.setFloatProperty("myfloat", myFloat);
-         tm.setIntProperty("myint", myInt);
-         tm.setLongProperty("mylong", myLong);
-         tm.setShortProperty("myshort", myShort);
-         tm.setStringProperty("mystring", myString);
-
-         tm.setStringProperty("JMSXMyNaughtyJMSXProperty", myJMSX);
-
-         prod.send(tm);
-
-         tm = (TextMessage)cons.receive(5000);
-
-         assertNotNull(tm);
-
-         assertEquals("blahmessage3", tm.getText());
-
-         assertEquals(myBool, tm.getBooleanProperty("mybool"));
-         assertEquals(myByte, tm.getByteProperty("mybyte"));
-         assertEquals(myDouble, tm.getDoubleProperty("mydouble"));
-         assertEquals(myFloat, tm.getFloatProperty("myfloat"));
-         assertEquals(myInt, tm.getIntProperty("myint"));
-         assertEquals(myLong, tm.getLongProperty("mylong"));
-         assertEquals(myShort, tm.getShortProperty("myshort"));
-         assertEquals(myString, tm.getStringProperty("mystring"));
-         assertEquals(myJMSX, tm.getStringProperty("JMSXMyNaughtyJMSXProperty"));
-
-         m = cons.receive(5000);
-         
-      }
-      finally
-      {                        
-         if (bridge != null)
-         {
-            bridge.stop();
-         }
-         
-         if (connSource != null)
-         {
-            connSource.close();
-         }
-         
-         if (connTarget != null)
-         {
-            connTarget.close();
-         }
-      }                  
-   }
-   
-   public void testNoMessageIDInHeader() throws Exception
-   { 
-      BridgeImpl bridge = null;
-      
-      Connection connSource = null;
-      
-      Connection connTarget = null;
-            
-      try
-      {
-         final int NUM_MESSAGES = 10;
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
-                  1, -1,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-         
-         connSource = cf0.createConnection();
-         
-         connTarget = cf1.createConnection();
-                    
-         log.trace("Sending " + NUM_MESSAGES + " messages");
-         
-         Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageProducer prod = sessSource.createProducer(sourceQueue);
-         
-         for (int i = 0; i < NUM_MESSAGES; i++)
-         {
-            TextMessage tm = sessSource.createTextMessage("message" + i);
-            
-            //We add some headers to make sure they get passed through ok
-            tm.setStringProperty("wib", "uhuh");
-            tm.setBooleanProperty("cheese", true);
-            tm.setIntProperty("Sausages", 23);
-            
-            prod.send(tm);
-         }
-
-         log.trace("Sent the first messages");
-         
-         Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageConsumer cons = sessTarget.createConsumer(targetQueue);
-         
-         connTarget.start();
-         
-         for (int i = 0; i < NUM_MESSAGES; i++)
-         {
-            TextMessage tm = (TextMessage)cons.receive(5000);
-            
-            assertNotNull(tm);
-            
-            assertEquals("message" + i, tm.getText());
-            
-            assertEquals("uhuh", tm.getStringProperty("wib"));
-            assertTrue(tm.getBooleanProperty("cheese"));
-            assertEquals(23, tm.getIntProperty("Sausages"));
-            
-            String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
-            
-            assertNull(header);
-         }                 
-      }
-      finally
-      {                        
-         if (bridge != null)
-         {
-            bridge.stop();
-         }
-         
-         if (connSource != null)
-         {
-            connSource.close();
-         }
-         
-         if (connTarget != null)
-         {
-            connTarget.close();
-         }
-      }                  
-   }
-   
-   
-   // Private -------------------------------------------------------------------------------
-             
-   private void testStress(QualityOfServiceMode qosMode, boolean persistent, int batchSize) throws Exception
-   {
-      Connection connSource = null;
-      
-      BridgeImpl bridge = null;
-      
-      Thread t = null;
-            
-      try
-      {      
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, qosMode,
-                  batchSize, -1,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         connSource = cf0.createConnection();
-         
-         Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageProducer prod = sessSend.createProducer(sourceQueue);
-         
-         final int NUM_MESSAGES = 250;
-         
-         StressSender sender = new StressSender();
-         sender.sess = sessSend;
-         sender.prod = prod;
-         sender.numMessages = NUM_MESSAGES;
-         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-                          
-         t = new Thread(sender);
-         
-         t.start();
-         
-         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
-                                              
-         t.join();
-         
-         if (sender.ex != null)
-         {
-            //An error occurred during the send
-            throw sender.ex;
-         }
-           
-      }
-      finally
-      {    
-         if (t != null)
-         {
-            t.join(10000);
-         }
-         
-         if (connSource != null)
-         {
-            try
-            {
-               connSource.close();
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to close connection", e);
-            }
-         }                
-         
-         if (bridge != null)
-         {
-            bridge.stop();
-         }                  
-      }      
-   }
-   
-   private void testStressBatchTime(QualityOfServiceMode qosMode, boolean persistent, int maxBatchTime) throws Exception
-   {
-      Connection connSource = null;
-      
-      BridgeImpl bridge = null;
-      
-      Thread t = null;
-            
-      try
-      {      
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, qosMode,
-                  2, maxBatchTime,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         connSource = cf0.createConnection();
-         
-         Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageProducer prod = sessSend.createProducer(sourceQueue);
-         
-         final int NUM_MESSAGES = 5000;
-         
-         StressSender sender = new StressSender();
-         sender.sess = sessSend;
-         sender.prod = prod;
-         sender.numMessages = NUM_MESSAGES;
-         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-                          
-         t = new Thread(sender);
-         
-         t.start();
-         
-         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
-                                              
-         t.join();
-         
-         if (sender.ex != null)
-         {
-            //An error occurred during the send
-            throw sender.ex;
-         }
-           
-      }
-      finally
-      {    
-         if (t != null)
-         {
-            t.join(10000);
-         }
-         
-         if (connSource != null)
-         {
-            try
-            {
-               connSource.close();
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to close connection", e);
-            }
-         }                
-         
-         if (bridge != null)
-         {
-            bridge.stop();
-         }                  
-      }      
-   }
-   
-   //Both source and destination on same rm
-   private void testStressSameServer(QualityOfServiceMode qosMode, boolean persistent, int batchSize) throws Exception
-   {
-      Connection connSource = null;
-      
-      BridgeImpl bridge = null;
-      
-      Thread t = null;
-            
-      try
-      {  
-         bridge = new BridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, qosMode,
-                  batchSize, -1,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         connSource = cf0.createConnection();
-         
-         Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
-         
-         MessageProducer prod = sessSend.createProducer(sourceQueue);
-         
-         final int NUM_MESSAGES = 2000;
-         
-         StressSender sender = new StressSender();
-         sender.sess = sessSend;
-         sender.prod = prod;
-         sender.numMessages = NUM_MESSAGES;
-         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-                          
-         t = new Thread(sender);
-         
-         t.start();
-         
-         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
-                         
-         t.join();
-         
-         if (sender.ex != null)
-         {
-            //An error occurred during the send
-            throw sender.ex;
-         }
-           
-      }
-      finally
-      {    
-         if (t != null)
-         {
-            t.join(10000);
-         }
-         
-         if (connSource != null)
-         {
-            try
-            {
-               connSource.close();
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to close connection", e);
-            }
-         }
-                          
-         if (bridge != null)
-         {
-            bridge.stop();
-         }
-      }      
-   }
-   
-      
-   private void testNoMaxBatchTime(QualityOfServiceMode qosMode, boolean persistent) throws Exception
-   {
-      BridgeImpl bridge = null;
-            
-      try
-      {
-         final int NUM_MESSAGES = 10;
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, qosMode,
-                  NUM_MESSAGES, -1,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         //Send half the messges
-
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent);
-                         
-         //Verify none are received
-         
-         this.checkEmpty(targetQueue, 1);
-         
-         //Send the other half
-         
-         this.sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent);
-         
-         //This should now be receivable
-         
-         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
-         
-         //Send another batch with one more than batch size
-         
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, persistent);
-                  
-         //Make sure only batch size are received
-         
-         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
-         
-         //Final batch
-         
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, persistent);
-         
-         this.checkAllMessageReceivedInOrder(cf1, targetQueue, NUM_MESSAGES, 1);
-         
-         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES - 1);
-      }
-      finally
-      {      
-         if (bridge != null)
-         {
-            log.info("Stopping bridge");
-            bridge.stop();
-         }         
-      }                  
-   }
-   
-   private void testNoMaxBatchTimeSameServer(QualityOfServiceMode qosMode, boolean persistent) throws Exception
-   {
-      BridgeImpl bridge = null;
-            
-      try
-      {
-         final int NUM_MESSAGES = 10;
-         
-         bridge = new BridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory,
-                  null, null, null, null,
-                  null, 5000, 10, qosMode,
-                  NUM_MESSAGES, -1,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent);
-         
-         this.checkEmpty(targetQueue, 1);                
-         
-         //Send the other half
-         
-         this.sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES /2, persistent);
-         
-         
-         //This should now be receivable
-         
-         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
-         
-         this.checkEmpty(localTargetQueue, 0);
-         
-         this.checkEmpty(sourceQueue, 0);
-         
-         //Send another batch with one more than batch size
-         
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, persistent);
-         
-         //Make sure only batch size are received
-         
-         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
-         
-         //Final batch
-         
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, persistent);
-         
-         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, NUM_MESSAGES, 1);
-         
-         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES - 1);
-      }
-      finally
-      {               
-         if (bridge != null)
-         {
-            bridge.stop();
-         }                  
-      }                  
-   }
-   
-   private void testMaxBatchTime(QualityOfServiceMode qosMode, boolean persistent) throws Exception
-   {
-      BridgeImpl bridge = null;
-            
-      try
-      {
-         final long MAX_BATCH_TIME = 3000;
-         
-         final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
-         
-         bridge = new BridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
-                  null, null, null, null,
-                  null, 3000, 10, qosMode,
-                  MAX_BATCH_SIZE, MAX_BATCH_TIME,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-            
-         final int NUM_MESSAGES = 10;
-         
-         //Send some message
-
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES, persistent);                 
-         
-         //Verify none are received
-         
-         this.checkEmpty(targetQueue, 1);
-         
-         //Messages should now be receivable
-         
-         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);         
-      }
-      finally
-      {      
-         if (bridge != null)
-         {
-            bridge.stop();
-         }         
-      }                  
-   }
-   
-   private void testMaxBatchTimeSameServer(QualityOfServiceMode qosMode, boolean persistent) throws Exception
-   {
-      BridgeImpl bridge = null;
-            
-      try
-      {
-         final long MAX_BATCH_TIME = 3000;
-         
-         final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
-         
-         bridge = new BridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory,
-                  null, null, null, null,
-                  null, 3000, 10, qosMode,
-                  MAX_BATCH_SIZE, MAX_BATCH_TIME,
-                  null, null, false);
-         bridge.setTransactionManager(newTransactionManager());
-
-         bridge.start();
-         
-         final int NUM_MESSAGES = 10;
-         
-         //Send some message
-
-         //Send some message
-
-         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES, persistent);                 
-         
-         //Verify none are received
-         
-         this.checkEmpty(localTargetQueue, 0);;
-         
-         //Messages should now be receivable
-         
-         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
-      }
-      finally
-      {              
-         if (bridge != null)
-         {
-            bridge.stop();
-         }        
-      }                  
-   }
-   
-   
-   // Inner classes -------------------------------------------------------------------
-   
-   private static class StressSender implements Runnable
-   {
-      int numMessages;
-      
-      Session sess;
-      
-      MessageProducer prod;
-      
-      Exception ex;
-      
-      public void run()
-      {
-         try
-         {
-            for (int i = 0; i < numMessages; i++)
-            {
-               TextMessage tm = sess.createTextMessage("message" + i);
-                                            
-               prod.send(tm);
-               
-               log.trace("Sent message " + i);
-            }
-         }
-         catch (Exception e)
-         {
-            log.error("Failed to send", e);
-            ex = e;
-         }         
-      }
-      
-   } 
-}

Copied: trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java (from rev 6295, trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeReconnectionTest.java)
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -0,0 +1,302 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * 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.messaging.tests.integration.jms.bridge;
+
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
+import org.jboss.messaging.jms.bridge.impl.JMSBridgeImpl;
+import org.jboss.messaging.jms.server.impl.JMSServerManagerImpl;
+import org.jboss.messaging.tests.unit.util.InVMContext;
+
+/**
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class JMSBridgeReconnectionTest extends BridgeTestBase
+{
+   private static final Logger log = Logger.getLogger(JMSBridgeReconnectionTest.class);
+
+   // Crash and reconnect
+   
+   // Once and only once
+   
+   public void testCrashAndReconnectDestBasic_OnceAndOnlyOnce_P() throws Exception
+   {
+      testCrashAndReconnectDestBasic(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
+   }
+   
+   public void testCrashAndReconnectDestBasic_OnceAndOnlyOnce_NP() throws Exception
+   {
+      testCrashAndReconnectDestBasic(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
+   }
+
+   // dups ok
+
+   public void testCrashAndReconnectDestBasic_DuplicatesOk_P() throws Exception
+   {
+      testCrashAndReconnectDestBasic(QualityOfServiceMode.DUPLICATES_OK, true);
+   }
+
+   public void testCrashAndReconnectDestBasic_DuplicatesOk_NP() throws Exception
+   {
+      testCrashAndReconnectDestBasic(QualityOfServiceMode.DUPLICATES_OK, false);
+   }
+
+   // At most once
+
+   public void testCrashAndReconnectDestBasic_AtMostOnce_P() throws Exception
+   {
+      testCrashAndReconnectDestBasic(QualityOfServiceMode.AT_MOST_ONCE, true);
+   }
+
+   public void testCrashAndReconnectDestBasic_AtMostOnce_NP() throws Exception
+   {
+      testCrashAndReconnectDestBasic(QualityOfServiceMode.AT_MOST_ONCE, false);
+   }
+
+   // Crash tests specific to XA transactions
+
+   public void testCrashAndReconnectDestCrashBeforePrepare_P() throws Exception
+   {
+      testCrashAndReconnectDestCrashBeforePrepare(true);
+   }
+
+   public void testCrashAndReconnectDestCrashBeforePrepare_NP() throws Exception
+   {
+      testCrashAndReconnectDestCrashBeforePrepare(false);
+   }
+   
+   // Crash before bridge is started
+
+   public void testRetryConnectionOnStartup() throws Exception
+   {
+      server1.stop();
+
+      JMSBridgeImpl bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+            null, null, null, null,
+            null, 1000, -1, QualityOfServiceMode.DUPLICATES_OK,
+            10, -1,
+            null, null, false);
+      bridge.setTransactionManager(newTransactionManager());
+
+      try
+      {
+         bridge.start();
+         assertFalse(bridge.isStarted());
+         assertTrue(bridge.isFailed());
+
+         //Restart the server         
+         server1.start();
+         
+         context1 = new InVMContext();
+         jmsServer1 = JMSServerManagerImpl.newJMSServerManagerImpl(server1);
+         jmsServer1.start();
+         jmsServer1.setContext(context1);
+
+         createQueue("targetQueue", 1);
+         setUpAdministeredObjects();
+         
+         Thread.sleep(3000);
+         
+         assertTrue(bridge.isStarted());
+         assertFalse(bridge.isFailed());
+      }
+      finally
+      {
+         try
+         {
+            bridge.stop();
+         }
+         catch (Exception e)
+         {
+            log.error("Failed to stop bridge", e);
+         }
+      }
+   }
+
+   /*
+    * Send some messages
+    * Crash the destination server
+    * Bring the destination server back up
+    * Send some more messages
+    * Verify all messages are received
+    */
+   private void testCrashAndReconnectDestBasic(QualityOfServiceMode qosMode, boolean persistent) throws Exception
+   {
+      JMSBridgeImpl bridge = null;
+         
+      try
+      {   
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 1000, -1, qosMode,
+                  10, -1,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+         bridge.start();
+            
+         final int NUM_MESSAGES = 10;
+         
+         //Send some messages
+         
+         sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2 , persistent);
+         
+         //Verify none are received
+         
+         checkEmpty(targetQueue, 1);
+         
+         //Now crash the dest server
+         
+         log.info("About to crash server");
+         
+         server1.stop();
+         
+         //Wait a while before starting up to simulate the dest being down for a while
+         log.info("Waiting 5 secs before bringing server back up");
+         Thread.sleep(10000);
+         log.info("Done wait");
+         
+         //Restart the server
+         
+         log.info("Restarting server");
+         
+         server1.start();
+         
+         context1 = new InVMContext();
+         jmsServer1 = JMSServerManagerImpl.newJMSServerManagerImpl(server1);
+         jmsServer1.start();
+         jmsServer1.setContext(context1);
+
+         createQueue("targetQueue", 1);
+         
+         setUpAdministeredObjects();
+         
+         //Send some more messages
+         
+         log.info("Sending more messages");
+         
+         sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent);
+         
+         log.info("Sent messages");
+         
+         checkMessagesReceived(cf1, targetQueue, qosMode, NUM_MESSAGES, false);                  
+      }
+      finally
+      {      
+
+         if (bridge != null)
+         {
+            try
+            {
+               bridge.stop();
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to stop bridge", e);
+            }
+         }         
+      }                  
+   }
+
+   /*
+    * Send some messages
+    * Crash the destination server
+    * Set the max batch time such that it will attempt to send the batch while the dest server is down
+    * Bring up the destination server
+    * Send some more messages
+    * Verify all messages are received
+    */
+   private void testCrashAndReconnectDestCrashBeforePrepare(boolean persistent) throws Exception
+   {   
+      JMSBridgeImpl bridge = null;
+            
+      try
+      {
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 1000, -1, QualityOfServiceMode.ONCE_AND_ONLY_ONCE,
+                  10, 5000,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+         
+         final int NUM_MESSAGES = 10;            
+         //Send some messages
+         
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent);
+                  
+         //verify none are received
+         
+         checkEmpty(targetQueue, 1);
+                  
+         //Now crash the dest server
+         
+         log.info("About to crash server");
+         
+         server1.stop();
+         
+         //Wait a while before starting up to simulate the dest being down for a while
+         log.info("Waiting 5 secs before bringing server back up");
+         Thread.sleep(10000);
+         log.info("Done wait");
+         
+         //Restart the server         
+         server1.start();
+         
+         context1 = new InVMContext();
+         jmsServer1 = JMSServerManagerImpl.newJMSServerManagerImpl(server1);
+         jmsServer1.start();
+         jmsServer1.setContext(context1);
+
+         createQueue("targetQueue", 1);
+         
+         setUpAdministeredObjects();
+         
+         sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent);
+                           
+         checkMessagesReceived(cf1, targetQueue, QualityOfServiceMode.ONCE_AND_ONLY_ONCE, NUM_MESSAGES, false);         
+      }
+      finally
+      {      
+                 
+         if (bridge != null)
+         {
+            try
+            {
+               bridge.stop();
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to stop bridge", e);
+            }
+         }
+         
+      }                  
+   }
+   
+   // Inner classes -------------------------------------------------------------------
+   
+}

Copied: trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/JMSBridgeTest.java (from rev 6295, trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/BridgeTest.java)
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/JMSBridgeTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/integration/jms/bridge/JMSBridgeTest.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -0,0 +1,1590 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * 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.messaging.tests.integration.jms.bridge;
+
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
+import org.jboss.messaging.jms.bridge.impl.JMSBridgeImpl;
+import org.jboss.messaging.jms.client.JBossMessage;
+
+import javax.jms.Connection;
+import javax.jms.DeliveryMode;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A JMSBridgeTest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public class JMSBridgeTest extends BridgeTestBase
+{
+   private static final Logger log = Logger.getLogger(JMSBridgeTest.class);
+   
+   // MaxBatchSize but no MaxBatchTime
+   
+   public void testNoMaxBatchTime_AtMostOnce_P() throws Exception
+   {
+      testNoMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, true);
+   }
+   
+   public void testNoMaxBatchTime_DuplicatesOk_P() throws Exception
+   {
+      testNoMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, true);
+   }
+   
+   public void testNoMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
+   {
+      testNoMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
+   }
+   
+   public void testNoMaxBatchTime_AtMostOnce_NP() throws Exception
+   {
+      testNoMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, false);
+   }
+   
+   public void testNoMaxBatchTime_DuplicatesOk_NP() throws Exception
+   {
+      testNoMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, false);
+   }
+   
+   public void testNoMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
+   {
+      testNoMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
+   }
+   
+   //Same server
+   
+   // MaxBatchSize but no MaxBatchTime
+   
+   public void testNoMaxBatchTimeSameServer_AtMostOnce_P() throws Exception
+   {
+      testNoMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, true);
+   }
+   
+   public void testNoMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception
+   {
+      testNoMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, true);
+   }
+   
+   public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception
+   {
+      testNoMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
+   }
+   
+   public void testNoMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception
+   {
+      testNoMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, false);
+   }
+   
+   public void testNoMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception
+   {
+      testNoMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, false);
+   }
+   
+   public void testNoMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception
+   {
+      testNoMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
+   }
+   
+   
+   // MaxBatchTime but no MaxBatchSize
+   
+   public void testMaxBatchTime_AtMostOnce_P() throws Exception
+   {
+      this.testMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, true);
+   }
+   
+   public void testMaxBatchTime_DuplicatesOk_P() throws Exception
+   {
+      this.testMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, true);
+   }
+   
+   public void testMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
+   {
+      testMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
+   }
+   
+   public void testMaxBatchTime_AtMostOnce_NP() throws Exception
+   {
+      this.testMaxBatchTime(QualityOfServiceMode.AT_MOST_ONCE, false);
+   }
+   
+   public void testMaxBatchTime_DuplicatesOk_NP() throws Exception
+   {
+      this.testMaxBatchTime(QualityOfServiceMode.DUPLICATES_OK, false);
+   }
+   
+   public void testMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
+   {
+      testMaxBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
+   }
+    
+   // Same server
+   
+   // MaxBatchTime but no MaxBatchSize
+   
+   public void testMaxBatchTimeSameServer_AtMostOnce_P() throws Exception
+   {
+      this.testMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, true);
+   }
+   
+   public void testMaxBatchTimeSameServer_DuplicatesOk_P() throws Exception
+   {
+      this.testMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, true);
+   }
+   
+   public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_P() throws Exception
+   {
+      testMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true);
+   }
+   
+   public void testMaxBatchTimeSameServer_AtMostOnce_NP() throws Exception
+   {
+      this.testMaxBatchTimeSameServer(QualityOfServiceMode.AT_MOST_ONCE, false);
+   }
+   
+   public void testMaxBatchTimeSameServer_DuplicatesOk_NP() throws Exception
+   {
+      this.testMaxBatchTimeSameServer(QualityOfServiceMode.DUPLICATES_OK, false);
+   }
+   
+   public void testMaxBatchTimeSameServer_OnceAndOnlyOnce_NP() throws Exception
+   {
+      testMaxBatchTimeSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false);
+   }
+   
+   // Stress with batch size of 50
+   
+   public void testStress_AtMostOnce_P_50() throws Exception
+   {
+      testStress(QualityOfServiceMode.AT_MOST_ONCE, true, 50);
+   }
+   
+   public void testStress_DuplicatesOk_P_50() throws Exception
+   {
+      testStress(QualityOfServiceMode.DUPLICATES_OK, true, 50);
+   }
+   
+   public void testStress_OnceAndOnlyOnce_P_50() throws Exception
+   {
+      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 50);
+   }
+   
+   public void testStress_AtMostOnce_NP_50() throws Exception
+   {
+      testStress(QualityOfServiceMode.AT_MOST_ONCE, false, 50);
+   }
+   
+   public void testStress_DuplicatesOk_NP_50() throws Exception
+   {
+      testStress(QualityOfServiceMode.DUPLICATES_OK, false, 50);
+   }
+   
+   public void testStress_OnceAndOnlyOnce_NP_50() throws Exception
+   {
+      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 50);
+   }
+   
+   // Stress with batch size of 1
+   
+   public void testStress_AtMostOnce_P_1() throws Exception
+   {
+      testStress(QualityOfServiceMode.AT_MOST_ONCE, true, 1);
+   }
+   
+   public void testStress_DuplicatesOk_P_1() throws Exception
+   {
+      testStress(QualityOfServiceMode.DUPLICATES_OK, true, 1);
+   }
+   
+   public void testStress_OnceAndOnlyOnce_P_1() throws Exception
+   {
+      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 1);
+   }
+   
+   public void testStress_AtMostOnce_NP_1() throws Exception
+   {
+      testStress(QualityOfServiceMode.AT_MOST_ONCE, false, 1);
+   }
+   
+   public void testStress_DuplicatesOk_NP_1() throws Exception
+   {
+      testStress(QualityOfServiceMode.DUPLICATES_OK, false, 1);
+   }
+   
+   public void testStress_OnceAndOnlyOnce_NP_1() throws Exception
+   {
+      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 1);
+   }
+   
+   // Max batch time
+   
+   public void testStressMaxBatchTime_OnceAndOnlyOnce_NP() throws Exception
+   {
+   	this.testStressBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 200);
+   }
+   
+   public void testStressMaxBatchTime_OnceAndOnlyOnce_P() throws Exception
+   {
+   	this.testStressBatchTime(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 200);
+   }
+   
+   
+   // Stress on same server
+   
+   // Stress with batch size of 50
+   
+   public void testStressSameServer_AtMostOnce_P_50() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, true, 50);
+   }
+   
+   public void testStressSameServer_DuplicatesOk_P_50() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, true, 50);
+   }
+   
+   public void testStressSameServer_OnceAndOnlyOnce_P_50() throws Exception
+   {
+      testStress(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 50);
+   }
+   
+   public void testStressSameServer_AtMostOnce_NP_50() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, false, 50);
+   }
+   
+   public void testStressSameServer_DuplicatesOk_NP_50() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, false, 50);
+   }
+   
+   public void testStressSameServer_OnceAndOnlyOnce_NP_50() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 50);
+   }
+   
+   // Stress with batch size of 1
+   
+   public void testStressSameServer_AtMostOnce_P_1() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, true, 1);
+   }
+   
+   public void testStressSameServer_DuplicatesOk_P_1() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, true, 1);
+   }
+   
+   public void testStressSameServer_OnceAndOnlyOnce_P_1() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, true, 1);
+   }
+   
+   public void testStressSameServer_AtMostOnce_NP_1() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.AT_MOST_ONCE, false, 1);
+   }
+   
+   public void testStressSameServer_DuplicatesOk_NP_1() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.DUPLICATES_OK, false, 1);
+   }
+   
+   public void testStressSameServer_OnceAndOnlyOnce_NP_1() throws Exception
+   {
+      testStressSameServer(QualityOfServiceMode.ONCE_AND_ONLY_ONCE, false, 1);
+   }
+   
+   public void testParams() throws Exception
+   {
+      JMSBridgeImpl bridge = null;
+      
+      try
+      {               
+         QualityOfServiceMode qosMode = QualityOfServiceMode.AT_MOST_ONCE;
+         
+         int batchSize = 10;
+         
+         int maxBatchTime = -1;
+         
+         String sourceUsername = null;
+         
+         String sourcePassword = null;
+         
+         String destUsername = null;
+         
+         String destPassword = null;
+         
+         String selector = null;
+         
+         long failureRetryInterval = 5000;
+         
+         int maxRetries = 10;
+         
+         String subName = null;
+         
+         String clientID = null;
+         
+         try
+         {
+            bridge= new JMSBridgeImpl(null, cff1, sourceQueueFactory, targetQueueFactory,
+                               sourceUsername, sourcePassword, destUsername, destPassword,
+                               selector, failureRetryInterval, maxRetries, qosMode,
+                               batchSize, maxBatchTime,
+                               subName, clientID, false);
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+         try
+         {
+            bridge= new JMSBridgeImpl(cff0, null, sourceQueueFactory, targetQueueFactory,
+                               sourceUsername, sourcePassword, destUsername, destPassword,
+                               selector, failureRetryInterval, maxRetries, qosMode,
+                               batchSize, maxBatchTime,
+                               subName, clientID, false);
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+         try
+         {
+            bridge= new JMSBridgeImpl(cff0, cff1, null, targetQueueFactory,
+                               sourceUsername, sourcePassword, destUsername, destPassword,
+                               selector, failureRetryInterval, maxRetries, qosMode,
+                               batchSize, maxBatchTime,
+                               subName, clientID, false);
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+         try
+         {
+            bridge= new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, null,
+                               sourceUsername, sourcePassword, destUsername, destPassword,
+                               selector, failureRetryInterval, maxRetries, qosMode,
+                               batchSize, maxBatchTime,
+                               subName, clientID, false);
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+         try
+         {
+            bridge= new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                               sourceUsername, sourcePassword, destUsername, destPassword,
+                               selector, -2, maxRetries, qosMode,
+                               batchSize, maxBatchTime,
+                               subName, clientID, false);
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+         try
+         {
+            bridge= new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                               sourceUsername, sourcePassword, destUsername, destPassword,
+                               selector, -1, 10, qosMode,
+                               batchSize, maxBatchTime,
+                               subName, clientID, false);
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+         try
+         {
+            bridge= new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, null,
+                               sourceUsername, sourcePassword, destUsername, destPassword,
+                               selector, failureRetryInterval, maxRetries, qosMode,
+                               0, maxBatchTime,
+                               subName, clientID, false);
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+         
+         try
+         {
+            bridge= new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, null,
+                               sourceUsername, sourcePassword, destUsername, destPassword,
+                               selector, failureRetryInterval, maxRetries, qosMode,
+                               batchSize, -2,
+                               subName, clientID, false);
+         }
+         catch (IllegalArgumentException e)
+         {
+            //Ok
+         }
+      }
+      finally
+      {                      
+         if (bridge != null)
+         {
+            bridge.stop();
+         }
+      }         
+   }
+   
+   public void testSelector() throws Exception
+   {      
+      JMSBridgeImpl bridge = null;
+      
+      Connection connSource = null;
+      
+      Connection connTarget = null;
+            
+      try
+      {
+         final int NUM_MESSAGES = 10;
+         
+         String selector = "vegetable='radish'";
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  selector, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
+                  1, -1,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         connSource = cf0.createConnection();
+         
+         Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageProducer prod = sessSend.createProducer(sourceQueue);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = sessSend.createTextMessage("message" + i);
+            
+            if (i >= NUM_MESSAGES / 2)
+            {
+               tm.setStringProperty("vegetable", "radish");
+            }
+            else
+            {
+               tm.setStringProperty("vegetable", "cauliflower");
+            }
+            
+            prod.send(tm);
+         }
+         
+         connTarget = cf1.createConnection();
+         
+         Session sessRec = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageConsumer cons = sessRec.createConsumer(targetQueue);
+         
+         connTarget.start();
+                                 
+         for (int i = NUM_MESSAGES / 2 ; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = (TextMessage)cons.receive(1000);
+            
+            assertNotNull(tm);
+            
+            assertEquals("message" + i, tm.getText());
+         }
+         
+         Message m = cons.receive(1000);
+         
+         assertNull(m);
+                       
+      }
+      finally
+      {      
+         if (connSource != null)
+         {
+            connSource.close();
+         }
+         
+         if (connTarget != null)
+         {
+            connTarget.close();
+         }
+         
+         if (bridge != null)
+         {
+            bridge.stop();
+         }
+         
+         removeAllMessages(sourceQueue.getQueueName(), 0);
+      }                  
+   }
+   
+   public void testStartBridgeWithJTATransactionAlreadyRunning() throws Exception
+   {  
+      JMSBridgeImpl bridge = null;
+      
+      Transaction toResume = null;
+      
+      Transaction started = null;
+      
+      TransactionManager mgr = newTransactionManager();
+                  
+      try
+      {
+         
+         toResume = mgr.suspend();
+         
+         mgr.begin();
+         
+         started = mgr.getTransaction();         
+           
+         final int NUM_MESSAGES = 10;
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
+                  1, -1,
+                  null, null, false);
+         bridge.setTransactionManager(mgr);
+         bridge.start();
+         
+         this.sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, false);
+            
+         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);                          
+      }
+      finally
+      {      
+         if (started != null)
+         {
+            try
+            {
+               started.rollback();
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to rollback", e);
+            }
+         }
+         
+         if (toResume != null)
+         {
+            try
+            {
+               mgr.resume(toResume);
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to resume", e);
+            }
+         }         
+         if (bridge != null)
+         {
+            bridge.stop();
+         }     
+      }                  
+   }   
+   
+   public void testNonDurableSubscriber() throws Exception
+   { 
+      JMSBridgeImpl bridge = null;
+            
+      try
+      {   
+         final int NUM_MESSAGES = 10;
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
+                  1, -1,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, false);
+         
+         checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);                    
+      }
+      finally
+      {                        
+         if (bridge != null)
+         {
+            bridge.stop();
+         }
+      }                  
+   }
+   
+   public void testDurableSubscriber() throws Exception
+   {
+      JMSBridgeImpl bridge = null;
+            
+      try
+      {
+         final int NUM_MESSAGES = 10;
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceTopicFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
+                  1, -1,
+                  "subTest", "clientid123", false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         sendMessages(cf0, sourceTopic, 0, NUM_MESSAGES, true);
+         
+         checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);              
+      }
+      finally
+      {                      
+         if (bridge != null)
+         {
+            bridge.stop();
+         }
+         
+         //Now unsubscribe
+         Connection conn = cf0.createConnection();
+         conn.setClientID("clientid123");
+         Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         sess.unsubscribe("subTest");
+         conn.close();         
+      }                  
+   }
+      
+   public void testMessageIDInHeaderOn() throws Exception
+   {
+   	messageIDInHeader(true);
+   }
+   
+   public void testMessageIDInHeaderOff() throws Exception
+   {
+   	messageIDInHeader(false);
+   }
+   
+   private void messageIDInHeader(boolean on) throws Exception
+   { 
+      JMSBridgeImpl bridge = null;
+      
+      Connection connSource = null;
+      
+      Connection connTarget = null;
+            
+      try
+      {
+         final int NUM_MESSAGES = 10;
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
+                  1, -1,
+                  null, null, on);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+         
+         connSource = cf0.createConnection();
+         
+         connTarget = cf1.createConnection();
+                    
+         log.trace("Sending " + NUM_MESSAGES + " messages");
+         
+         List ids1 = new ArrayList();
+     
+         Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageProducer prod = sessSource.createProducer(sourceQueue);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = sessSource.createTextMessage("message" + i);
+            
+            //We add some headers to make sure they get passed through ok
+            tm.setStringProperty("wib", "uhuh");
+            tm.setBooleanProperty("cheese", true);
+            tm.setIntProperty("Sausages", 23);
+            
+            //We add some JMSX ones too
+            
+            tm.setStringProperty("JMSXGroupID", "mygroup543");
+            tm.setIntProperty("JMSXGroupSeq", 777);
+            
+            prod.send(tm);
+            
+            ids1.add(tm.getJMSMessageID());
+         }
+
+         log.trace("Sent the first messages");
+         
+         Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageConsumer cons = sessTarget.createConsumer(targetQueue);
+         
+         connTarget.start();
+         
+         List msgs = new ArrayList();
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = (TextMessage)cons.receive(5000);
+            
+            assertNotNull(tm);
+            
+            assertEquals("message" + i, tm.getText());
+            
+            assertEquals("uhuh", tm.getStringProperty("wib"));
+            assertTrue(tm.getBooleanProperty("cheese"));
+            assertEquals(23, tm.getIntProperty("Sausages"));
+            
+            assertEquals("mygroup543", tm.getStringProperty("JMSXGroupID"));
+            assertEquals(777, tm.getIntProperty("JMSXGroupSeq"));
+            
+            if (on)
+            {            
+	            String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
+	            
+	            assertNotNull(header);
+	            
+	            assertEquals(ids1.get(i), header);
+	            
+	            msgs.add(tm);
+            }
+         }
+         
+         if (on)
+         {	         
+	         //Now we send them again back to the source
+	         
+	         Iterator iter = msgs.iterator();
+	         
+	         List ids2 = new ArrayList();
+	         
+	         while (iter.hasNext())
+	         {
+	         	Message msg = (Message)iter.next();
+	         	
+	         	prod.send(msg);
+	            
+	            ids2.add(msg.getJMSMessageID());
+	         }
+	                               
+	         //And consume them again
+	         
+	         for (int i = 0; i < NUM_MESSAGES; i++)
+	         {
+	            TextMessage tm = (TextMessage)cons.receive(5000);
+	            
+	            assertNotNull(tm);
+	            
+	            assertEquals("message" + i, tm.getText());
+	            
+	            assertEquals("uhuh", tm.getStringProperty("wib"));
+	            assertTrue(tm.getBooleanProperty("cheese"));
+	            assertEquals(23, tm.getIntProperty("Sausages"));
+	            
+	            assertEquals("mygroup543", tm.getStringProperty("JMSXGroupID"));
+	            assertEquals(777, tm.getIntProperty("JMSXGroupSeq"));            
+	            
+	            String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
+	            
+	            assertNotNull(header);
+	            
+	            assertEquals(ids1.get(i) + "," + ids2.get(i), header);
+	         }
+         }
+         
+      }
+      finally
+      {                        
+         if (bridge != null)
+         {
+            bridge.stop();
+         }
+         
+         if (connSource != null)
+         {
+            connSource.close();
+         }
+         
+         if (connTarget != null)
+         {
+            connTarget.close();
+         }
+      }                  
+   }
+   
+   
+   public void testPropertiesPreservedPOn() throws Exception
+   {
+   	propertiesPreserved(true, true);
+   }
+   
+   public void testPropertiesPreservedNPoff() throws Exception
+   {
+   	propertiesPreserved(false, true);
+   }
+   
+   public void testPropertiesPreservedNPOn() throws Exception
+   {
+   	propertiesPreserved(false, true);
+   }
+   
+   public void testPropertiesPreservedPoff() throws Exception
+   {
+   	propertiesPreserved(true, true);
+   }
+   
+   private void propertiesPreserved(boolean persistent, boolean messageIDInHeader) throws Exception
+   { 
+      JMSBridgeImpl bridge = null;
+      
+      Connection connSource = null;
+      
+      Connection connTarget = null;
+            
+      try
+      {
+         final int NUM_MESSAGES = 10;
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
+                  1, -1,
+                  null, null, messageIDInHeader);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+         
+         connSource = cf0.createConnection();
+         
+         connTarget = cf1.createConnection();
+                    
+         log.trace("Sending " + NUM_MESSAGES + " messages");
+         
+         Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageConsumer cons = sessTarget.createConsumer(targetQueue);
+         
+         connTarget.start();
+         
+         MessageProducer prod = sessSource.createProducer(sourceQueue);
+         
+         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);  
+         
+         
+         
+         TextMessage tm = sessSource.createTextMessage("blahmessage");
+         
+         prod.setPriority(7);
+         
+         prod.setTimeToLive(1 * 60 * 60 * 1000);
+
+         prod.send(tm);
+         
+         long expiration = tm.getJMSExpiration();
+         
+         assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
+                                 
+         tm = (TextMessage)cons.receive(1000);
+         
+         assertNotNull(tm);
+         
+         assertEquals("blahmessage", tm.getText());
+
+         assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
+         
+         assertEquals(7, tm.getJMSPriority());
+        
+         assertTrue(Math.abs(expiration - tm.getJMSExpiration()) < 100);
+                  
+         Message m = cons.receive(5000);
+         
+         assertNull(m);
+         
+         
+         //Now do one with expiration = 0
+         
+         
+         tm = sessSource.createTextMessage("blahmessage2");
+         
+         prod.setPriority(7);
+         
+         prod.setTimeToLive(0);
+
+         prod.send(tm);
+         
+         assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
+                                 
+         tm = (TextMessage)cons.receive(1000);
+         
+         assertNotNull(tm);
+         
+         assertEquals("blahmessage2", tm.getText());
+
+         assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
+         
+         assertEquals(7, tm.getJMSPriority());
+        
+         assertEquals(0, tm.getJMSExpiration());
+                  
+         m = cons.receive(5000);
+         
+         assertNull(m);            
+         
+         tm = sessSource.createTextMessage("blahmessage3");
+
+         final boolean myBool = false;
+         final byte myByte = (byte)23;
+         final double myDouble = 17625765d;
+         final float myFloat = 87127.23f;
+         final int myInt = 123;
+         final long myLong = 81728712;
+         final short myShort = (short)88;
+         final String myString = "ojweodewj";
+         final String myJMSX = "aardvark";
+
+         tm.setBooleanProperty("mybool", myBool);
+         tm.setByteProperty("mybyte", myByte);
+         tm.setDoubleProperty("mydouble", myDouble);
+         tm.setFloatProperty("myfloat", myFloat);
+         tm.setIntProperty("myint", myInt);
+         tm.setLongProperty("mylong", myLong);
+         tm.setShortProperty("myshort", myShort);
+         tm.setStringProperty("mystring", myString);
+
+         tm.setStringProperty("JMSXMyNaughtyJMSXProperty", myJMSX);
+
+         prod.send(tm);
+
+         tm = (TextMessage)cons.receive(5000);
+
+         assertNotNull(tm);
+
+         assertEquals("blahmessage3", tm.getText());
+
+         assertEquals(myBool, tm.getBooleanProperty("mybool"));
+         assertEquals(myByte, tm.getByteProperty("mybyte"));
+         assertEquals(myDouble, tm.getDoubleProperty("mydouble"));
+         assertEquals(myFloat, tm.getFloatProperty("myfloat"));
+         assertEquals(myInt, tm.getIntProperty("myint"));
+         assertEquals(myLong, tm.getLongProperty("mylong"));
+         assertEquals(myShort, tm.getShortProperty("myshort"));
+         assertEquals(myString, tm.getStringProperty("mystring"));
+         assertEquals(myJMSX, tm.getStringProperty("JMSXMyNaughtyJMSXProperty"));
+
+         m = cons.receive(5000);
+         
+      }
+      finally
+      {                        
+         if (bridge != null)
+         {
+            bridge.stop();
+         }
+         
+         if (connSource != null)
+         {
+            connSource.close();
+         }
+         
+         if (connTarget != null)
+         {
+            connTarget.close();
+         }
+      }                  
+   }
+   
+   public void testNoMessageIDInHeader() throws Exception
+   { 
+      JMSBridgeImpl bridge = null;
+      
+      Connection connSource = null;
+      
+      Connection connTarget = null;
+            
+      try
+      {
+         final int NUM_MESSAGES = 10;
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, QualityOfServiceMode.AT_MOST_ONCE,
+                  1, -1,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+         
+         connSource = cf0.createConnection();
+         
+         connTarget = cf1.createConnection();
+                    
+         log.trace("Sending " + NUM_MESSAGES + " messages");
+         
+         Session sessSource = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageProducer prod = sessSource.createProducer(sourceQueue);
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = sessSource.createTextMessage("message" + i);
+            
+            //We add some headers to make sure they get passed through ok
+            tm.setStringProperty("wib", "uhuh");
+            tm.setBooleanProperty("cheese", true);
+            tm.setIntProperty("Sausages", 23);
+            
+            prod.send(tm);
+         }
+
+         log.trace("Sent the first messages");
+         
+         Session sessTarget = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageConsumer cons = sessTarget.createConsumer(targetQueue);
+         
+         connTarget.start();
+         
+         for (int i = 0; i < NUM_MESSAGES; i++)
+         {
+            TextMessage tm = (TextMessage)cons.receive(5000);
+            
+            assertNotNull(tm);
+            
+            assertEquals("message" + i, tm.getText());
+            
+            assertEquals("uhuh", tm.getStringProperty("wib"));
+            assertTrue(tm.getBooleanProperty("cheese"));
+            assertEquals(23, tm.getIntProperty("Sausages"));
+            
+            String header = tm.getStringProperty(JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST);
+            
+            assertNull(header);
+         }                 
+      }
+      finally
+      {                        
+         if (bridge != null)
+         {
+            bridge.stop();
+         }
+         
+         if (connSource != null)
+         {
+            connSource.close();
+         }
+         
+         if (connTarget != null)
+         {
+            connTarget.close();
+         }
+      }                  
+   }
+   
+   
+   // Private -------------------------------------------------------------------------------
+             
+   private void testStress(QualityOfServiceMode qosMode, boolean persistent, int batchSize) throws Exception
+   {
+      Connection connSource = null;
+      
+      JMSBridgeImpl bridge = null;
+      
+      Thread t = null;
+            
+      try
+      {      
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, qosMode,
+                  batchSize, -1,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         connSource = cf0.createConnection();
+         
+         Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageProducer prod = sessSend.createProducer(sourceQueue);
+         
+         final int NUM_MESSAGES = 250;
+         
+         StressSender sender = new StressSender();
+         sender.sess = sessSend;
+         sender.prod = prod;
+         sender.numMessages = NUM_MESSAGES;
+         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+                          
+         t = new Thread(sender);
+         
+         t.start();
+         
+         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
+                                              
+         t.join();
+         
+         if (sender.ex != null)
+         {
+            //An error occurred during the send
+            throw sender.ex;
+         }
+           
+      }
+      finally
+      {    
+         if (t != null)
+         {
+            t.join(10000);
+         }
+         
+         if (connSource != null)
+         {
+            try
+            {
+               connSource.close();
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to close connection", e);
+            }
+         }                
+         
+         if (bridge != null)
+         {
+            bridge.stop();
+         }                  
+      }      
+   }
+   
+   private void testStressBatchTime(QualityOfServiceMode qosMode, boolean persistent, int maxBatchTime) throws Exception
+   {
+      Connection connSource = null;
+      
+      JMSBridgeImpl bridge = null;
+      
+      Thread t = null;
+            
+      try
+      {      
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, qosMode,
+                  2, maxBatchTime,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         connSource = cf0.createConnection();
+         
+         Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageProducer prod = sessSend.createProducer(sourceQueue);
+         
+         final int NUM_MESSAGES = 5000;
+         
+         StressSender sender = new StressSender();
+         sender.sess = sessSend;
+         sender.prod = prod;
+         sender.numMessages = NUM_MESSAGES;
+         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+                          
+         t = new Thread(sender);
+         
+         t.start();
+         
+         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
+                                              
+         t.join();
+         
+         if (sender.ex != null)
+         {
+            //An error occurred during the send
+            throw sender.ex;
+         }
+           
+      }
+      finally
+      {    
+         if (t != null)
+         {
+            t.join(10000);
+         }
+         
+         if (connSource != null)
+         {
+            try
+            {
+               connSource.close();
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to close connection", e);
+            }
+         }                
+         
+         if (bridge != null)
+         {
+            bridge.stop();
+         }                  
+      }      
+   }
+   
+   //Both source and destination on same rm
+   private void testStressSameServer(QualityOfServiceMode qosMode, boolean persistent, int batchSize) throws Exception
+   {
+      Connection connSource = null;
+      
+      JMSBridgeImpl bridge = null;
+      
+      Thread t = null;
+            
+      try
+      {  
+         bridge = new JMSBridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, qosMode,
+                  batchSize, -1,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         connSource = cf0.createConnection();
+         
+         Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageProducer prod = sessSend.createProducer(sourceQueue);
+         
+         final int NUM_MESSAGES = 2000;
+         
+         StressSender sender = new StressSender();
+         sender.sess = sessSend;
+         sender.prod = prod;
+         sender.numMessages = NUM_MESSAGES;
+         prod.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+                          
+         t = new Thread(sender);
+         
+         t.start();
+         
+         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
+                         
+         t.join();
+         
+         if (sender.ex != null)
+         {
+            //An error occurred during the send
+            throw sender.ex;
+         }
+           
+      }
+      finally
+      {    
+         if (t != null)
+         {
+            t.join(10000);
+         }
+         
+         if (connSource != null)
+         {
+            try
+            {
+               connSource.close();
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to close connection", e);
+            }
+         }
+                          
+         if (bridge != null)
+         {
+            bridge.stop();
+         }
+      }      
+   }
+   
+      
+   private void testNoMaxBatchTime(QualityOfServiceMode qosMode, boolean persistent) throws Exception
+   {
+      JMSBridgeImpl bridge = null;
+            
+      try
+      {
+         final int NUM_MESSAGES = 10;
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, qosMode,
+                  NUM_MESSAGES, -1,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         //Send half the messges
+
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent);
+                         
+         //Verify none are received
+         
+         this.checkEmpty(targetQueue, 1);
+         
+         //Send the other half
+         
+         this.sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES / 2, persistent);
+         
+         //This should now be receivable
+         
+         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
+         
+         //Send another batch with one more than batch size
+         
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, persistent);
+                  
+         //Make sure only batch size are received
+         
+         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);
+         
+         //Final batch
+         
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, persistent);
+         
+         this.checkAllMessageReceivedInOrder(cf1, targetQueue, NUM_MESSAGES, 1);
+         
+         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES - 1);
+      }
+      finally
+      {      
+         if (bridge != null)
+         {
+            log.info("Stopping bridge");
+            bridge.stop();
+         }         
+      }                  
+   }
+   
+   private void testNoMaxBatchTimeSameServer(QualityOfServiceMode qosMode, boolean persistent) throws Exception
+   {
+      JMSBridgeImpl bridge = null;
+            
+      try
+      {
+         final int NUM_MESSAGES = 10;
+         
+         bridge = new JMSBridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory,
+                  null, null, null, null,
+                  null, 5000, 10, qosMode,
+                  NUM_MESSAGES, -1,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES / 2, persistent);
+         
+         this.checkEmpty(targetQueue, 1);                
+         
+         //Send the other half
+         
+         this.sendMessages(cf0, sourceQueue, NUM_MESSAGES / 2, NUM_MESSAGES /2, persistent);
+         
+         
+         //This should now be receivable
+         
+         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
+         
+         this.checkEmpty(localTargetQueue, 0);
+         
+         this.checkEmpty(sourceQueue, 0);
+         
+         //Send another batch with one more than batch size
+         
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES + 1, persistent);
+         
+         //Make sure only batch size are received
+         
+         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
+         
+         //Final batch
+         
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES - 1, persistent);
+         
+         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, NUM_MESSAGES, 1);
+         
+         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES - 1);
+      }
+      finally
+      {               
+         if (bridge != null)
+         {
+            bridge.stop();
+         }                  
+      }                  
+   }
+   
+   private void testMaxBatchTime(QualityOfServiceMode qosMode, boolean persistent) throws Exception
+   {
+      JMSBridgeImpl bridge = null;
+            
+      try
+      {
+         final long MAX_BATCH_TIME = 3000;
+         
+         final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
+         
+         bridge = new JMSBridgeImpl(cff0, cff1, sourceQueueFactory, targetQueueFactory,
+                  null, null, null, null,
+                  null, 3000, 10, qosMode,
+                  MAX_BATCH_SIZE, MAX_BATCH_TIME,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+            
+         final int NUM_MESSAGES = 10;
+         
+         //Send some message
+
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES, persistent);                 
+         
+         //Verify none are received
+         
+         this.checkEmpty(targetQueue, 1);
+         
+         //Messages should now be receivable
+         
+         this.checkAllMessageReceivedInOrder(cf1, targetQueue, 0, NUM_MESSAGES);         
+      }
+      finally
+      {      
+         if (bridge != null)
+         {
+            bridge.stop();
+         }         
+      }                  
+   }
+   
+   private void testMaxBatchTimeSameServer(QualityOfServiceMode qosMode, boolean persistent) throws Exception
+   {
+      JMSBridgeImpl bridge = null;
+            
+      try
+      {
+         final long MAX_BATCH_TIME = 3000;
+         
+         final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
+         
+         bridge = new JMSBridgeImpl(cff0, cff0, sourceQueueFactory, localTargetQueueFactory,
+                  null, null, null, null,
+                  null, 3000, 10, qosMode,
+                  MAX_BATCH_SIZE, MAX_BATCH_TIME,
+                  null, null, false);
+         bridge.setTransactionManager(newTransactionManager());
+
+         bridge.start();
+         
+         final int NUM_MESSAGES = 10;
+         
+         //Send some message
+
+         //Send some message
+
+         this.sendMessages(cf0, sourceQueue, 0, NUM_MESSAGES, persistent);                 
+         
+         //Verify none are received
+         
+         this.checkEmpty(localTargetQueue, 0);;
+         
+         //Messages should now be receivable
+         
+         this.checkAllMessageReceivedInOrder(cf0, localTargetQueue, 0, NUM_MESSAGES);
+      }
+      finally
+      {              
+         if (bridge != null)
+         {
+            bridge.stop();
+         }        
+      }                  
+   }
+   
+   
+   // Inner classes -------------------------------------------------------------------
+   
+   private static class StressSender implements Runnable
+   {
+      int numMessages;
+      
+      Session sess;
+      
+      MessageProducer prod;
+      
+      Exception ex;
+      
+      public void run()
+      {
+         try
+         {
+            for (int i = 0; i < numMessages; i++)
+            {
+               TextMessage tm = sess.createTextMessage("message" + i);
+                                            
+               prod.send(tm);
+               
+               log.trace("Sent message " + i);
+            }
+         }
+         catch (Exception e)
+         {
+            log.error("Failed to send", e);
+            ex = e;
+         }         
+      }
+      
+   } 
+}

Deleted: trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/BridgeImplTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/BridgeImplTest.java	2009-04-03 14:08:30 UTC (rev 6298)
+++ trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/BridgeImplTest.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -1,519 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * 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.messaging.tests.timing.jms.bridge.impl;
-
-import static org.easymock.EasyMock.anyBoolean;
-import static org.easymock.EasyMock.anyInt;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.createStrictMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.getCurrentArguments;
-import static org.easymock.EasyMock.isA;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.transaction.TransactionManager;
-
-import org.easymock.IAnswer;
-import org.jboss.messaging.jms.bridge.ConnectionFactoryFactory;
-import org.jboss.messaging.jms.bridge.DestinationFactory;
-import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
-import org.jboss.messaging.jms.bridge.impl.BridgeImpl;
-import org.jboss.messaging.tests.util.UnitTestCase;
-
-/**
- * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
- * 
- * @version <tt>$Revision$</tt>
- * 
- */
-public class BridgeImplTest extends UnitTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   // Public --------------------------------------------------------
-
-   public void testStartWithRepeatedFailure() throws Exception
-   {
-      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
-      Connection sourceConn = createStrictMock(Connection.class);
-      Session sourceSession = createStrictMock(Session.class);
-      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
-      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
-      Destination sourceDest = createStrictMock(Destination.class);
-      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
-      Connection targetConn = createStrictMock(Connection.class);
-      Session targetSession = createStrictMock(Session.class);
-      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
-      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
-      Destination targetDest = createStrictMock(Destination.class);
-      TransactionManager tm = createStrictMock(TransactionManager.class);
-
-      expect(tm.suspend()).andReturn(null);
-      expect(sourceDF.createDestination()).andStubReturn(sourceDest);
-      expect(targetDF.createDestination()).andStubReturn(targetDest);
-      expect(sourceCFF.createConnectionFactory()).andStubReturn(sourceCF);
-      // the source connection can not be created
-      expect(sourceCF.createConnection()).andStubThrow(
-            new JMSException("unable to create a conn"));
-
-      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      replay(tm);
-
-      BridgeImpl bridge = new BridgeImpl();
-
-      bridge.setSourceConnectionFactoryFactory(sourceCFF);
-      bridge.setSourceDestinationFactory(sourceDF);
-      bridge.setTargetConnectionFactoryFactory(targetCFF);
-      bridge.setTargetDestinationFactory(targetDF);
-      // retry after 10 ms
-      bridge.setFailureRetryInterval(10);
-      // retry only once
-      bridge.setMaxRetries(1);
-      bridge.setMaxBatchSize(1);
-      bridge.setMaxBatchTime(-1);
-      bridge.setTransactionManager(tm);
-      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
-
-      assertFalse(bridge.isStarted());
-      bridge.start();
-
-      Thread.sleep(50);
-      assertFalse(bridge.isStarted());
-      assertTrue(bridge.isFailed());
-
-      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      verify(tm);
-   }
-
-   public void testStartWithFailureThenSuccess() throws Exception
-   {
-      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
-      Connection sourceConn = createStrictMock(Connection.class);
-      Session sourceSession = createStrictMock(Session.class);
-      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
-      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
-      Destination sourceDest = createStrictMock(Destination.class);
-      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
-      Connection targetConn = createStrictMock(Connection.class);
-      Session targetSession = createStrictMock(Session.class);
-      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
-      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
-      Destination targetDest = createStrictMock(Destination.class);
-      TransactionManager tm = createStrictMock(TransactionManager.class);
-
-      expect(tm.suspend()).andReturn(null);
-      expect(sourceDF.createDestination()).andStubReturn(sourceDest);
-      expect(targetDF.createDestination()).andStubReturn(targetDest);
-      expect(sourceCFF.createConnectionFactory()).andStubReturn(sourceCF);
-      // the source connection can not be created the 1st time...
-      expect(sourceCF.createConnection()).andThrow(
-            new JMSException("unable to create a conn"));
-      // ... and it succeeds the 2nd time
-      expect(sourceCF.createConnection()).andReturn(sourceConn);
-      sourceConn.setExceptionListener(isA(ExceptionListener.class));
-      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
-            sourceSession);
-      expect(sourceSession.createConsumer(sourceDest))
-            .andReturn(sourceConsumer);
-      sourceConsumer.setMessageListener(isA(MessageListener.class));
-      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
-      expect(targetCF.createConnection()).andReturn(targetConn);
-      targetConn.setExceptionListener(isA(ExceptionListener.class));
-      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
-            targetSession);
-      expect(targetSession.createProducer(null)).andReturn(targetProducer);
-      sourceConn.start();
-
-      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      replay(tm);
-
-      BridgeImpl bridge = new BridgeImpl();
-
-      bridge.setSourceConnectionFactoryFactory(sourceCFF);
-      bridge.setSourceDestinationFactory(sourceDF);
-      bridge.setTargetConnectionFactoryFactory(targetCFF);
-      bridge.setTargetDestinationFactory(targetDF);
-      // retry after 10 ms
-      bridge.setFailureRetryInterval(10);
-      // retry only once
-      bridge.setMaxRetries(1);
-      bridge.setMaxBatchSize(1);
-      bridge.setMaxBatchTime(-1);
-      bridge.setTransactionManager(tm);
-      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
-
-      assertFalse(bridge.isStarted());
-      bridge.start();
-
-      Thread.sleep(50);
-      assertTrue(bridge.isStarted());
-      assertFalse(bridge.isFailed());
-
-      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      verify(tm);
-   }
-
-   /*
-    * we receive only 1 message. The message is sent when the maxBatchTime
-    * expires even if the maxBatchSize is not reached
-    */
-   public void testSendMessagesWhenMaxBatchTimeExpires() throws Exception
-   {
-      int maxBatchSize = 2;
-      long maxBatchTime = 500;
-
-      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
-      Connection sourceConn = createStrictMock(Connection.class);
-      Session sourceSession = createStrictMock(Session.class);
-      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
-      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
-      Destination sourceDest = createStrictMock(Destination.class);
-      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
-      Connection targetConn = createStrictMock(Connection.class);
-      Session targetSession = createStrictMock(Session.class);
-      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
-      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
-      Destination targetDest = createStrictMock(Destination.class);
-      TransactionManager tm = createStrictMock(TransactionManager.class);
-      Message message = createNiceMock(Message.class);
-
-      expect(tm.suspend()).andReturn(null);
-      expect(sourceDF.createDestination()).andReturn(sourceDest);
-      expect(targetDF.createDestination()).andReturn(targetDest);
-      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
-      expect(sourceCF.createConnection()).andReturn(sourceConn);
-      sourceConn.setExceptionListener(isA(ExceptionListener.class));
-      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
-            sourceSession);
-      expect(sourceSession.createConsumer(sourceDest))
-            .andReturn(sourceConsumer);
-      SetMessageListenerAnswer answer = new SetMessageListenerAnswer();
-      sourceConsumer.setMessageListener(isA(MessageListener.class));
-      expectLastCall().andAnswer(answer);
-      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
-      expect(targetCF.createConnection()).andReturn(targetConn);
-      targetConn.setExceptionListener(isA(ExceptionListener.class));
-      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
-            targetSession);
-      expect(targetSession.createProducer(null)).andReturn(targetProducer);
-      sourceConn.start();
-
-      targetProducer.send(targetDest, message, 0, 0, 0);
-      targetSession.commit();
-
-      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      replay(tm);
-      replay(message);
-
-      BridgeImpl bridge = new BridgeImpl();
-      assertNotNull(bridge);
-
-      bridge.setSourceConnectionFactoryFactory(sourceCFF);
-      bridge.setSourceDestinationFactory(sourceDF);
-      bridge.setTargetConnectionFactoryFactory(targetCFF);
-      bridge.setTargetDestinationFactory(targetDF);
-      bridge.setFailureRetryInterval(-1);
-      bridge.setMaxRetries(-1);
-      bridge.setMaxBatchSize(maxBatchSize);
-      bridge.setMaxBatchTime(maxBatchTime);
-      bridge.setTransactionManager(tm);
-      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
-
-      assertFalse(bridge.isStarted());
-      bridge.start();
-      assertTrue(bridge.isStarted());
-
-      answer.listener.onMessage(message);
-
-      Thread.sleep(3 * maxBatchTime);
-
-      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      verify(tm);
-      verify(message);
-   }
-
-   public void testExceptionOnSourceAndRetrySucceeds() throws Exception
-   {
-      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
-      Connection sourceConn = createStrictMock(Connection.class);
-      Session sourceSession = createStrictMock(Session.class);
-      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
-      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
-      Destination sourceDest = createStrictMock(Destination.class);
-      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
-      Connection targetConn = createStrictMock(Connection.class);
-      Session targetSession = createStrictMock(Session.class);
-      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
-      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
-      Destination targetDest = createStrictMock(Destination.class);
-      TransactionManager tm = createStrictMock(TransactionManager.class);
-      Message message = createNiceMock(Message.class);
-
-      expect(tm.suspend()).andReturn(null);
-      expect(sourceDF.createDestination()).andReturn(sourceDest);
-      expect(targetDF.createDestination()).andReturn(targetDest);
-      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
-      expect(sourceCF.createConnection()).andReturn(sourceConn);
-      SetExceptionListenerAnswer exceptionListenerAnswer = new SetExceptionListenerAnswer();
-      sourceConn.setExceptionListener(isA(ExceptionListener.class));
-      expectLastCall().andAnswer(exceptionListenerAnswer);
-      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
-            sourceSession);
-      expect(sourceSession.createConsumer(sourceDest))
-            .andReturn(sourceConsumer);
-      sourceConsumer.setMessageListener(isA(MessageListener.class));
-      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
-      expect(targetCF.createConnection()).andReturn(targetConn);
-      targetConn.setExceptionListener(isA(ExceptionListener.class));
-      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
-            targetSession);
-      expect(targetSession.createProducer(null)).andReturn(targetProducer);
-      sourceConn.start();
-
-      //after failure detection, we retry to start the bridge:
-      expect(sourceDF.createDestination()).andReturn(sourceDest);
-      expect(targetDF.createDestination()).andReturn(targetDest);
-      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
-      expect(sourceCF.createConnection()).andReturn(sourceConn);
-      sourceConn.setExceptionListener(isA(ExceptionListener.class));
-      expectLastCall().andAnswer(exceptionListenerAnswer);
-      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
-            sourceSession);
-      expect(sourceSession.createConsumer(sourceDest))
-            .andReturn(sourceConsumer);
-      sourceConsumer.setMessageListener(isA(MessageListener.class));
-      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
-      expect(targetCF.createConnection()).andReturn(targetConn);
-      targetConn.setExceptionListener(isA(ExceptionListener.class));
-      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
-            targetSession);
-      expect(targetSession.createProducer(null)).andReturn(targetProducer);
-      sourceConn.start();
-      
-      
-      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      replay(tm);
-      replay(message);
-
-      BridgeImpl bridge = new BridgeImpl();
-      assertNotNull(bridge);
-
-      bridge.setSourceConnectionFactoryFactory(sourceCFF);
-      bridge.setSourceDestinationFactory(sourceDF);
-      bridge.setTargetConnectionFactoryFactory(targetCFF);
-      bridge.setTargetDestinationFactory(targetDF);
-      bridge.setFailureRetryInterval(10);
-      bridge.setMaxRetries(2);
-      bridge.setMaxBatchSize(1);
-      bridge.setMaxBatchTime(-1);
-      bridge.setTransactionManager(tm);
-      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
-
-      assertFalse(bridge.isStarted());
-      bridge.start();
-      assertTrue(bridge.isStarted());
-      
-      exceptionListenerAnswer.listener.onException(new JMSException("exception on the source"));
-      Thread.sleep(4 * bridge.getFailureRetryInterval());
-      // reconnection must have succeded
-      assertTrue(bridge.isStarted());
-      
-      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      verify(tm);
-      verify(message);
-   }
-   
-   public void testExceptionOnSourceAndRetryFails() throws Exception
-   {
-      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
-      Connection sourceConn = createStrictMock(Connection.class);
-      Session sourceSession = createStrictMock(Session.class);
-      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
-      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
-      Destination sourceDest = createStrictMock(Destination.class);
-      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
-      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
-      Connection targetConn = createStrictMock(Connection.class);
-      Session targetSession = createStrictMock(Session.class);
-      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
-      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
-      Destination targetDest = createStrictMock(Destination.class);
-      TransactionManager tm = createStrictMock(TransactionManager.class);
-      Message message = createNiceMock(Message.class);
-
-      expect(tm.suspend()).andReturn(null);
-      expect(sourceDF.createDestination()).andReturn(sourceDest);
-      expect(targetDF.createDestination()).andReturn(targetDest);
-      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
-      expect(sourceCF.createConnection()).andReturn(sourceConn);
-      SetExceptionListenerAnswer exceptionListenerAnswer = new SetExceptionListenerAnswer();
-      sourceConn.setExceptionListener(isA(ExceptionListener.class));
-      expectLastCall().andAnswer(exceptionListenerAnswer);
-      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
-            sourceSession);
-      expect(sourceSession.createConsumer(sourceDest))
-            .andReturn(sourceConsumer);
-      sourceConsumer.setMessageListener(isA(MessageListener.class));
-      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
-      expect(targetCF.createConnection()).andReturn(targetConn);
-      targetConn.setExceptionListener(isA(ExceptionListener.class));
-      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
-            targetSession);
-      expect(targetSession.createProducer(null)).andReturn(targetProducer);
-      sourceConn.start();
-
-      //after failure detection, we clean up...
-      // and it is stopped
-      sourceConn.close();
-      targetConn.close();
-      // ...retry to start the bridge but it fails...
-      expect(sourceDF.createDestination()).andReturn(sourceDest);
-      expect(targetDF.createDestination()).andReturn(targetDest);
-      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
-      expect(sourceCF.createConnection()).andThrow(new JMSException("exception while retrying to connect"));
-      // ... so we clean up again...
-      sourceConn.close();
-      targetConn.close();
-      // ... and finally stop the bridge
-      sourceConn.close();
-      targetConn.close();
-      
-      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      replay(tm);
-      replay(message);
-
-      BridgeImpl bridge = new BridgeImpl();
-      assertNotNull(bridge);
-
-      bridge.setSourceConnectionFactoryFactory(sourceCFF);
-      bridge.setSourceDestinationFactory(sourceDF);
-      bridge.setTargetConnectionFactoryFactory(targetCFF);
-      bridge.setTargetDestinationFactory(targetDF);
-      bridge.setFailureRetryInterval(10);
-      bridge.setMaxRetries(1);
-      bridge.setMaxBatchSize(1);
-      bridge.setMaxBatchTime(-1);
-      bridge.setTransactionManager(tm);
-      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
-
-      assertFalse(bridge.isStarted());
-      bridge.start();
-      assertTrue(bridge.isStarted());
-      
-      exceptionListenerAnswer.listener.onException(new JMSException("exception on the source"));
-      Thread.sleep(4 * bridge.getFailureRetryInterval());
-      // reconnection must have failed
-      assertFalse(bridge.isStarted());
-      
-      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
-            sourceDF, sourceDest);
-      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
-            targetDF, targetDest);
-      verify(tm);
-      verify(message);
-   }
-   
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-   
-   class SetExceptionListenerAnswer implements IAnswer
-   {
-      ExceptionListener listener = null;
-
-      public Object answer() throws Throwable
-      {
-         listener = (ExceptionListener) getCurrentArguments()[0];
-         return null;
-      }
-   }
-   
-   class SetMessageListenerAnswer implements IAnswer
-   {
-      MessageListener listener = null;
-
-      public Object answer() throws Throwable
-      {
-         listener = (MessageListener) getCurrentArguments()[0];
-         return null;
-      }
-   }
-}

Copied: trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/JMSBridgeImplTest.java (from rev 6295, trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/BridgeImplTest.java)
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/JMSBridgeImplTest.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/timing/jms/bridge/impl/JMSBridgeImplTest.java	2009-04-03 14:12:53 UTC (rev 6299)
@@ -0,0 +1,519 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.messaging.tests.timing.jms.bridge.impl;
+
+import static org.easymock.EasyMock.anyBoolean;
+import static org.easymock.EasyMock.anyInt;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.transaction.TransactionManager;
+
+import org.easymock.IAnswer;
+import org.jboss.messaging.jms.bridge.ConnectionFactoryFactory;
+import org.jboss.messaging.jms.bridge.DestinationFactory;
+import org.jboss.messaging.jms.bridge.QualityOfServiceMode;
+import org.jboss.messaging.jms.bridge.impl.JMSBridgeImpl;
+import org.jboss.messaging.tests.util.UnitTestCase;
+
+/**
+ * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
+ * 
+ * @version <tt>$Revision$</tt>
+ * 
+ */
+public class JMSBridgeImplTest extends UnitTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   // Public --------------------------------------------------------
+
+   public void testStartWithRepeatedFailure() throws Exception
+   {
+      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
+      Connection sourceConn = createStrictMock(Connection.class);
+      Session sourceSession = createStrictMock(Session.class);
+      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
+      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
+      Destination sourceDest = createStrictMock(Destination.class);
+      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
+      Connection targetConn = createStrictMock(Connection.class);
+      Session targetSession = createStrictMock(Session.class);
+      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
+      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
+      Destination targetDest = createStrictMock(Destination.class);
+      TransactionManager tm = createStrictMock(TransactionManager.class);
+
+      expect(tm.suspend()).andReturn(null);
+      expect(sourceDF.createDestination()).andStubReturn(sourceDest);
+      expect(targetDF.createDestination()).andStubReturn(targetDest);
+      expect(sourceCFF.createConnectionFactory()).andStubReturn(sourceCF);
+      // the source connection can not be created
+      expect(sourceCF.createConnection()).andStubThrow(
+            new JMSException("unable to create a conn"));
+
+      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      replay(tm);
+
+      JMSBridgeImpl bridge = new JMSBridgeImpl();
+
+      bridge.setSourceConnectionFactoryFactory(sourceCFF);
+      bridge.setSourceDestinationFactory(sourceDF);
+      bridge.setTargetConnectionFactoryFactory(targetCFF);
+      bridge.setTargetDestinationFactory(targetDF);
+      // retry after 10 ms
+      bridge.setFailureRetryInterval(10);
+      // retry only once
+      bridge.setMaxRetries(1);
+      bridge.setMaxBatchSize(1);
+      bridge.setMaxBatchTime(-1);
+      bridge.setTransactionManager(tm);
+      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
+
+      assertFalse(bridge.isStarted());
+      bridge.start();
+
+      Thread.sleep(50);
+      assertFalse(bridge.isStarted());
+      assertTrue(bridge.isFailed());
+
+      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      verify(tm);
+   }
+
+   public void testStartWithFailureThenSuccess() throws Exception
+   {
+      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
+      Connection sourceConn = createStrictMock(Connection.class);
+      Session sourceSession = createStrictMock(Session.class);
+      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
+      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
+      Destination sourceDest = createStrictMock(Destination.class);
+      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
+      Connection targetConn = createStrictMock(Connection.class);
+      Session targetSession = createStrictMock(Session.class);
+      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
+      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
+      Destination targetDest = createStrictMock(Destination.class);
+      TransactionManager tm = createStrictMock(TransactionManager.class);
+
+      expect(tm.suspend()).andReturn(null);
+      expect(sourceDF.createDestination()).andStubReturn(sourceDest);
+      expect(targetDF.createDestination()).andStubReturn(targetDest);
+      expect(sourceCFF.createConnectionFactory()).andStubReturn(sourceCF);
+      // the source connection can not be created the 1st time...
+      expect(sourceCF.createConnection()).andThrow(
+            new JMSException("unable to create a conn"));
+      // ... and it succeeds the 2nd time
+      expect(sourceCF.createConnection()).andReturn(sourceConn);
+      sourceConn.setExceptionListener(isA(ExceptionListener.class));
+      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
+            sourceSession);
+      expect(sourceSession.createConsumer(sourceDest))
+            .andReturn(sourceConsumer);
+      sourceConsumer.setMessageListener(isA(MessageListener.class));
+      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
+      expect(targetCF.createConnection()).andReturn(targetConn);
+      targetConn.setExceptionListener(isA(ExceptionListener.class));
+      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
+            targetSession);
+      expect(targetSession.createProducer(null)).andReturn(targetProducer);
+      sourceConn.start();
+
+      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      replay(tm);
+
+      JMSBridgeImpl bridge = new JMSBridgeImpl();
+
+      bridge.setSourceConnectionFactoryFactory(sourceCFF);
+      bridge.setSourceDestinationFactory(sourceDF);
+      bridge.setTargetConnectionFactoryFactory(targetCFF);
+      bridge.setTargetDestinationFactory(targetDF);
+      // retry after 10 ms
+      bridge.setFailureRetryInterval(10);
+      // retry only once
+      bridge.setMaxRetries(1);
+      bridge.setMaxBatchSize(1);
+      bridge.setMaxBatchTime(-1);
+      bridge.setTransactionManager(tm);
+      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
+
+      assertFalse(bridge.isStarted());
+      bridge.start();
+
+      Thread.sleep(50);
+      assertTrue(bridge.isStarted());
+      assertFalse(bridge.isFailed());
+
+      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      verify(tm);
+   }
+
+   /*
+    * we receive only 1 message. The message is sent when the maxBatchTime
+    * expires even if the maxBatchSize is not reached
+    */
+   public void testSendMessagesWhenMaxBatchTimeExpires() throws Exception
+   {
+      int maxBatchSize = 2;
+      long maxBatchTime = 500;
+
+      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
+      Connection sourceConn = createStrictMock(Connection.class);
+      Session sourceSession = createStrictMock(Session.class);
+      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
+      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
+      Destination sourceDest = createStrictMock(Destination.class);
+      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
+      Connection targetConn = createStrictMock(Connection.class);
+      Session targetSession = createStrictMock(Session.class);
+      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
+      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
+      Destination targetDest = createStrictMock(Destination.class);
+      TransactionManager tm = createStrictMock(TransactionManager.class);
+      Message message = createNiceMock(Message.class);
+
+      expect(tm.suspend()).andReturn(null);
+      expect(sourceDF.createDestination()).andReturn(sourceDest);
+      expect(targetDF.createDestination()).andReturn(targetDest);
+      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
+      expect(sourceCF.createConnection()).andReturn(sourceConn);
+      sourceConn.setExceptionListener(isA(ExceptionListener.class));
+      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
+            sourceSession);
+      expect(sourceSession.createConsumer(sourceDest))
+            .andReturn(sourceConsumer);
+      SetMessageListenerAnswer answer = new SetMessageListenerAnswer();
+      sourceConsumer.setMessageListener(isA(MessageListener.class));
+      expectLastCall().andAnswer(answer);
+      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
+      expect(targetCF.createConnection()).andReturn(targetConn);
+      targetConn.setExceptionListener(isA(ExceptionListener.class));
+      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
+            targetSession);
+      expect(targetSession.createProducer(null)).andReturn(targetProducer);
+      sourceConn.start();
+
+      targetProducer.send(targetDest, message, 0, 0, 0);
+      targetSession.commit();
+
+      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      replay(tm);
+      replay(message);
+
+      JMSBridgeImpl bridge = new JMSBridgeImpl();
+      assertNotNull(bridge);
+
+      bridge.setSourceConnectionFactoryFactory(sourceCFF);
+      bridge.setSourceDestinationFactory(sourceDF);
+      bridge.setTargetConnectionFactoryFactory(targetCFF);
+      bridge.setTargetDestinationFactory(targetDF);
+      bridge.setFailureRetryInterval(-1);
+      bridge.setMaxRetries(-1);
+      bridge.setMaxBatchSize(maxBatchSize);
+      bridge.setMaxBatchTime(maxBatchTime);
+      bridge.setTransactionManager(tm);
+      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
+
+      assertFalse(bridge.isStarted());
+      bridge.start();
+      assertTrue(bridge.isStarted());
+
+      answer.listener.onMessage(message);
+
+      Thread.sleep(3 * maxBatchTime);
+
+      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      verify(tm);
+      verify(message);
+   }
+
+   public void testExceptionOnSourceAndRetrySucceeds() throws Exception
+   {
+      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
+      Connection sourceConn = createStrictMock(Connection.class);
+      Session sourceSession = createStrictMock(Session.class);
+      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
+      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
+      Destination sourceDest = createStrictMock(Destination.class);
+      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
+      Connection targetConn = createStrictMock(Connection.class);
+      Session targetSession = createStrictMock(Session.class);
+      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
+      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
+      Destination targetDest = createStrictMock(Destination.class);
+      TransactionManager tm = createStrictMock(TransactionManager.class);
+      Message message = createNiceMock(Message.class);
+
+      expect(tm.suspend()).andReturn(null);
+      expect(sourceDF.createDestination()).andReturn(sourceDest);
+      expect(targetDF.createDestination()).andReturn(targetDest);
+      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
+      expect(sourceCF.createConnection()).andReturn(sourceConn);
+      SetExceptionListenerAnswer exceptionListenerAnswer = new SetExceptionListenerAnswer();
+      sourceConn.setExceptionListener(isA(ExceptionListener.class));
+      expectLastCall().andAnswer(exceptionListenerAnswer);
+      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
+            sourceSession);
+      expect(sourceSession.createConsumer(sourceDest))
+            .andReturn(sourceConsumer);
+      sourceConsumer.setMessageListener(isA(MessageListener.class));
+      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
+      expect(targetCF.createConnection()).andReturn(targetConn);
+      targetConn.setExceptionListener(isA(ExceptionListener.class));
+      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
+            targetSession);
+      expect(targetSession.createProducer(null)).andReturn(targetProducer);
+      sourceConn.start();
+
+      //after failure detection, we retry to start the bridge:
+      expect(sourceDF.createDestination()).andReturn(sourceDest);
+      expect(targetDF.createDestination()).andReturn(targetDest);
+      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
+      expect(sourceCF.createConnection()).andReturn(sourceConn);
+      sourceConn.setExceptionListener(isA(ExceptionListener.class));
+      expectLastCall().andAnswer(exceptionListenerAnswer);
+      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
+            sourceSession);
+      expect(sourceSession.createConsumer(sourceDest))
+            .andReturn(sourceConsumer);
+      sourceConsumer.setMessageListener(isA(MessageListener.class));
+      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
+      expect(targetCF.createConnection()).andReturn(targetConn);
+      targetConn.setExceptionListener(isA(ExceptionListener.class));
+      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
+            targetSession);
+      expect(targetSession.createProducer(null)).andReturn(targetProducer);
+      sourceConn.start();
+      
+      
+      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      replay(tm);
+      replay(message);
+
+      JMSBridgeImpl bridge = new JMSBridgeImpl();
+      assertNotNull(bridge);
+
+      bridge.setSourceConnectionFactoryFactory(sourceCFF);
+      bridge.setSourceDestinationFactory(sourceDF);
+      bridge.setTargetConnectionFactoryFactory(targetCFF);
+      bridge.setTargetDestinationFactory(targetDF);
+      bridge.setFailureRetryInterval(10);
+      bridge.setMaxRetries(2);
+      bridge.setMaxBatchSize(1);
+      bridge.setMaxBatchTime(-1);
+      bridge.setTransactionManager(tm);
+      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
+
+      assertFalse(bridge.isStarted());
+      bridge.start();
+      assertTrue(bridge.isStarted());
+      
+      exceptionListenerAnswer.listener.onException(new JMSException("exception on the source"));
+      Thread.sleep(4 * bridge.getFailureRetryInterval());
+      // reconnection must have succeded
+      assertTrue(bridge.isStarted());
+      
+      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      verify(tm);
+      verify(message);
+   }
+   
+   public void testExceptionOnSourceAndRetryFails() throws Exception
+   {
+      ConnectionFactoryFactory sourceCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory sourceCF = createStrictMock(ConnectionFactory.class);
+      Connection sourceConn = createStrictMock(Connection.class);
+      Session sourceSession = createStrictMock(Session.class);
+      MessageConsumer sourceConsumer = createStrictMock(MessageConsumer.class);
+      DestinationFactory sourceDF = createStrictMock(DestinationFactory.class);
+      Destination sourceDest = createStrictMock(Destination.class);
+      ConnectionFactoryFactory targetCFF = createStrictMock(ConnectionFactoryFactory.class);
+      ConnectionFactory targetCF = createStrictMock(ConnectionFactory.class);
+      Connection targetConn = createStrictMock(Connection.class);
+      Session targetSession = createStrictMock(Session.class);
+      MessageProducer targetProducer = createStrictMock(MessageProducer.class);
+      DestinationFactory targetDF = createStrictMock(DestinationFactory.class);
+      Destination targetDest = createStrictMock(Destination.class);
+      TransactionManager tm = createStrictMock(TransactionManager.class);
+      Message message = createNiceMock(Message.class);
+
+      expect(tm.suspend()).andReturn(null);
+      expect(sourceDF.createDestination()).andReturn(sourceDest);
+      expect(targetDF.createDestination()).andReturn(targetDest);
+      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
+      expect(sourceCF.createConnection()).andReturn(sourceConn);
+      SetExceptionListenerAnswer exceptionListenerAnswer = new SetExceptionListenerAnswer();
+      sourceConn.setExceptionListener(isA(ExceptionListener.class));
+      expectLastCall().andAnswer(exceptionListenerAnswer);
+      expect(sourceConn.createSession(anyBoolean(), anyInt())).andReturn(
+            sourceSession);
+      expect(sourceSession.createConsumer(sourceDest))
+            .andReturn(sourceConsumer);
+      sourceConsumer.setMessageListener(isA(MessageListener.class));
+      expect(targetCFF.createConnectionFactory()).andReturn(targetCF);
+      expect(targetCF.createConnection()).andReturn(targetConn);
+      targetConn.setExceptionListener(isA(ExceptionListener.class));
+      expect(targetConn.createSession(anyBoolean(), anyInt())).andReturn(
+            targetSession);
+      expect(targetSession.createProducer(null)).andReturn(targetProducer);
+      sourceConn.start();
+
+      //after failure detection, we clean up...
+      // and it is stopped
+      sourceConn.close();
+      targetConn.close();
+      // ...retry to start the bridge but it fails...
+      expect(sourceDF.createDestination()).andReturn(sourceDest);
+      expect(targetDF.createDestination()).andReturn(targetDest);
+      expect(sourceCFF.createConnectionFactory()).andReturn(sourceCF);
+      expect(sourceCF.createConnection()).andThrow(new JMSException("exception while retrying to connect"));
+      // ... so we clean up again...
+      sourceConn.close();
+      targetConn.close();
+      // ... and finally stop the bridge
+      sourceConn.close();
+      targetConn.close();
+      
+      replay(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      replay(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      replay(tm);
+      replay(message);
+
+      JMSBridgeImpl bridge = new JMSBridgeImpl();
+      assertNotNull(bridge);
+
+      bridge.setSourceConnectionFactoryFactory(sourceCFF);
+      bridge.setSourceDestinationFactory(sourceDF);
+      bridge.setTargetConnectionFactoryFactory(targetCFF);
+      bridge.setTargetDestinationFactory(targetDF);
+      bridge.setFailureRetryInterval(10);
+      bridge.setMaxRetries(1);
+      bridge.setMaxBatchSize(1);
+      bridge.setMaxBatchTime(-1);
+      bridge.setTransactionManager(tm);
+      bridge.setQualityOfServiceMode(QualityOfServiceMode.AT_MOST_ONCE);
+
+      assertFalse(bridge.isStarted());
+      bridge.start();
+      assertTrue(bridge.isStarted());
+      
+      exceptionListenerAnswer.listener.onException(new JMSException("exception on the source"));
+      Thread.sleep(4 * bridge.getFailureRetryInterval());
+      // reconnection must have failed
+      assertFalse(bridge.isStarted());
+      
+      verify(sourceCFF, sourceCF, sourceConn, sourceSession, sourceConsumer,
+            sourceDF, sourceDest);
+      verify(targetCFF, targetCF, targetConn, targetSession, targetProducer,
+            targetDF, targetDest);
+      verify(tm);
+      verify(message);
+   }
+   
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+   
+   class SetExceptionListenerAnswer implements IAnswer
+   {
+      ExceptionListener listener = null;
+
+      public Object answer() throws Throwable
+      {
+         listener = (ExceptionListener) getCurrentArguments()[0];
+         return null;
+      }
+   }
+   
+   class SetMessageListenerAnswer implements IAnswer
+   {
+      MessageListener listener = null;
+
+      public Object answer() throws Throwable
+      {
+         listener = (MessageListener) getCurrentArguments()[0];
+         return null;
+      }
+   }
+}




More information about the jboss-cvs-commits mailing list