[jboss-cvs] JBoss Messaging SVN: r1663 - in branches/Branch_Client_Failover_Experiment: src/etc src/etc/server/default/deploy src/etc/xmdesc src/main/org/jboss/jms/client src/main/org/jboss/jms/client/container src/main/org/jboss/jms/client/delegate src/main/org/jboss/jms/client/ha src/main/org/jboss/jms/delegate src/main/org/jboss/jms/server src/main/org/jboss/jms/server/connectionfactory src/main/org/jboss/jms/server/container src/main/org/jboss/jms/server/endpoint src/main/org/jboss/jms/server/endpoint/advised src/main/org/jboss/jms/server/remoting src/main/org/jboss/messaging/core/plugin src/main/org/jboss/messaging/core/plugin/contract src/main/org/jboss/messaging/core/plugin/postoffice/cluster tests/src/org/jboss/test/messaging/core/ha tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster tests/src/org/jboss/test/messaging/jms/clustering tests/src/org/jboss/test/messaging/tools/jmx/rmi

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Nov 30 10:28:33 EST 2006


Author: timfox
Date: 2006-11-30 10:27:59 -0500 (Thu, 30 Nov 2006)
New Revision: 1663

Added:
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/HAAspect.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClusteredClientConnectionFactoryDelegate.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/FailoverMapper.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/ReplicationListener.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultFailoverMapper.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeAddressInfo.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PutReplicantRequest.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoveReplicantRequest.java
Removed:
   branches/Branch_Client_Failover_Experiment/src/etc/xmdesc/ClusteredConnectionFactory-xmbean.xml
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/FailoverAspect.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/ha/ClusteredConnectionFactoryDelegate.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ha/
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NodeAddressInfo.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendNodeIdRequest.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/factoryinterface/
Modified:
   branches/Branch_Client_Failover_Experiment/src/etc/aop-messaging-client.xml
   branches/Branch_Client_Failover_Experiment/src/etc/server/default/deploy/connection-factories-service.xml
   branches/Branch_Client_Failover_Experiment/src/etc/xmdesc/ConnectionFactory-xmbean.xml
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/JBossConnectionFactory.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/ConnectionAspect.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/StateCreationAspect.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConnectionDelegate.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConnectionFactoryDelegate.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConsumerDelegate.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/DelegateSupport.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/delegate/ConnectionDelegate.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ConnectionFactoryManager.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ServerPeer.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/container/InjectionAspect.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/SessionEndpoint.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/remoting/MetaDataConstants.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRequest.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicy.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/LeaveClusterRequest.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeInternal.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesRequest.java
   branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SharedState.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ClusterecConnectionTest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ReconnectClusteredTest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ReconnectNonClusteredTest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeTest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RecoveryTest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/jms/clustering/HATest.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java
   branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java
Log:
Failover refactoring



Modified: branches/Branch_Client_Failover_Experiment/src/etc/aop-messaging-client.xml
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/etc/aop-messaging-client.xml	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/etc/aop-messaging-client.xml	2006-11-30 15:27:59 UTC (rev 1663)
@@ -18,7 +18,7 @@
    <aspect class="org.jboss.jms.client.container.AsfAspect" scope="PER_INSTANCE"/>
    <aspect class="org.jboss.jms.client.container.BrowserAspect" scope="PER_INSTANCE"/>
    <aspect class="org.jboss.jms.client.container.ConnectionAspect" scope="PER_INSTANCE"/>
-   <aspect class="org.jboss.jms.client.container.FailoverAspect" scope="PER_VM"/>
+   <aspect class="org.jboss.jms.client.container.FailoverAspect" scope="PER_INSTANCE"/>
    <aspect class="org.jboss.jms.client.container.FactoryAspect" scope="PER_INSTANCE"/>
 
    <!-- ConnectionFactory Stack-->        
@@ -29,6 +29,9 @@
    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate->createConnectionDelegate(..))">
       <advice name="handleCreateConnectionDelegate" aspect="org.jboss.jms.client.container.StateCreationAspect"/>
    </bind>
+   <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate->createConnectionDelegate(..))">
+      <advice name="handleCreateConnectionDelegate" aspect="org.jboss.jms.client.container.FailoverAspect"/>
+   </bind>
                
    <!-- Connection Stack -->   
    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionDelegate->$implementing{org.jboss.jms.delegate.ConnectionDelegate}(..))">
@@ -42,9 +45,6 @@
     <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionDelegate->stop())">
        <advice name="handleStop" aspect="org.jboss.jms.client.container.ConnectionAspect"/>
     </bind>
-    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionDelegate->failOver(..))">
-       <advice name="handleFailover" aspect="org.jboss.jms.client.container.FailoverAspect"/>
-    </bind>
    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionDelegate->createConnectionConsumer(..))">
       <advice name="handleCreateConnectionConsumer" aspect="org.jboss.jms.client.container.AsfAspect"/>
    </bind>
@@ -69,9 +69,10 @@
    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionDelegate->close())">
       <advice name="handleClose" aspect="org.jboss.jms.client.container.ConnectionAspect"/>
    </bind>   
-    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionDelegate->createSessionDelegate(..))">
-       <advice name="handleCreateSessionDelegate" aspect="org.jboss.jms.client.container.StateCreationAspect"/>
-    </bind>
+   <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientConnectionDelegate->createSessionDelegate(..))">
+      <advice name="handleCreateSessionDelegate" aspect="org.jboss.jms.client.container.StateCreationAspect"/>
+   </bind>
+    
 
    <!-- Session Stack -->   
    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientSessionDelegate->$implementing{org.jboss.jms.delegate.SessionDelegate}(..))">

Modified: branches/Branch_Client_Failover_Experiment/src/etc/server/default/deploy/connection-factories-service.xml
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/etc/server/default/deploy/connection-factories-service.xml	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/etc/server/default/deploy/connection-factories-service.xml	2006-11-30 15:27:59 UTC (rev 1663)
@@ -22,23 +22,8 @@
             <binding>java:/XAConnectionFactory</binding>
          </bindings>
       </attribute>
+      
+      <attribute name="Clustered">true</attribute>
    </mbean>
 
-
-   <!-- TODO: Move this MBean to its own XML -->
-   <mbean code="org.jboss.jms.server.ha.ClusteredConnectionFactory"
-      name="jboss.messaging.destination:service=ClusteredConnectionFactory"
-      xmbean-dd="xmdesc/ClusteredConnectionFactory-xmbean.xml">
-      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-      <depends optional-attribute-name="ClusteredPostOffice">jboss.messaging:service=QueuePostOffice</depends>
-      <attribute name="JNDIBindings">
-         <bindings>
-            <binding>/HAConnectionFactory</binding>
-            <binding>/HAXAConnectionFactory</binding>
-            <binding>java:/HAConnectionFactory</binding>
-            <binding>java:/HAXAConnectionFactory</binding>
-         </bindings>
-      </attribute>
-   </mbean>
-
 </server>
\ No newline at end of file

Deleted: branches/Branch_Client_Failover_Experiment/src/etc/xmdesc/ClusteredConnectionFactory-xmbean.xml
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/etc/xmdesc/ClusteredConnectionFactory-xmbean.xml	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/etc/xmdesc/ClusteredConnectionFactory-xmbean.xml	2006-11-30 15:27:59 UTC (rev 1663)
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-   <!DOCTYPE mbean PUBLIC
-      "-//JBoss//DTD JBOSS XMBEAN 1.2//EN"
-      "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_2.dtd">
-
-<!-- $Id: ConnectionFactory-xmbean.xml 1178 2006-08-02 14:57:43 -0600 (Wed, 02 Aug 2006) ovidiu.feodorov at jboss.com $ -->
-
-
-<mbean>
-   <description>A deployable JBoss Messaging Clustered Connection Factory</description>
-   <class>org.jboss.jms.server.ha.ClusteredConnectionFactory</class>
-
-   <!-- Managed constructors -->
-
-   <constructor>
-      <name>ClusteredConnectionFactory</name>
-   </constructor>
-
-   <!-- Managed attributes -->
-
-   <!-- This attribute is writable to allow configuring an arbitrary set of JNDI names in the
-        queue's service deployment descriptor. Any attempt to change the attribute after
-        initialization will be ignored.
-   -->
-   <attribute access="read-write" getMethod="getJNDIBindings" setMethod="setJNDIBindings">
-      <description>The element containing the JNDI bindings this connection factory is to be bound under</description>
-      <name>JNDIBindings</name>
-      <type>org.w3c.dom.Element</type>
-   </attribute>
-
-   <!-- ServerPeer ObjectName is configured as a dependency optional-attribute-name, this is the
-        only reason for this attribute to be writable. Any write attempt on this attribute after
-        initialization will be ignored.
-   -->
-   <attribute access="read-write" getMethod="getServerPeer" setMethod="setServerPeer">
-      <description>The ObjectName of the server peer this destination was deployed on</description>
-      <name>ServerPeer</name>
-      <type>javax.management.ObjectName</type>
-   </attribute>
-
-
-   <attribute access="read-write" getMethod="getClusteredPostOffice" setMethod="setClusteredPostOffice">
-      <description>The ObjectName any clustered post office that will have a list of active nodes in a cluster</description>
-      <name>ClusteredPostOffice</name>
-      <type>javax.management.ObjectName</type>
-   </attribute>
-
-
-   <!-- Managed operations -->
-
-   <operation>
-      <description>JBoss Service lifecycle operation</description>
-      <name>create</name>
-   </operation>
-
-   <operation>
-      <description>JBoss Service lifecycle operation</description>
-      <name>start</name>
-   </operation>
-
-   <operation>
-      <description>JBoss Service lifecycle operation</description>
-      <name>stop</name>
-   </operation>
-
-   <operation>
-      <description>JBoss Service lifecycle operation</description>
-      <name>destroy</name>
-   </operation>
-
-</mbean>
\ No newline at end of file

Modified: branches/Branch_Client_Failover_Experiment/src/etc/xmdesc/ConnectionFactory-xmbean.xml
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/etc/xmdesc/ConnectionFactory-xmbean.xml	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/etc/xmdesc/ConnectionFactory-xmbean.xml	2006-11-30 15:27:59 UTC (rev 1663)
@@ -81,6 +81,12 @@
       <name>Connector</name>
       <type>javax.management.ObjectName</type>
    </attribute>
+   
+   <attribute access="read-write" getMethod="isClustered" setMethod="setClustered">
+      <description>Is this a clustered connection factory?</description>
+      <name>Clustered</name>
+      <type>boolean</type>
+   </attribute>    
 
    <!-- Managed operations -->
 

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/JBossConnectionFactory.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/JBossConnectionFactory.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/JBossConnectionFactory.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -1,34 +1,47 @@
 /*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
 package org.jboss.jms.client;
 
 import java.io.Serializable;
-import javax.jms.*;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.XAConnection;
+import javax.jms.XAConnectionFactory;
+import javax.jms.XAQueueConnection;
+import javax.jms.XAQueueConnectionFactory;
+import javax.jms.XATopicConnection;
+import javax.jms.XATopicConnectionFactory;
 import javax.naming.NamingException;
 import javax.naming.Reference;
+
 import org.jboss.aop.Advised;
 import org.jboss.jms.client.container.JmsClientAspectXMLLoader;
 import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
-import org.jboss.jms.client.ha.ClusteredConnectionFactoryDelegate;
 import org.jboss.jms.delegate.ConnectionDelegate;
 import org.jboss.jms.delegate.ConnectionFactoryDelegate;
 import org.jboss.jms.referenceable.SerializableObjectRefAddr;
@@ -43,89 +56,89 @@
  * $Id$
  */
 public class JBossConnectionFactory implements
-    ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory,
-    XAConnectionFactory, XAQueueConnectionFactory, XATopicConnectionFactory,
-    Serializable/*, Referenceable http://jira.jboss.org/jira/browse/JBMESSAGING-395*/
+               ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory,
+               XAConnectionFactory, XAQueueConnectionFactory, XATopicConnectionFactory,
+               Serializable/*, Referenceable http://jira.jboss.org/jira/browse/JBMESSAGING-395*/
 {
    // Constants -----------------------------------------------------
-
+   
    private final static long serialVersionUID = -2810634789345348326L;
    
    private static final Logger log = Logger.getLogger(JBossConnectionFactory.class);
    
-
+   
    // Static --------------------------------------------------------
    
    private static boolean configLoaded;
-
+   
    // Attributes ----------------------------------------------------
-
+   
    protected ConnectionFactoryDelegate delegate;
    
    private boolean initialised;
-     
+   
    // Constructors --------------------------------------------------
-
+   
    public JBossConnectionFactory(ConnectionFactoryDelegate delegate)
    {
       this.delegate = delegate;      
    }
-
+   
    // ConnectionFactory implementation ------------------------------
-
+   
    public Connection createConnection() throws JMSException
    {
       return createConnection(null, null);
    }
-
+   
    public Connection createConnection(String username, String password) throws JMSException
    {
       return createConnectionInternal(username, password, false, JBossConnection.TYPE_GENERIC_CONNECTION);
    }
    
    // QueueConnectionFactory implementation -------------------------
-
+   
    public QueueConnection createQueueConnection() throws JMSException
    {
       return createQueueConnection(null, null);
    }
-
+   
    public QueueConnection createQueueConnection(String username, String password) throws JMSException
    {
-       return createConnectionInternal(username, password, false, JBossConnection.TYPE_QUEUE_CONNECTION);
+      return createConnectionInternal(username, password, false, JBossConnection.TYPE_QUEUE_CONNECTION);
    }
    
    // TopicConnectionFactory implementation -------------------------
-
+   
    public TopicConnection createTopicConnection() throws JMSException
    {
       return createTopicConnection(null, null);
    }
-
+   
    public TopicConnection createTopicConnection(String username, String password) throws JMSException
    {
       return createConnectionInternal(username, password, false, JBossConnection.TYPE_TOPIC_CONNECTION);
    }
    
    // XAConnectionFactory implementation ------------------------------
-
+   
    public XAConnection createXAConnection() throws JMSException
    {
       return createXAConnection(null, null);
    }
-
+   
    public XAConnection createXAConnection(String username, String password) throws JMSException
    {
       return createConnectionInternal(username, password, true, JBossConnection.TYPE_GENERIC_CONNECTION);   
    }
    
    // XAQueueConnectionFactory implementation -------------------------
-
+   
    public XAQueueConnection createXAQueueConnection() throws JMSException
    {
-       return createXAQueueConnection(null, null);
+      return createXAQueueConnection(null, null);
    }
-
+   
    public XAQueueConnection createXAQueueConnection(String username, String password) throws JMSException
    {
       return createConnectionInternal(username, password, true, JBossConnection.TYPE_QUEUE_CONNECTION);   
@@ -137,7 +150,7 @@
    {
       return createXATopicConnection(null, null);
    }
-
+   
    public XATopicConnection createXATopicConnection(String username, String password) throws JMSException
    {
       return createConnectionInternal(username, password, true, JBossConnection.TYPE_TOPIC_CONNECTION);   
@@ -148,13 +161,13 @@
    public Reference getReference() throws NamingException
    {
       return new Reference("org.jboss.jms.client.JBossConnectionFactory",
-                           new SerializableObjectRefAddr("JBM-CF", this),
-                           "org.jboss.jms.referenceable.ConnectionFactoryObjectFactory",
-                           null);
+               new SerializableObjectRefAddr("JBM-CF", this),
+               "org.jboss.jms.referenceable.ConnectionFactoryObjectFactory",
+               null);
    }
-
+   
    // Public --------------------------------------------------------
-
+   
    public String toString()
    {
       return "JBossConnectionFactory->" + delegate;
@@ -164,35 +177,30 @@
    {
       return delegate;
    }
-
-   public void setDelegate(ConnectionFactoryDelegate delegate)
-   {
-      this.delegate = delegate;
-   }
    
    // Package protected ---------------------------------------------
-
+   
    // Protected -----------------------------------------------------
-
+   
    protected JBossConnection createConnectionInternal(String username, String password,
-                                                      boolean isXA, int type)
+            boolean isXA, int type)
       throws JMSException
    {
-
+      
       ThreadContextClassLoaderChanger tccc = new ThreadContextClassLoaderChanger();
-
+      
       try
       {
          tccc.set(getClass().getClassLoader());
-
-         ensureAOPConfigLoaded(delegate);
+         
+         ensureAOPConfigLoaded((ClientConnectionFactoryDelegate)delegate);
          initDelegate();
-           
+         
          // The version used by the connection is the minimum of the server version for the
          // connection factory and the client code version
          
          ConnectionDelegate cd = delegate.createConnectionDelegate(username, password);        
-          
+         
          return new JBossConnection(cd, type);
       }
       finally
@@ -205,21 +213,12 @@
    {
       if (!initialised)
       {
-         if (delegate instanceof ClientConnectionFactoryDelegate)
-         {
-            ((ClientConnectionFactoryDelegate)delegate).init();
-         }
-         else
-         {
-            System.out.println("Initializing clustered factory");
-            ((ClusteredConnectionFactoryDelegate)delegate).init();
-         }
+         ((ClientConnectionFactoryDelegate)delegate).init();
          initialised = true;
       }         
    }
-
-
-   protected void ensureAOPConfigLoaded(ConnectionFactoryDelegate delegate)
+   
+   protected void ensureAOPConfigLoaded(ClientConnectionFactoryDelegate delegate)
    {
       try
       {
@@ -227,23 +226,14 @@
          {
             if (!configLoaded)
             {
-               ClientConnectionFactoryDelegate currentDelegate = null;
-               if (delegate instanceof ClusteredConnectionFactoryDelegate)
-               {
-                  currentDelegate = ((ClusteredConnectionFactoryDelegate)delegate).getRoundRobbinFactoryDelegate();
-               }
-               else
-               {
-                  currentDelegate = (ClientConnectionFactoryDelegate)delegate;
-               }
-
-               currentDelegate.init();
                // Load the client side aspect stack configuration from the server and apply it
                
-               byte[] clientAOPConfig = currentDelegate.getClientAOPConfig();
+               delegate.init();
                
+               byte[] clientAOPConfig = delegate.getClientAOPConfig();
+               
                // Remove interceptor since we don't want it on the front of the stack
-               ((Advised)currentDelegate)._getInstanceAdvisor().removeInterceptor(currentDelegate.getName());
+               ((Advised)delegate)._getInstanceAdvisor().removeInterceptor(delegate.getName());
                
                JmsClientAspectXMLLoader loader = new JmsClientAspectXMLLoader();
                
@@ -261,8 +251,8 @@
          throw new RuntimeException(msg, e);
       }
    }
-
+   
    // Private -------------------------------------------------------
-
+      
    // Inner classes -------------------------------------------------
 }

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/ConnectionAspect.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/ConnectionAspect.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/ConnectionAspect.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -1,24 +1,24 @@
 /*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
 package org.jboss.jms.client.container;
 
 import javax.jms.ExceptionListener;
@@ -50,31 +50,31 @@
 public class ConnectionAspect implements ConnectionListener
 {
    // Constants -----------------------------------------------------
-
+   
    // Static --------------------------------------------------------
-
+   
    private static final Logger log = Logger.getLogger(ConnectionAspect.class);
    private static boolean trace = log.isTraceEnabled();
-
+   
    // Attributes ----------------------------------------------------
-
-
-    protected JBossConnectionMetaData connMetaData;
-
-    protected ConnectionState state;
-
+   
+   
+   protected JBossConnectionMetaData connMetaData;
+   
+   protected ConnectionState state;
+   
    // Constructors --------------------------------------------------
-
+   
    // Public --------------------------------------------------------
-
+   
    // Interceptor implementation ------------------------------------
-
+   
    public Object handleGetClientID(Invocation invocation) throws Throwable
    {
       ConnectionState currentState = getConnectionState(invocation);
-
+      
       currentState.setJustCreated(false);
-
+      
       if (currentState.getClientID() == null)
       {
          //Get from the server
@@ -82,11 +82,11 @@
       }
       return currentState.getClientID();
    }
-
+   
    public Object handleSetClientID(Invocation invocation) throws Throwable
    {
       ConnectionState currentState = getConnectionState(invocation);
-
+      
       if (currentState.getClientID() != null)
       {
          throw new IllegalStateException("Client id has already been set");
@@ -95,41 +95,41 @@
       {
          throw new IllegalStateException("setClientID can only be called directly after the connection is created");
       }
-
+      
       MethodInvocation mi = (MethodInvocation)invocation;
-
+      
       currentState.setClientID((String)mi.getArguments()[0]);
-
+      
       currentState.setJustCreated(false);
-
+      
       // this gets invoked on the server too
       return invocation.invokeNext();
    }
-
+   
    public Object handleGetExceptionListener(Invocation invocation) throws Throwable
    {
       ConnectionState currentState = getConnectionState(invocation);
       currentState.setJustCreated(false);
-
+      
       return currentState.getExceptionListener();
    }
-
+   
    public Object handleSetExceptionListener(Invocation invocation) throws Throwable
    {
-       ConnectionState currentState = getConnectionState(invocation);
-       currentState.setJustCreated(false);
-
+      ConnectionState currentState = getConnectionState(invocation);
+      currentState.setJustCreated(false);
+      
       MethodInvocation mi = (MethodInvocation)invocation;
-
+      
       currentState.setExceptionListener((ExceptionListener)mi.getArguments()[0]);
-
+      
       Client client = getConnectionState(invocation).getRemotingConnection().getInvokingClient();
-
+      
       if (client == null)
       {
          throw new java.lang.IllegalStateException("Cannot find remoting client");
       }
-
+      
       if (currentState.getExceptionListener() != null)
       {
          client.addConnectionListener(this);
@@ -144,67 +144,67 @@
       }
       return null;
    }
-
+   
    public Object handleGetConnectionMetaData(Invocation invocation) throws Throwable
    {
-       ConnectionState currentState = getConnectionState(invocation);
-       currentState.setJustCreated(false);
-
-       if (connMetaData == null)
-       {
-          ClientConnectionDelegate delegate = (ClientConnectionDelegate)invocation.getTargetObject();
-          connMetaData = new JBossConnectionMetaData(((ConnectionState)delegate.getState()).getVersionToUse());
-       }
-
-       return connMetaData;
+      ConnectionState currentState = getConnectionState(invocation);
+      currentState.setJustCreated(false);
+      
+      if (connMetaData == null)
+      {
+         ClientConnectionDelegate delegate = (ClientConnectionDelegate)invocation.getTargetObject();
+         connMetaData = new JBossConnectionMetaData(((ConnectionState)delegate.getState()).getVersionToUse());
+      }
+      
+      return connMetaData;
    }
-
-    public Object handleStart(Invocation invocation) throws Throwable
-    {
-        ConnectionState currentState = getConnectionState(invocation);
-        currentState.setStarted(true);
-        return invocation.invokeNext();
-    }
-
-    public Object handleStop(Invocation invocation) throws Throwable
-    {
-        ConnectionState currentState = getConnectionState(invocation);
-        currentState.setStarted(false);
-        return invocation.invokeNext();
-    }
-
-    public Object handleCreateSessionDelegate(Invocation invocation) throws Throwable
-    {
-       ConnectionState currentState = getConnectionState(invocation);
-       currentState.setJustCreated(false);
-       return invocation.invokeNext();
-    }
-
+   
+   public Object handleStart(Invocation invocation) throws Throwable
+   {
+      ConnectionState currentState = getConnectionState(invocation);
+      currentState.setStarted(true);
+      return invocation.invokeNext();
+   }
+   
+   public Object handleStop(Invocation invocation) throws Throwable
+   {
+      ConnectionState currentState = getConnectionState(invocation);
+      currentState.setStarted(false);
+      return invocation.invokeNext();
+   }
+   
+   public Object handleCreateSessionDelegate(Invocation invocation) throws Throwable
+   {
+      ConnectionState currentState = getConnectionState(invocation);
+      currentState.setJustCreated(false);
+      return invocation.invokeNext();
+   }
+   
    public Object handleClose(Invocation invocation) throws Throwable
    {
       Object ret = invocation.invokeNext();
-
+      
       ConnectionState state = getConnectionState(invocation);
-
+      
       // Finished with the connection - we need to shutdown callback server
       state.getRemotingConnection().stop();
-
+      
       // Remove reference to resource manager
       ResourceManagerFactory.instance.checkInResourceManager(state.getServerID());
-
+      
       // Remove reference to message id generator
       MessageIdGeneratorFactory.instance.checkInGenerator(state.getServerID());
-
+      
       return ret;
    }
-
-
+   
+   
    // ConnectionListener implementation -----------------------------------------------------------
-
+   
    public void handleConnectionException(Throwable t, Client c)
    {
       log.error("Caught exception from connection", t);
-
+      
       if (state.getExceptionListener()!= null)
       {
          JMSException j = null;
@@ -233,25 +233,25 @@
          }
       }
    }
-
+   
    // Package protected ---------------------------------------------
-
+   
    // Protected -----------------------------------------------------
-
+   
    // Private -------------------------------------------------------
-
+   
    private ConnectionState getConnectionState(Invocation invocation)
    {
       if (state==null)
       {
          ClientConnectionDelegate currentDelegate =
             ((ClientConnectionDelegate)invocation.getTargetObject());
-
+         
          state = (ConnectionState)currentDelegate.getState();
       }
       return state;
    }
-
-
+   
+   
    // Inner classes -------------------------------------------------
 }

Deleted: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/FailoverAspect.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/FailoverAspect.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/FailoverAspect.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -1,216 +0,0 @@
-/*
-   * JBoss, Home of Professional Open Source
-   * Copyright 2005, JBoss Inc., and individual contributors as indicated
-   * by the @authors tag. See the copyright.txt in the distribution for a
-   * full listing of individual contributors.
-   *
-   * This is free software; you can redistribute it and/or modify it
-   * under the terms of the GNU Lesser General Public License as
-   * published by the Free Software Foundation; either version 2.1 of
-   * the License, or (at your option) any later version.
-   *
-   * This software is distributed in the hope that it will be useful,
-   * but WITHOUT ANY WARRANTY; without even the implied warranty of
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   * Lesser General Public License for more details.
-   *
-   * You should have received a copy of the GNU Lesser General Public
-   * License along with this software; if not, write to the Free
-   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-   */
-
-package org.jboss.jms.client.container;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import javax.jms.JMSException;
-import org.jboss.aop.joinpoint.Invocation;
-import org.jboss.aop.joinpoint.MethodInvocation;
-import org.jboss.jms.client.delegate.ClientBrowserDelegate;
-import org.jboss.jms.client.delegate.ClientConnectionDelegate;
-import org.jboss.jms.client.delegate.ClientConsumerDelegate;
-import org.jboss.jms.client.delegate.ClientProducerDelegate;
-import org.jboss.jms.client.delegate.ClientSessionDelegate;
-import org.jboss.jms.client.remoting.CallbackManager;
-import org.jboss.jms.client.remoting.MessageCallbackHandler;
-import org.jboss.jms.client.state.BrowserState;
-import org.jboss.jms.client.state.ConnectionState;
-import org.jboss.jms.client.state.ConsumerState;
-import org.jboss.jms.client.state.HierarchicalStateSupport;
-import org.jboss.jms.client.state.ProducerState;
-import org.jboss.jms.client.state.SessionState;
-import org.jboss.jms.destination.JBossDestination;
-import org.jboss.logging.Logger;
-
-/**
- * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
- * @version <tt>$Revision:$</tt>
- *          <p/>
- *          $Id:$
- */
-public class FailoverAspect
-{
-
-   private static final Logger log = Logger.getLogger(ConnectionAspect.class);
-   private static boolean trace = log.isTraceEnabled();
-
-   
-
-   public Object handleFailover(Invocation invocation) throws Throwable
-   {
-      if (trace) { log.trace("calling handleFailover"); }
-
-      ClientConnectionDelegate failedDelegate =
-         ((ClientConnectionDelegate)invocation.getTargetObject());
-      ConnectionState failedState = (ConnectionState)failedDelegate.getState();
-
-      int oldServerID = failedState.getServerID();
-
-      ClientConnectionDelegate newDelegate =
-         (ClientConnectionDelegate)((MethodInvocation)invocation).getArguments()[0];
-      ConnectionState newState = (ConnectionState)newDelegate.getState();
-
-      failedState.copy(newState);
-
-      if (failedState.getClientID() != null)
-      {
-         newDelegate.setClientID(failedState.getClientID());
-      }
-
-      // Transfering state from newDelegate to currentDelegate
-      failedDelegate.copyState(newDelegate);
-
-      if (failedState.isStarted())
-      {
-         failedDelegate.start();
-      }
-
-      for(Iterator i = failedState.getChildren().iterator(); i.hasNext(); )
-      {
-         SessionState failedSessionState = (SessionState)i.next();
-
-         ClientSessionDelegate newSessionDelegate = (ClientSessionDelegate)newDelegate.
-            createSessionDelegate(failedSessionState.isTransacted(),
-                                  failedSessionState.getAcknowledgeMode(),
-                                  failedSessionState.isXA());
-
-         ClientSessionDelegate failedSessionDelegate =
-            (ClientSessionDelegate)failedSessionState.getDelegate();
-
-         failedSessionDelegate.copyState(newSessionDelegate);
-
-         if (trace) { log.trace("replacing session (" + failedSessionDelegate + ") with a new failover session " + newSessionDelegate); }
-
-         List children = new ArrayList();
-         children.addAll(failedSessionState.getChildren());
-
-         for(Iterator j = children.iterator(); j.hasNext(); )
-         {
-            HierarchicalStateSupport sessionChild = (HierarchicalStateSupport)j.next();
-
-            if (sessionChild instanceof ProducerState)
-            {
-               handleFailoverOnProducer((ProducerState)sessionChild, newSessionDelegate);
-            }
-            else if (sessionChild instanceof ConsumerState)
-            {
-               handleFailoverOnConsumer(failedDelegate,
-                                        failedState,
-                                        failedSessionState,
-                                        (ConsumerState)sessionChild,
-                                        failedSessionDelegate,
-                                        oldServerID);
-            }
-            else if (sessionChild instanceof BrowserState)
-            {
-                handleFailoverOnBrowser((BrowserState)sessionChild, newSessionDelegate);
-            }
-         }
-      }
-
-      return null;
-   }
-
-   private void handleFailoverOnConsumer(ClientConnectionDelegate connectionDelegate,
-                                         ConnectionState failedConnectionState,
-                                         SessionState failedSessionState,
-                                         ConsumerState failedConsumerState,
-                                         ClientSessionDelegate failedSessionDelegate,
-                                         int oldServerID)
-      throws JMSException
-   {
-      ClientConsumerDelegate failedConsumerDelegate =
-         (ClientConsumerDelegate)failedConsumerState.getDelegate();
-
-      if (trace) { log.trace("handleFailoverOnConsumer: creating alternate consumer"); }
-
-      ClientConsumerDelegate newConsumerDelegate = (ClientConsumerDelegate)failedSessionDelegate.
-         failOverConsumer((JBossDestination)failedConsumerState.getDestination(),
-                                failedConsumerState.getSelector(),
-                                failedConsumerState.isNoLocal(),
-                                failedConsumerState.getSubscriptionName(),
-                                failedConsumerState.isConnectionConsumer(),
-                                failedConsumerDelegate.getChannelId(),
-                                oldServerID);
-
-      if (trace) { log.trace("handleFailoverOnConsumer: alternate consumer created"); }
-
-      failedConsumerDelegate.copyState(newConsumerDelegate);
-
-      int oldConsumerID = failedConsumerState.getConsumerID();
-
-      ConsumerState newState = (ConsumerState)newConsumerDelegate.getState();
-      failedConsumerState.copy(newState);
-
-      failedConnectionState.getResourceManager().
-         handleFailover(failedSessionState.getCurrentTxId(),
-                        oldConsumerID,
-                        failedConsumerState.getConsumerID());
-
-      CallbackManager cm = failedConnectionState.getRemotingConnection().getCallbackManager();
-
-      MessageCallbackHandler handler = cm.unregisterHandler(oldServerID, oldConsumerID);
-      handler.setConsumerId(failedConsumerState.getConsumerID());
-
-      cm.registerHandler(failedConnectionState.getServerID(),
-                         failedConsumerState.getConsumerID(),
-                         handler);
-      failedSessionState.addCallbackHandler(handler);
-
-   }
-
-   private void handleFailoverOnProducer(ProducerState failedProducerState,
-                                         ClientSessionDelegate failedSessionDelegate)
-      throws JMSException
-   {
-      ClientProducerDelegate newProducerDelegate = (ClientProducerDelegate)failedSessionDelegate.
-         createProducerDelegate((JBossDestination)failedProducerState.getDestination());
-
-      ClientProducerDelegate failedProducerDelegate =
-         (ClientProducerDelegate)failedProducerState.getDelegate();
-
-      failedProducerDelegate.copyState(newProducerDelegate);
-
-      if (trace) { log.trace("handling fail over on producerDelegate " + failedProducerDelegate + " destination=" + failedProducerState.getDestination()); }
-   }
-
-   private void handleFailoverOnBrowser(BrowserState failedBrowserState,
-                                         ClientSessionDelegate failedSessionDelegate)
-      throws JMSException
-   {
-      ClientBrowserDelegate newBrowserDelegate = (ClientBrowserDelegate)failedSessionDelegate.
-          createBrowserDelegate(failedBrowserState.getJmsDestination(),failedBrowserState.getMessageSelector());
-
-      ClientBrowserDelegate failedBrowserDelegate =
-         (ClientBrowserDelegate)failedBrowserState.getDelegate();
-
-      failedBrowserDelegate.copyState(newBrowserDelegate);
-
-      if (trace) { log.trace("handling fail over on browserDelegate " + failedBrowserDelegate + " destination=" + failedBrowserState.getJmsDestination() + " selector=" + failedBrowserState.getMessageSelector()); }
-
-   }
-
-
-}

Copied: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/HAAspect.java (from rev 1662, branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/FailoverAspect.java)
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/FailoverAspect.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/HAAspect.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,411 @@
+/*
+   * JBoss, Home of Professional Open Source
+   * Copyright 2005, JBoss Inc., and individual contributors as indicated
+   * by the @authors tag. See the copyright.txt in the distribution for a
+   * full listing of individual contributors.
+   *
+   * This is free software; you can redistribute it and/or modify it
+   * under the terms of the GNU Lesser General Public License as
+   * published by the Free Software Foundation; either version 2.1 of
+   * the License, or (at your option) any later version.
+   *
+   * This software is distributed in the hope that it will be useful,
+   * but WITHOUT ANY WARRANTY; without even the implied warranty of
+   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   * Lesser General Public License for more details.
+   *
+   * You should have received a copy of the GNU Lesser General Public
+   * License along with this software; if not, write to the Free
+   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+   */
+
+package org.jboss.jms.client.container;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jms.JMSException;
+
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.aop.joinpoint.MethodInvocation;
+import org.jboss.aop.metadata.SimpleMetaData;
+import org.jboss.jms.client.delegate.ClientBrowserDelegate;
+import org.jboss.jms.client.delegate.ClientConnectionDelegate;
+import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
+import org.jboss.jms.client.delegate.ClientConsumerDelegate;
+import org.jboss.jms.client.delegate.ClientProducerDelegate;
+import org.jboss.jms.client.delegate.ClientSessionDelegate;
+import org.jboss.jms.client.delegate.DelegateSupport;
+import org.jboss.jms.client.remoting.CallbackManager;
+import org.jboss.jms.client.remoting.MessageCallbackHandler;
+import org.jboss.jms.client.state.BrowserState;
+import org.jboss.jms.client.state.ConnectionState;
+import org.jboss.jms.client.state.ConsumerState;
+import org.jboss.jms.client.state.HierarchicalStateSupport;
+import org.jboss.jms.client.state.ProducerState;
+import org.jboss.jms.client.state.SessionState;
+import org.jboss.jms.destination.JBossDestination;
+import org.jboss.jms.server.remoting.MetaDataConstants;
+import org.jboss.logging.Logger;
+import org.jboss.remoting.Client;
+import org.jboss.remoting.ConnectionListener;
+
+/**
+ * 
+ * A HAAspect
+ * 
+ * There is one of these PER_INSTANCE of connection factory
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
+ * 
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class HAAspect
+{
+   private static final Logger log = Logger.getLogger(ConnectionAspect.class);
+   
+   private static boolean trace = log.isTraceEnabled();
+   
+   //Cache this here
+   private ClientConnectionFactoryDelegate[] delegates;
+   
+   private int[] failoverIndexes;
+   
+   private int current;
+   
+   public Object handleCreateConnectionDelegate(Invocation invocation) throws Throwable
+   {
+      if (getServers(invocation) != null)
+      {         
+         //In a clustered configuration we create connections in a round-robin fashion
+         //from the available servers
+         
+         ClientConnectionFactoryDelegate cfDelegate = getDelegateRoundRobin();
+         
+         //Now create a connection delegate for this
+         
+         MethodInvocation mi = (MethodInvocation)invocation;
+         
+         String username = (String)mi.getArguments()[0];
+         
+         String password = (String)mi.getArguments()[1];
+         
+         ClientConnectionDelegate connDelegate = createConnection(cfDelegate, username, password);
+         
+         return connDelegate;   
+      }
+      else
+      {
+         //Non clustered
+         
+         return invocation.invokeNext();
+      }
+   }
+   
+   //TODO this is currently hardcoded as round-robin, this should be made pluggable
+   private synchronized ClientConnectionFactoryDelegate getDelegateRoundRobin()
+   {
+      ClientConnectionFactoryDelegate currentDelegate = delegates[current++];
+      
+      if (current >= delegates.length)
+      {
+         current = 0;
+      }
+      return currentDelegate;
+   }
+   
+   private synchronized ClientConnectionFactoryDelegate[] getServers(Invocation invocation)
+   {
+      if (delegates == null)
+      {         
+         SimpleMetaData metaData = invocation.getMetaData();
+         
+         delegates = (ClientConnectionFactoryDelegate[])metaData.getMetaData(MetaDataConstants.JMS, MetaDataConstants.CF_DELEGATES);
+         
+         if (delegates == null)
+         {
+            throw new IllegalStateException("Cannot find delegates!");
+         }
+         
+         failoverIndexes = (int[])metaData.getMetaData(MetaDataConstants.JMS, MetaDataConstants.CF_FAILOVER_INDEXES);
+         
+         if (failoverIndexes == null)
+         {
+            throw new IllegalStateException("Cannot find failoverIndexes!");
+         }
+      }
+      
+      return delegates;
+   }
+   
+   private ClientConnectionDelegate createConnection(ClientConnectionFactoryDelegate cf, String username, String password)
+      throws Exception
+   {
+      ClientConnectionDelegate connDelegate = (ClientConnectionDelegate)cf.createConnectionDelegate(username, password);
+      
+      //Add a connection listener
+      
+      ConnectionState state = (ConnectionState)((DelegateSupport)connDelegate).getState();
+      
+      state.getRemotingConnection().getInvokingClient().addConnectionListener(new Listener(connDelegate));
+      
+      return connDelegate;   
+   }
+
+   
+   //The connection has failed
+   private void handleFailure(ClientConnectionDelegate failedConnection) throws Exception
+   {
+      ClientConnectionFactoryDelegate newCF = getAlternateDelegate(failedConnection);
+      
+      //TODO implement client side valve to prevent invocations occurring whilst failover is occurring
+      
+      ConnectionState state = (ConnectionState)((DelegateSupport)failedConnection).getState();
+      
+      ClientConnectionDelegate newConnection = createConnection(newCF, state.getUser(), state.getPassword());
+      
+      try
+      {
+         failover(failedConnection, newConnection);
+      }
+      catch (Throwable t)
+      {
+         //TODO
+         //If failover itself fails, we shouldn't give up, we should try the next one in the list
+         //etc until we find one that works
+         //TODO
+      }
+   }
+   
+   private ClientConnectionFactoryDelegate getAlternateDelegate(ClientConnectionDelegate currentDelegate)
+   {
+      //We need to choose which delegate to fail over to
+      
+      //This is determined by the failoverIndexes array
+      //The fail over delegate for delegates[i] is given by
+      //delegates[failoverIndexes[i]]
+      
+      //The technique (TODO) is to try that server. There is a possibility the expected failover server
+      //is not actually the real failover server, e.g. since the client side array and server side state
+      //are not totally in synch.
+      //In this case we need to implement hopping, so the incorrect server redirects us to the correct server.
+      //This may require several hops to get the right server (since another failure(s) can occur when the hop is
+      //happening!)
+      
+      ConnectionState currentState = (ConnectionState)((DelegateSupport)currentDelegate).getState();
+      
+      String currentLocator =
+         currentState.getRemotingConnection().getInvokingClient().getInvoker().getLocator().getLocatorURI();
+      
+      int local = -1;
+      
+      for (int i = 0; i < delegates.length; i++)
+      {
+         ConnectionState state = (ConnectionState)((DelegateSupport)delegates[i]).getState();
+         
+         String locator =
+            state.getRemotingConnection().getInvokingClient().getInvoker().getLocator().getLocatorURI();
+         
+         if (currentLocator.equals(locator))
+         {
+            local = i;
+            
+            break;
+         }
+      }
+      
+      //Sanity
+      if (local == -1)
+      {
+         throw new IllegalStateException("Cannot find local delegate!");
+      }
+      
+      if (delegates.length == 1)
+      {
+         throw new IllegalStateException("Cannot failover connection since no servers to fail over onto");
+      }      
+
+      return delegates[failoverIndexes[local]];
+   }
+   
+   private void failover(ClientConnectionDelegate failedConnection, ClientConnectionDelegate newConnection) throws Exception
+   {
+      if (trace) { log.trace("calling handleFailover"); }
+
+      ConnectionState failedState = (ConnectionState)failedConnection.getState();
+
+      int oldServerID = failedState.getServerID();
+
+      ConnectionState newState = (ConnectionState)newConnection.getState();
+
+      failedState.copy(newState);
+
+      if (failedState.getClientID() != null)
+      {
+         newConnection.setClientID(failedState.getClientID());
+      }
+
+      // Transfering state from newDelegate to currentDelegate
+      failedConnection.copyState(newConnection);
+
+      if (failedState.isStarted())
+      {
+         failedConnection.start();
+      }
+
+      for(Iterator i = failedState.getChildren().iterator(); i.hasNext(); )
+      {
+         SessionState failedSessionState = (SessionState)i.next();
+
+         ClientSessionDelegate newSessionDelegate = (ClientSessionDelegate)newConnection.
+            createSessionDelegate(failedSessionState.isTransacted(),
+                                  failedSessionState.getAcknowledgeMode(),
+                                  failedSessionState.isXA());
+
+         ClientSessionDelegate failedSessionDelegate =
+            (ClientSessionDelegate)failedSessionState.getDelegate();
+
+         failedSessionDelegate.copyState(newSessionDelegate);
+
+         if (trace) { log.trace("replacing session (" + failedSessionDelegate + ") with a new failover session " + newSessionDelegate); }
+
+         //TODO Clebert please add comment as to why this clone is necessary
+         //In general, please comment more - there is a serious lack of comments!!
+         List children = new ArrayList();
+         children.addAll(failedSessionState.getChildren());
+
+         for(Iterator j = children.iterator(); j.hasNext(); )
+         {
+            HierarchicalStateSupport sessionChild = (HierarchicalStateSupport)j.next();
+
+            if (sessionChild instanceof ProducerState)
+            {
+               handleFailoverOnProducer((ProducerState)sessionChild, newSessionDelegate);
+            }
+            else if (sessionChild instanceof ConsumerState)
+            {
+               handleFailoverOnConsumer(failedConnection,
+                                        failedState,
+                                        failedSessionState,
+                                        (ConsumerState)sessionChild,
+                                        failedSessionDelegate,
+                                        oldServerID);
+            }
+            else if (sessionChild instanceof BrowserState)
+            {
+                handleFailoverOnBrowser((BrowserState)sessionChild, newSessionDelegate);
+            }
+         }
+      }
+   }
+
+   private void handleFailoverOnConsumer(ClientConnectionDelegate connectionDelegate,
+                                         ConnectionState failedConnectionState,
+                                         SessionState failedSessionState,
+                                         ConsumerState failedConsumerState,
+                                         ClientSessionDelegate failedSessionDelegate,
+                                         int oldServerID)
+      throws JMSException
+   {
+      ClientConsumerDelegate failedConsumerDelegate =
+         (ClientConsumerDelegate)failedConsumerState.getDelegate();
+
+      if (trace) { log.trace("handleFailoverOnConsumer: creating alternate consumer"); }
+
+      ClientConsumerDelegate newConsumerDelegate = (ClientConsumerDelegate)failedSessionDelegate.
+         failOverConsumer((JBossDestination)failedConsumerState.getDestination(),
+                                failedConsumerState.getSelector(),
+                                failedConsumerState.isNoLocal(),
+                                failedConsumerState.getSubscriptionName(),
+                                failedConsumerState.isConnectionConsumer(),
+                                failedConsumerDelegate.getChannelId());
+
+      if (trace) { log.trace("handleFailoverOnConsumer: alternate consumer created"); }
+
+      failedConsumerDelegate.copyState(newConsumerDelegate);
+
+      int oldConsumerID = failedConsumerState.getConsumerID();
+
+      ConsumerState newState = (ConsumerState)newConsumerDelegate.getState();
+      failedConsumerState.copy(newState);
+
+      failedConnectionState.getResourceManager().
+         handleFailover(failedSessionState.getCurrentTxId(),
+                        oldConsumerID,
+                        failedConsumerState.getConsumerID());
+
+      CallbackManager cm = failedConnectionState.getRemotingConnection().getCallbackManager();
+
+      MessageCallbackHandler handler = cm.unregisterHandler(oldServerID, oldConsumerID);
+      handler.setConsumerId(failedConsumerState.getConsumerID());
+
+      cm.registerHandler(failedConnectionState.getServerID(),
+                         failedConsumerState.getConsumerID(),
+                         handler);
+      failedSessionState.addCallbackHandler(handler);
+
+   }
+
+   private void handleFailoverOnProducer(ProducerState failedProducerState,
+                                         ClientSessionDelegate failedSessionDelegate)
+      throws JMSException
+   {
+      ClientProducerDelegate newProducerDelegate = (ClientProducerDelegate)failedSessionDelegate.
+         createProducerDelegate((JBossDestination)failedProducerState.getDestination());
+
+      ClientProducerDelegate failedProducerDelegate =
+         (ClientProducerDelegate)failedProducerState.getDelegate();
+
+      failedProducerDelegate.copyState(newProducerDelegate);
+
+      if (trace) { log.trace("handling fail over on producerDelegate " + failedProducerDelegate + " destination=" + failedProducerState.getDestination()); }
+   }
+
+   private void handleFailoverOnBrowser(BrowserState failedBrowserState,
+                                         ClientSessionDelegate failedSessionDelegate)
+      throws JMSException
+   {
+      ClientBrowserDelegate newBrowserDelegate = (ClientBrowserDelegate)failedSessionDelegate.
+          createBrowserDelegate(failedBrowserState.getJmsDestination(),failedBrowserState.getMessageSelector());
+
+      ClientBrowserDelegate failedBrowserDelegate =
+         (ClientBrowserDelegate)failedBrowserState.getDelegate();
+
+      failedBrowserDelegate.copyState(newBrowserDelegate);
+
+      if (trace) { log.trace("handling fail over on browserDelegate " + failedBrowserDelegate + " destination=" + failedBrowserState.getJmsDestination() + " selector=" + failedBrowserState.getMessageSelector()); }
+
+   }
+   
+   private class Listener implements ConnectionListener
+   {
+      private ClientConnectionDelegate connection;
+      
+      Listener(ClientConnectionDelegate connection)
+      {
+         this.connection = connection;
+      }
+      
+      public void handleConnectionException(Throwable throwable, Client client)
+      {
+         try
+         {
+            log.info("Caught connection exception for connection: " + connection);
+            
+            handleFailure(connection);
+         }
+         catch (Throwable e)
+         {
+            e.printStackTrace();
+         }
+      }
+   }
+}
+
+

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/StateCreationAspect.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/StateCreationAspect.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/container/StateCreationAspect.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -21,6 +21,8 @@
   */
 package org.jboss.jms.client.container;
 
+import javax.jms.Destination;
+
 import org.jboss.aop.Advised;
 import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.aop.joinpoint.MethodInvocation;
@@ -29,7 +31,13 @@
 import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
 import org.jboss.jms.client.delegate.ClientProducerDelegate;
 import org.jboss.jms.client.delegate.DelegateSupport;
-import org.jboss.jms.client.state.*;
+import org.jboss.jms.client.remoting.JMSRemotingConnection;
+import org.jboss.jms.client.state.BrowserState;
+import org.jboss.jms.client.state.ConnectionState;
+import org.jboss.jms.client.state.ConsumerState;
+import org.jboss.jms.client.state.HierarchicalState;
+import org.jboss.jms.client.state.ProducerState;
+import org.jboss.jms.client.state.SessionState;
 import org.jboss.jms.delegate.BrowserDelegate;
 import org.jboss.jms.delegate.ConsumerDelegate;
 import org.jboss.jms.delegate.ProducerDelegate;
@@ -37,12 +45,11 @@
 import org.jboss.jms.destination.JBossDestination;
 import org.jboss.jms.message.MessageIdGenerator;
 import org.jboss.jms.message.MessageIdGeneratorFactory;
+import org.jboss.jms.server.Version;
 import org.jboss.jms.server.remoting.MetaDataConstants;
 import org.jboss.jms.tx.ResourceManager;
 import org.jboss.jms.tx.ResourceManagerFactory;
 
-import javax.jms.Destination;
-
 /**
  * Maintains the hierarchy of parent and child state objects. For each delegate, this interceptor
  * maintains a state object and it's children/parent. The state object is then made accessible to
@@ -78,16 +85,33 @@
       ClientConnectionDelegate connectionDelegate = (ClientConnectionDelegate)inv.invokeNext();
       connectionDelegate.init();
 
-      int serverID = cfd.getServerID();
-
+      SimpleMetaData md = ((Advised)connectionDelegate)._getInstanceAdvisor().getMetaData();
+      
+      int serverID =
+         ((Integer)md.getMetaData(MetaDataConstants.JMS, MetaDataConstants.SERVER_ID)).intValue();
+      
+      Version connectionVersion = 
+         (Version)md.getMetaData(MetaDataConstants.JMS, MetaDataConstants.VERSION_NUMBER);
+      
+      JMSRemotingConnection connection = 
+         (JMSRemotingConnection)md.getMetaData(MetaDataConstants.JMS, MetaDataConstants.REMOTING_CONNECTION);
+      
+      if (connectionVersion == null)
+      {
+         throw new IllegalStateException("Connection version is null");
+      }
+           
+      //We have one resource manager per unique server
       ResourceManager rm = ResourceManagerFactory.instance.checkOutResourceManager(serverID);
+      
+      //We have one message id generator per unique server
       MessageIdGenerator gen =
          MessageIdGeneratorFactory.instance.checkOutGenerator(serverID, cfd);
 
       ConnectionState connectionState =
          new ConnectionState(serverID, connectionDelegate,
-                             connectionDelegate.getRemotingConnection(),
-                             cfd.getVersionToUse(), rm, gen);
+                             connection,
+                             connectionVersion, rm, gen);
 
       connectionDelegate.setState(connectionState);
       return connectionDelegate;

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConnectionDelegate.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConnectionDelegate.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConnectionDelegate.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -28,11 +28,12 @@
 import javax.jms.ServerSessionPool;
 import javax.transaction.xa.Xid;
 
+import org.jboss.aop.util.PayloadKey;
 import org.jboss.jms.client.JBossConnectionConsumer;
-import org.jboss.jms.client.remoting.JMSRemotingConnection;
 import org.jboss.jms.client.state.ConnectionState;
 import org.jboss.jms.delegate.ConnectionDelegate;
 import org.jboss.jms.delegate.SessionDelegate;
+import org.jboss.jms.server.remoting.MetaDataConstants;
 import org.jboss.jms.tx.TransactionRequest;
 import org.jboss.remoting.Client;
 
@@ -54,15 +55,19 @@
    private static final long serialVersionUID = 6680015509555859038L;
 
    // Attributes ----------------------------------------------------
-   private transient JMSRemotingConnection remotingConnection;
 
+   // This should not be exposed other than through meta data
+   private int serverId;
+
    // Static --------------------------------------------------------
 
    // Constructors --------------------------------------------------
 
-   public ClientConnectionDelegate(int objectID)
+   public ClientConnectionDelegate(int objectID, int serverId)
    {
       super(objectID);
+      
+      this.serverId = serverId;
    }
 
    public ClientConnectionDelegate()
@@ -205,39 +210,20 @@
       throw new IllegalStateException("This invocation should not be handled here!");
    }
 
-    /** @see org.jboss.jms.client.container.ConnectionAspect#handleFailover(org.jboss.aop.joinpoint.Invocation) */
-    public void failOver(ConnectionDelegate newConnection)
-   {
-       throw new IllegalStateException("This invocation should not be handled here!");
-   }
-
    // Public --------------------------------------------------------
 
    public String toString()
    {
       return "ConnectionDelegate[" + id + "]";
    }
-
-    public void setRemotingConnection(JMSRemotingConnection conn)
-    {
-       if (state!=null)
-       {
-           ((ConnectionState)state).setRemotingConnection(conn);
-       }
-       this.remotingConnection=conn;
-    }
-
-   public JMSRemotingConnection getRemotingConnection()
+   
+   public void init()
    {
-      return remotingConnection;
+      super.init();
+      getMetaData().addMetaData(MetaDataConstants.JMS, MetaDataConstants.SERVER_ID,
+                                new Integer(serverId), PayloadKey.TRANSIENT);
    }
 
-   public void copyState(DelegateSupport newDelegate)
-   {
-       super.copyState(newDelegate);
-       setRemotingConnection(((ClientConnectionDelegate)newDelegate).getRemotingConnection());
-   }
-
    // Protected -----------------------------------------------------
 
    protected Client getClient()
@@ -245,7 +231,7 @@
       return ((ConnectionState)state).getRemotingConnection().getInvokingClient();
    }
 
-    // Package Private -----------------------------------------------
+   // Package Private -----------------------------------------------
 
    // Private -------------------------------------------------------
 

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConnectionFactoryDelegate.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConnectionFactoryDelegate.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConnectionFactoryDelegate.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -23,8 +23,10 @@
 
 import java.util.HashMap;
 import java.util.Map;
+
 import javax.jms.JMSException;
-import org.jboss.aop.Dispatcher;
+
+import org.jboss.aop.Advised;
 import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.aop.joinpoint.MethodInvocation;
 import org.jboss.aop.metadata.SimpleMetaData;
@@ -64,30 +66,48 @@
 
    // Attributes ----------------------------------------------------
 
+   //This data is needed in order to create a connection
    protected String serverLocatorURI;
    protected Version serverVersion;
-   protected int serverID;
    protected boolean clientPing;
    
-   /** This is the serverSide objectID used on JMSInvoker */
-   protected String strObjectID;
+   private transient boolean trace;
 
-   private boolean trace;
-
    // Static --------------------------------------------------------
+   
+   /*
+    * Calculate what version to use.
+    * The client itself has a version, but we also support other versions of servers lower if the
+    * connection version is lower (backwards compatibility)
+    */
+   public static Version getVersionToUse(Version connectionVersion)
+   {
+      Version clientVersion = Version.instance();
 
+      Version versionToUse;
+
+      if (connectionVersion.getProviderIncrementingVersion() <= clientVersion.getProviderIncrementingVersion())
+      {
+         versionToUse = connectionVersion;
+      }
+      else
+      {
+         versionToUse = clientVersion;
+      }
+
+      return versionToUse;
+   }
+
    // Constructors --------------------------------------------------
 
-   public ClientConnectionFactoryDelegate(int objectID, String strObjectID, String serverLocatorURI,
-                                          Version serverVersion, int serverID,
+   public ClientConnectionFactoryDelegate(int objectID, String serverLocatorURI,
+                                          Version serverVersion,
                                           boolean clientPing)
    {
       super(objectID);
 
-      this.strObjectID = strObjectID;
       this.serverLocatorURI = serverLocatorURI;
       this.serverVersion = serverVersion;
-      this.serverID = serverID;
       this.clientPing = clientPing;
       trace = log.isTraceEnabled();
    }
@@ -137,11 +157,6 @@
 
       SimpleMetaData md = mi.getMetaData();
 
-      md.addMetaData(Dispatcher.DISPATCHER,
-                     Dispatcher.OID,
-                     strObjectID,
-                     PayloadKey.AS_IS);
-
       /*
        * If the method being invoked is createConnectionDelegate then we must invoke it on the same
        * remoting client subsequently used by the connection.
@@ -178,6 +193,8 @@
       }
       else
       {
+         //getClientAOPConfig or getIDBlock
+         
          // Create a client - make sure pinging is off
          
          Map configuration = new HashMap();
@@ -194,7 +211,8 @@
          client.setUnMarshaller(new JMSWireFormat());         
       }
 
-      byte v = getVersionToUse().getProviderIncrementingVersion();
+      //What version should we use for invocations on this connection factory?
+      byte v = getVersionToUse(serverVersion).getProviderIncrementingVersion();
       
       MessagingMarshallable request = new MessagingMarshallable(v, mi);
       
@@ -224,15 +242,6 @@
          
          throw t;
       }
-      finally
-      {
-         if (remotingConnection == null)
-         {
-            //Not a call to createConnectionDelegate - disconnect the client
-            
-            // client.disconnect();
-         }
-      }
 
       Object ret = response.getLoad();
       
@@ -241,50 +250,33 @@
          // It was a call to createConnectionDelegate - set the remoting connection to use
          ClientConnectionDelegate connectionDelegate = (ClientConnectionDelegate)ret;
          
-         connectionDelegate.setRemotingConnection(remotingConnection);
+         //We set the version for the connection and the remoting connection on the meta-data
+         //this is so the StateCreationAspect can pick it up
+         
+         SimpleMetaData metaData = ((Advised)connectionDelegate)._getInstanceAdvisor().getMetaData();
+         
+         metaData.addMetaData(MetaDataConstants.JMS, MetaDataConstants.REMOTING_CONNECTION,
+                              remotingConnection, PayloadKey.TRANSIENT);
+         
+         metaData.addMetaData(MetaDataConstants.JMS, MetaDataConstants.VERSION_NUMBER,
+                              new Byte(v), PayloadKey.TRANSIENT);
+
       }
 
       return ret;
    }
 
-   public Version getServerVersion()
+   public String toString()
    {
-      return serverVersion;
+      return "ClientConnectionFactoryDelegate[objectId=" + id + "]";
    }
-
-   public int getServerID()
-   {
-      return serverID;
-   }
-
-   public Version getVersionToUse()
-   {
-      Version clientVersion = Version.instance();
-
-      Version versionToUse;
-
-      if (serverVersion.getProviderIncrementingVersion() <= clientVersion.getProviderIncrementingVersion())
-      {
-         versionToUse = serverVersion;
-      }
-      else
-      {
-         versionToUse = clientVersion;
-      }
-
-      return versionToUse;
-   }
-
+   
+   //This MUST ONLY be used in testing
    public String getServerLocatorURI()
    {
       return serverLocatorURI;
    }
 
-   public String toString()
-   {
-      return "ConnectionFactoryDelegate[strObjectID=" + strObjectID + "]";
-   }
-
    // Protected -----------------------------------------------------
 
    protected Client getClient()

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConsumerDelegate.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConsumerDelegate.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientConsumerDelegate.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -50,9 +50,11 @@
 
    // Attributes ----------------------------------------------------
    
-   protected int bufferSize;
+   // This should not be exposed other than through meta data
+   private int bufferSize;
 
-   protected long channelId;
+   // This should not be exposed other than through meta data
+   private long channelId;
 
    // Static --------------------------------------------------------
 

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -200,7 +200,7 @@
                                             String selectorString,
                                             boolean noLocal,  String subscriptionName,
                                             boolean connectionConsumer,
-                                            long oldChannelID, int nodeId) throws JMSException
+                                            long oldChannelID) throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }

Added: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClusteredClientConnectionFactoryDelegate.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClusteredClientConnectionFactoryDelegate.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/ClusteredClientConnectionFactoryDelegate.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.client.delegate;
+
+import org.jboss.aop.util.PayloadKey;
+import org.jboss.jms.server.Version;
+import org.jboss.jms.server.remoting.MetaDataConstants;
+
+/**
+ * A ClusteredClientConnectionFactoryDelegate
+ * 
+ * This ConnectionFactoryDelegate handles connection factory operations
+ * (getIdBlock, getClientAOPConfig like any other connection factory)
+ * 
+ * The actual failover logic is in the FailoverAspect
+ * 
+ * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class ClusteredClientConnectionFactoryDelegate extends
+                ClientConnectionFactoryDelegate
+{
+   private static final long serialVersionUID = 8286850860206289277L;
+   
+   
+   /*
+    * If delegates[i] is the current delegate, then the failover delegate
+    * is given by delegates[failoverIndexes[i]]
+    */   
+   private ClientConnectionFactoryDelegate[] delegates;
+   
+   private int[] failoverIndexes;
+      
+   public ClusteredClientConnectionFactoryDelegate(int objectID,
+            String serverLocatorURI, Version serverVersion, boolean clientPing)
+   {
+      super(objectID, serverLocatorURI, serverVersion, clientPing);
+   }
+   
+   public void init()
+   {
+      super.init();
+      
+      for (int i=0; i < delegates.length; i++)
+      {
+         delegates[i].init();
+      }
+      
+      //We add this to the meta data so the failOver aspect can get access to it
+      getMetaData().addMetaData(MetaDataConstants.JMS, MetaDataConstants.CF_DELEGATES,
+                                delegates, PayloadKey.TRANSIENT);
+      
+      getMetaData().addMetaData(MetaDataConstants.JMS, MetaDataConstants.CF_FAILOVER_INDEXES,
+                                failoverIndexes, PayloadKey.TRANSIENT);
+   }
+   
+   //Only be used in testing
+   public ClientConnectionFactoryDelegate[] getDelegates()
+   {
+      return delegates;
+   }
+   
+   public void setFailoverDelegates(ClientConnectionFactoryDelegate[] delegates, int[] failoverIndexes)
+   {
+      this.delegates = delegates;
+      
+      this.failoverIndexes = failoverIndexes;
+   }
+   
+}

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/DelegateSupport.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/DelegateSupport.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/delegate/DelegateSupport.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -67,9 +67,15 @@
 
    // Attributes ----------------------------------------------------
 
+   //This is set on the server
    protected int id;
    
-   protected HierarchicalState state;
+   //This is set on the client
+   //The reason we don't use the meta-data to store the state for the delegate is to avoid
+   //the extra HashMap lookup that would entail.
+   //This can be significant since the state could be queried for many aspects
+   //in an a single invocation
+   protected transient HierarchicalState state;
    
    // Static --------------------------------------------------------
 

Deleted: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/ha/ClusteredConnectionFactoryDelegate.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/ha/ClusteredConnectionFactoryDelegate.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/client/ha/ClusteredConnectionFactoryDelegate.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -1,126 +0,0 @@
-package org.jboss.jms.client.ha;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-import java.io.Serializable;
-import javax.jms.JMSException;
-import org.jboss.jms.client.delegate.ClientConnectionDelegate;
-import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
-import org.jboss.jms.client.state.ConnectionState;
-import org.jboss.jms.delegate.ConnectionDelegate;
-import org.jboss.jms.delegate.ConnectionFactoryDelegate;
-import org.jboss.messaging.core.plugin.IdBlock;
-import org.jboss.remoting.Client;
-
-/**
- * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
- * @version <tt>$Revision:$</tt>
- *          <p/>
- *          $Id:$
- */
-public class ClusteredConnectionFactoryDelegate implements ConnectionFactoryDelegate, Serializable
-{
-
-   private int current;
-   ClientConnectionFactoryDelegate[] delegates;
-   private ConcurrentHashMap clientsMap = new ConcurrentHashMap();
-   transient private Listener listener = new Listener();
-
-   public ClusteredConnectionFactoryDelegate(ClientConnectionFactoryDelegate[] delegates)
-   {
-      this.delegates = delegates;
-   }
-
-   public ConnectionDelegate createConnectionDelegate(String username, String password) throws JMSException
-   {
-      ClientConnectionDelegate delegate = (ClientConnectionDelegate)getRoundRobbinFactoryDelegate().createConnectionDelegate(username, password);
-      delegate.getRemotingConnection().getInvokingClient().addConnectionListener(new Listener());
-      clientsMap.put(delegate.getRemotingConnection().getInvokingClient(),delegate);
-      return delegate;
-   }
-
-   class Listener implements org.jboss.remoting.ConnectionListener
-   {
-      public void handleConnectionException(Throwable throwable, Client client)
-      {
-         try
-         {
-            System.out.println("Failing over client " + client);
-            ClientConnectionFactoryDelegate alternateFactory = getAlternateDelegate(client);
-            ClientConnectionDelegate delegate = (ClientConnectionDelegate) clientsMap.get(client);
-            ConnectionState connectionState = (ConnectionState) delegate.getState();
-            ClientConnectionDelegate newConnection = (ClientConnectionDelegate) alternateFactory.createConnectionDelegate(connectionState.getUser(), connectionState.getPassword());
-            delegate.failOver(newConnection);
-         }
-         catch (Throwable e)
-         {
-            e.printStackTrace();
-         }
-      }
-   }
-
-
-
-   public synchronized ClientConnectionFactoryDelegate getRoundRobbinFactoryDelegate()
-   {
-      ClientConnectionFactoryDelegate currentDelegate = delegates[current++];
-      if (current >= delegates.length)
-      {
-         current = 0;
-      }
-      return currentDelegate;
-   }
-
-   public byte[] getClientAOPConfig() throws JMSException
-   {
-      throw new RuntimeException("Shouldn't be called here");
-   }
-
-   public IdBlock getIdBlock(int size) throws JMSException
-   {
-      throw new RuntimeException("Shouldn't be called here");
-   }
-
-   /** This method was meant for testcases only */
-   public ClientConnectionFactoryDelegate[] getDelegates()
-   {
-      return delegates;
-   }
-
-   public synchronized void init()
-   {
-      for (int i=0;i<delegates.length;i++)
-      {
-         delegates[i].init();
-      }
-   }
-
-   // private
-
-   /**
-    * Return the next client needed for a failover
-    * @param client
-    * @return
-    */
-   private ClientConnectionFactoryDelegate getAlternateDelegate(Client client)
-   {
-      String serverURI = client.getInvoker().getLocator().getLocatorURI();
-      int local = -1;
-      for (int i = 0; i < delegates.length; i++)
-      {
-         if (delegates[i].getServerLocatorURI().equals(serverURI))
-         {
-            local = i;
-            break;
-         }
-      }
-
-      local++;
-      if (local >= delegates.length)
-      {
-         local = 0;
-      }
-
-      return delegates[local];
-
-   }
-}

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/delegate/ConnectionDelegate.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/delegate/ConnectionDelegate.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/delegate/ConnectionDelegate.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -57,6 +57,6 @@
    /**
     * Reconnects the current connection hierarchy using newConnection's properties.
     */
-    void failOver(ConnectionDelegate newConnection);
+    //void failOver(ConnectionDelegate newConnection);
 
 }

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ConnectionFactoryManager.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ConnectionFactoryManager.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ConnectionFactoryManager.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -22,7 +22,6 @@
 package org.jboss.jms.server;
 
 import org.jboss.jms.server.connectionfactory.JNDIBindings;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
 import org.jboss.messaging.core.plugin.contract.MessagingComponent;
 
 /**
@@ -36,23 +35,17 @@
 {
    /**
     * @param jndiBindings - if null, the connection factory will be created and registered with the
-    *                     AOP subsystem, but not bound in JNDI.
+    *        AOP subsystem, but not bound in JNDI.
+    *
     * @return an identifier that uniques identifies the registered ConnectionFactory.
     */
-   int registerConnectionFactory(String clientID, String serverObjectID, JNDIBindings jndiBindings,
+   void registerConnectionFactory(String uniqueName, String clientID, JNDIBindings jndiBindings,
                                  String locatorURI, boolean clientPing,
                                  int prefetchSize,
                                  int defaultTempQueueFullSize,
                                  int defaultTempQueuePageSize,
-                                 int defaultTempQueueDownCacheSize) throws Exception;
+                                 int defaultTempQueueDownCacheSize,
+                                 boolean clustered) throws Exception;
 
-   void registerClusteredConnectionFactory(ClusteredPostOffice postOffice,
-                                                               JNDIBindings jndiBindings) throws Exception;
-
-   void unregisterConnectionFactory(String connectionFactoryID) throws Exception;
-
-   javax.jms.ConnectionFactory getConnectionFactory(int connectionFactoryID);
-
-   javax.jms.ConnectionFactory[] getAllConnectionFactories();
-
+   void unregisterConnectionFactory(String uniqueName, boolean clustered) throws Exception;
 }

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ServerPeer.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ServerPeer.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/ServerPeer.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -21,15 +21,16 @@
   */
 package org.jboss.jms.server;
 
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.Map;
 import java.util.Set;
+
 import javax.management.Attribute;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
+
 import org.jboss.aop.AspectXmlLoader;
 import org.jboss.jms.server.connectionfactory.ConnectionFactoryJNDIMapper;
 import org.jboss.jms.server.connectionmanager.SimpleConnectionManager;
@@ -47,6 +48,7 @@
 import org.jboss.messaging.core.plugin.contract.MessageStore;
 import org.jboss.messaging.core.plugin.contract.PersistenceManager;
 import org.jboss.messaging.core.plugin.contract.PostOffice;
+import org.jboss.messaging.core.plugin.contract.Replicator;
 import org.jboss.messaging.core.plugin.postoffice.DefaultPostOffice;
 import org.jboss.messaging.core.tx.TransactionRepository;
 import org.jboss.messaging.util.Util;
@@ -57,6 +59,8 @@
 import org.jboss.system.ServiceMBeanSupport;
 import org.w3c.dom.Element;
 
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
+
 /**
  * A JMS server peer.
  *
@@ -116,14 +120,16 @@
    protected PersistenceManager persistenceManager;
    
    protected ObjectName queuePostOfficeObjectName;
-   protected DefaultPostOffice queuePostOffice;
+   protected PostOffice queuePostOffice;
    
    protected ObjectName topicPostOfficeObjectName;
-   protected DefaultPostOffice topicPostOffice;
+   protected PostOffice topicPostOffice;
      
    protected ObjectName jmsUserManagerObjectName;
    protected JMSUserManager jmsUserManager;
    
+   protected Replicator dataReplicator;
+   
    //Other stuff
 
    // We keep a map of consumers to prevent us to recurse through the attached session in order to
@@ -594,7 +600,7 @@
       // We get the reference lazily to avoid problems with MBean circular dependencies
       if (queuePostOffice == null)
       {
-         queuePostOffice = (DefaultPostOffice)getServer().
+         queuePostOffice = (PostOffice)getServer().
             getAttribute(queuePostOfficeObjectName, "Instance");
       }
       return queuePostOffice;
@@ -605,12 +611,27 @@
       // We get the reference lazily to avoid problems with MBean circular dependencies
       if (topicPostOffice == null)
       {
-         topicPostOffice = (DefaultPostOffice)getServer().
+         topicPostOffice = (PostOffice)getServer().
             getAttribute(topicPostOfficeObjectName, "Instance");
       }
       return topicPostOffice;        
    }
+   
+   public Replicator getDataReplicator() throws Exception
+   {
+      //For now we just choose the queue post office - soon we merge both post offices into one
+      //anyway
       
+      PostOffice office = getQueuePostOfficeInstance();
+      
+      if (!office.isLocal())
+      {
+         dataReplicator = (Replicator)office;
+      }
+      
+      return dataReplicator;
+   }
+      
    public synchronized int getNextObjectID()
    {
       return objectIDSequence++;

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -34,9 +34,9 @@
    // Attributes ----------------------------------------------------
 
    protected String clientID;
-   protected int connectionFactoryID;
    protected JNDIBindings jndiBindings;
    protected int prefetchSize = 150;
+   protected boolean clustered;
    
    protected int defaultTempQueueFullSize = 75000;
    protected int defaultTempQueuePageSize = 2000;
@@ -106,9 +106,12 @@
                   new String[] {"org.jboss.remoting.ConnectionListener"});                     
          }
          
-         connectionFactoryID = connectionFactoryManager.
-            registerConnectionFactory(clientID, this.getName(), jndiBindings, locatorURI, enablePing, prefetchSize,
-                     defaultTempQueueFullSize, defaultTempQueuePageSize, defaultTempQueueDownCacheSize);
+         //We use the MBean service name to uniquely identify the cf
+         
+         connectionFactoryManager.
+            registerConnectionFactory(this.getName(), clientID, jndiBindings, locatorURI, enablePing, prefetchSize,
+                     defaultTempQueueFullSize, defaultTempQueuePageSize, defaultTempQueueDownCacheSize,
+                     clustered);
       
          InvokerLocator locator = new InvokerLocator(locatorURI);
          String info =
@@ -138,7 +141,7 @@
       {
          started = false;
          
-         connectionFactoryManager.unregisterConnectionFactory(clientID);
+         connectionFactoryManager.unregisterConnectionFactory(this.getName(), clustered);
          
          connectorManager.unregisterConnector(connectorObjectName.getCanonicalName());
          
@@ -244,6 +247,21 @@
    {
       return connectorObjectName;
    }
+   
+   public boolean isClustered()
+   {
+      return clustered;
+   }
+   
+   public void setClustered(boolean clustered)
+   {
+      if (started)
+      {
+         log.warn("Clustered can only be changed when connection factory is stopped");
+         return;
+      }
+      this.clustered = clustered;
+   }
 
    // JMX managed operations ----------------------------------------
 

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -1,38 +1,39 @@
 /*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
 package org.jboss.jms.server.connectionfactory;
 
-import java.util.ArrayList;
+import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+
 import javax.naming.Context;
 import javax.naming.InitialContext;
-import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+
 import org.jboss.jms.client.JBossConnectionFactory;
 import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
-import org.jboss.jms.client.ha.ClusteredConnectionFactoryDelegate;
-import org.jboss.jms.delegate.ConnectionFactoryDelegate;
+import org.jboss.jms.client.delegate.ClusteredClientConnectionFactoryDelegate;
 import org.jboss.jms.server.ConnectionFactoryManager;
 import org.jboss.jms.server.ServerPeer;
 import org.jboss.jms.server.endpoint.ServerConnectionFactoryEndpoint;
@@ -40,10 +41,8 @@
 import org.jboss.jms.server.remoting.JMSDispatcher;
 import org.jboss.jms.util.JNDIUtil;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.postoffice.cluster.NodeAddressInfo;
-import org.jboss.messaging.core.plugin.postoffice.cluster.factoryinterface.ConnectionFactoryInfo;
-import org.jboss.messaging.core.plugin.postoffice.cluster.factoryinterface.ConnectionFactoryUpdater;
+import org.jboss.messaging.core.plugin.contract.ReplicationListener;
+import org.jboss.messaging.core.plugin.contract.Replicator;
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
@@ -53,101 +52,90 @@
  *
  * $Id$
  */
-public class ConnectionFactoryJNDIMapper implements ConnectionFactoryManager, ConnectionFactoryUpdater
+public class ConnectionFactoryJNDIMapper 
+   implements ConnectionFactoryManager, ReplicationListener
 {
    // Constants -----------------------------------------------------
-
+   
    private static final Logger log = Logger.getLogger(ConnectionFactoryJNDIMapper.class);
    
    // Static --------------------------------------------------------
    
+   private static final String CF_PREFIX = "CF_";
+   
    // Attributes ----------------------------------------------------
-
+   
    protected Context initialContext;
    protected ServerPeer serverPeer;
    protected Map endpoints;
    protected Map factories;
-
+   
+   protected Replicator replicator;
+   
    // Constructors --------------------------------------------------
-
+   
    public ConnectionFactoryJNDIMapper(ServerPeer serverPeer) throws Exception
    {
       this.serverPeer = serverPeer;
       endpoints = new HashMap();
       factories = new HashMap();
    }
-
+   
    // ConnectionFactoryManager implementation -----------------------
-
-   public synchronized void registerClusteredConnectionFactory(
-                                                     ClusteredPostOffice postOffice,
-                                                     JNDIBindings jndiBindings) throws Exception
+   
+   
+   
+   public synchronized void registerConnectionFactory(String uniqueName,
+            String clientID,
+            JNDIBindings jndiBindings,
+            String locatorURI,
+            boolean clientPing,
+            int prefetchSize,
+            int defaultTempQueueFullSize,
+            int defaultTempQueuePageSize,
+            int defaultTempQueueDownCacheSize,
+            boolean clustered) throws Exception
    {
-
-
-      ClusteredConnectionFactoryDelegate factoryDelegate = createClusteredConnectionFactoryDelegate(postOffice);
-      JBossConnectionFactory cf = new JBossConnectionFactory(factoryDelegate);
-
-      if (jndiBindings != null)
-      {
-         List jndiNames = jndiBindings.getNames();
-         for (Iterator i = jndiNames.iterator(); i.hasNext();)
-         {
-            String jndiName = (String) i.next();
-            boolean isBound = false;
-
-            try
-            {
-               isBound = initialContext.lookup(jndiName) != null;
-            }
-            catch (NameNotFoundException ignored)
-            {
-            }
-
-
-            if (isBound)
-            {
-               initialContext.rebind(jndiName,cf);
-            }
-            else
-            {
-               JNDIUtil.rebind(initialContext, jndiName, cf);
-            }
-         }
-      }
-   }
-
-
-   public synchronized int registerConnectionFactory(String clientID,
-                                                     String serverObjectID,
-                                                     JNDIBindings jndiBindings,
-                                                     String locatorURI,
-                                                     boolean clientPing,
-                                                     int prefetchSize,
-                                                     int defaultTempQueueFullSize,
-                                                     int defaultTempQueuePageSize,
-                                                     int defaultTempQueueDownCacheSize) throws Exception
-   {
       int id = serverPeer.getNextObjectID();
-
+      
       ServerConnectionFactoryEndpoint endpoint =
-         new ServerConnectionFactoryEndpoint(-1, serverPeer, clientID, jndiBindings,
-                                             prefetchSize, defaultTempQueueFullSize,
-                                             defaultTempQueuePageSize,
-                                             defaultTempQueueDownCacheSize);
-
+         new ServerConnectionFactoryEndpoint(id, serverPeer, clientID,
+                  jndiBindings, prefetchSize,
+                  defaultTempQueueFullSize,
+                  defaultTempQueuePageSize, defaultTempQueueDownCacheSize);
+      
       ClientConnectionFactoryDelegate delegate =
-         new ClientConnectionFactoryDelegate(-1, serverObjectID, locatorURI, serverPeer.getVersion(),
-                                             serverPeer.getServerPeerID(), clientPing);
-
+         new ClientConnectionFactoryDelegate(id, locatorURI, serverPeer.getVersion(),
+                  clientPing);
+      
+      if (clustered)
+      {
+         //First we must replicate the delegate across the cluster so that all the ConnectionFactoryJNDIMapper
+         //instances on different nodes have access to the list of local connection factories
+         //so they can be added to the clustered connection factory
+         
+         replicator.putReplicant(CF_PREFIX + uniqueName, delegate);         
+         
+         //Get the list of delegates
+         
+         Map replicants = replicator.getReplicants(CF_PREFIX + uniqueName);
+         
+         //Create a clustered delegate which contains the array of the local delegates
+         //and failover indexes
+         
+         ClusteredClientConnectionFactoryDelegate clusteredDel = 
+            new ClusteredClientConnectionFactoryDelegate(id,
+                     locatorURI, serverPeer.getVersion(), clientPing);
+         
+         setFailoverDelegates(clusteredDel, replicants);
+         
+         delegate = clusteredDel;
+      }
+      
       ConnectionFactoryAdvised connFactoryAdvised = new ConnectionFactoryAdvised(endpoint);
-
-      JMSDispatcher.instance.registerTarget(serverObjectID, connFactoryAdvised);
-
-      endpoints.put(serverObjectID, endpoint);
-
+      
       JBossConnectionFactory cf = new JBossConnectionFactory(delegate);
-
+      
       if (jndiBindings != null)
       {
          List jndiNames = jndiBindings.getNames();
@@ -157,35 +145,26 @@
             JNDIUtil.rebind(initialContext, jndiName, cf);
          }
       }
-
-      factories.put(serverObjectID, cf);
-
-      return id;
-   }
-
-
-   public ConnectionFactoryInfo[] getDatasourceInformation()
+      
+      factories.put(uniqueName, cf);
+      
+      endpoints.put(uniqueName, endpoint);
+      
+      JMSDispatcher.instance.registerTarget(new Integer(id), connFactoryAdvised);
+            }
+   
+   public synchronized void unregisterConnectionFactory(String uniqueName, boolean clustered) throws Exception
    {
-      ConnectionFactoryInfo[] info = new ConnectionFactoryInfo[factories.size()];
-      int counter = 0;
-      for (Iterator iter = factories.entrySet().iterator(); iter.hasNext();)
+      ServerConnectionFactoryEndpoint endpoint =
+         (ServerConnectionFactoryEndpoint)endpoints.remove(uniqueName);
+      
+      if (endpoint == null)
       {
-         Map.Entry entry = (Map.Entry) iter.next();
-         String name = (String) entry.getKey();
-         JBossConnectionFactory factory = (JBossConnectionFactory) entry.getValue();
-         ClientConnectionFactoryDelegate delegate = (ClientConnectionFactoryDelegate)factory.getDelegate();
-         String locatorURL = delegate.getServerLocatorURI();
-         info [counter++] = new ConnectionFactoryInfo(name, locatorURL);
+         throw new IllegalArgumentException("Cannot find endpoint with name " + uniqueName);
       }
-      return info;
-   }
-
-   public synchronized void unregisterConnectionFactory(String serverObjectID) throws Exception
-   {
-      ServerConnectionFactoryEndpoint endpoint =
-         (ServerConnectionFactoryEndpoint)endpoints.get(serverObjectID);
-
+      
       JNDIBindings jndiBindings = endpoint.getJNDIBindings();
+      
       if (jndiBindings != null)
       {
          List jndiNames = jndiBindings.getNames();
@@ -196,27 +175,23 @@
             log.debug(jndiName + " unregistered");
          }
       }
-
-      JMSDispatcher.instance.unregisterTarget(serverObjectID);
-
-      endpoints.remove(serverObjectID);
-      factories.remove(serverObjectID);
-   }
-
-   public synchronized javax.jms.ConnectionFactory getConnectionFactory(int connectionFactoryID)
-   {
-      return (javax.jms.ConnectionFactory)factories.get(new Integer(connectionFactoryID));
-   }
-
-   public synchronized javax.jms.ConnectionFactory[] getAllConnectionFactories()
-   {
-      ArrayList list = new ArrayList();
-      for (Iterator iter = factories.values().iterator();iter.hasNext();)
+      
+      ClientConnectionFactoryDelegate delegate =
+         (ClientConnectionFactoryDelegate)factories.remove(uniqueName);
+      
+      if (delegate == null)
       {
-         list.add(iter.next());
+         throw new IllegalArgumentException("Cannot find factory with name " + uniqueName);
       }
-
-      return (javax.jms.ConnectionFactory[])list.toArray(new JBossConnectionFactory[list.size()]);
+      
+      if (clustered)
+      {
+         //Remove from replicants
+         
+         replicator.removeReplicant(CF_PREFIX + uniqueName);         
+      }
+      
+      JMSDispatcher.instance.unregisterTarget(new Integer(endpoint.getID()));
    }
    
    // MessagingComponent implementation -----------------------------
@@ -224,43 +199,167 @@
    public void start() throws Exception
    {
       initialContext = new InitialContext();
+      
+      replicator = serverPeer.getDataReplicator();
+      
+      if (replicator != null)
+      {
+         replicator.registerListener(this);
+      }
+      
       log.debug("started");
    }
-
+   
    public void stop() throws Exception
    {
       initialContext.close();
+      
+      if (replicator != null)
+      {
+         replicator.unregisterListener(this);
+      }
+      
       log.debug("stopped");
    }
-
+   
+   // ReplicationListener interface ----------------------------------
+   
+   public synchronized void onReplicationChange(Serializable key, Map replicants)
+   {
+      try
+      {
+         //The list of connection factories across the cluster has changed -
+         //we need to update the clustered connection factories in JNDI with
+         //new ones with the up to date list
+         
+         //Replication can be used for other stuff (not just connection factories)
+         //so we check the prefix
+         
+         String sKey = (String)key;
+         
+         if (key instanceof String && sKey.startsWith(CF_PREFIX))
+         {
+            String uniqueName = sKey.substring(CF_PREFIX.length());
+            
+            ClusteredClientConnectionFactoryDelegate cf =
+               (ClusteredClientConnectionFactoryDelegate)factories.get(uniqueName);
+            
+            if (cf == null)
+            {
+               throw new IllegalStateException("Cannot find connection factory " + uniqueName + " to update");
+            }
+            
+            setFailoverDelegates(cf, replicants);
+            
+            //Now rebind
+            
+            ServerConnectionFactoryEndpoint endpoint =
+               (ServerConnectionFactoryEndpoint)endpoints.remove(uniqueName);
+            
+            if (endpoint == null)
+            {
+               throw new IllegalStateException("Cannot find endpoint " + uniqueName );
+            }
+            
+            JNDIBindings jndiBindings = endpoint.getJNDIBindings();
+            
+            if (jndiBindings != null)
+            {
+               List jndiNames = jndiBindings.getNames();
+               for(Iterator i = jndiNames.iterator(); i.hasNext(); )
+               {
+                  String jndiName = (String)i.next();
+                  initialContext.rebind(jndiName, cf);
+               }
+            }  
+         } 
+      }
+      catch (NamingException e)
+      {
+         log.error("Failed to rebind connection factory", e);
+      }
+   }
+   
    // Public --------------------------------------------------------
-
+   
    // Package protected ---------------------------------------------
-
+   
    // Protected -----------------------------------------------------
-
+   
    // Private -------------------------------------------------------
-
-   private ClusteredConnectionFactoryDelegate createClusteredConnectionFactoryDelegate(ClusteredPostOffice postOffice)
+   
+   
+   private void setFailoverDelegates(ClusteredClientConnectionFactoryDelegate cf,
+                                     Map replicants)
    {
-      NodeAddressInfo[] addresses = postOffice.getClusterNodes();
-
-      ArrayList delegatesList = new ArrayList();
-
-      for (int i = 0; i < addresses.length; i++)
+      // We need to get the failover indexes too
+      // If delegates[i] is the current delegate, then the failover delegate
+      // is given by delegates[failoverIndexes[i]]
+      
+      int s = replicants.size();
+      
+      ClientConnectionFactoryDelegate[] delegates = new ClientConnectionFactoryDelegate[s];
+      
+      Iterator iter = replicants.entrySet().iterator();
+      
+      int i = 0;
+      
+      int[] nodes = new int[s];
+      
+      int[] failoverNodes = new int[s];
+      
+      while (iter.hasNext())
       {
-         //ConnectionFactoryDelegate delegateArray[] = addresses[i].getConnectionFactoryDelegates();
-         ConnectionFactoryDelegate delegateArray[] = null;
-
-         for (int j = 0; j < delegateArray.length; j++)
+         Map.Entry entry = (Map.Entry)iter.next();
+         
+         int nodeId = ((Integer)entry.getKey()).intValue();
+         
+         ClientConnectionFactoryDelegate del = (ClientConnectionFactoryDelegate)entry.getValue();
+         
+         delegates[i] = del;
+         
+         int failoverNode = replicator.getFailoverNodeForNode(nodeId);
+         
+         nodes[i] = nodeId;
+         
+         failoverNodes[i] = failoverNode; 
+         
+         i++;
+      }
+      
+      //Generate the failover indexes
+      //This could probably be optimised if need be
+      
+      int[] failoverIndexes = new int[s];
+      
+      for (int j = 0; j < s; i++)
+      {
+         int failoverNode = failoverNodes[j];
+         
+         //What index is this node?
+         
+         int failoverIndex = -1;
+         
+         for (int k = 0; k  < s; k++)
          {
-            delegatesList.add(delegateArray[j]);
+            if (nodes[k] == failoverNode)
+            {
+               failoverIndex = k;
+               
+               break;
+            }
          }
+         
+         if (failoverIndex == -1)
+         {
+            throw new IllegalStateException("Failover node is not in list of nodes!");
+         }
+         
+         failoverIndexes[j] = failoverIndex;
       }
-      ClientConnectionFactoryDelegate[] delegateFinal = (ClientConnectionFactoryDelegate[]) delegatesList.toArray(new ClientConnectionFactoryDelegate[delegatesList.size()]);
-
-      return new ClusteredConnectionFactoryDelegate(delegateFinal);
+      
+      cf.setFailoverDelegates(delegates, failoverIndexes);
    }
-
+   
    // Inner classes -------------------------------------------------
 }

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/container/InjectionAspect.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/container/InjectionAspect.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/container/InjectionAspect.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -101,7 +101,7 @@
        
        Byte ver =
           (Byte)mi.getMetaData(MetaDataConstants.JMS,
-                                 MetaDataConstants.VERSION_NUMBER);
+                               MetaDataConstants.VERSION_NUMBER);
        
        if (ver == null)
        {

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -130,7 +130,7 @@
 
          log.debug("created and registered " + endpoint);
 
-         return new ClientConnectionDelegate(connectionID);
+         return new ClientConnectionDelegate(connectionID, serverPeer.getServerPeerID());
       }
       catch (Throwable t)
       {

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -86,8 +86,6 @@
 
    private int id;
 
-   private int nodeId;
-
    private PagingFilteredQueue messageQueue;
    
    private String queueName;
@@ -130,13 +128,12 @@
    protected ServerConsumerEndpoint(int id, PagingFilteredQueue messageQueue, String queueName,
                                     ServerSessionEndpoint sessionEndpoint,
                                     String selector, boolean noLocal, JBossDestination dest,
-                                    int prefetchSize, int nodeId)
+                                    int prefetchSize)
                                     throws InvalidSelectorException
    {
       if (trace) { log.trace("constructing consumer endpoint " + id); }
 
       this.id = id;
-      this.nodeId = nodeId;
       this.messageQueue = messageQueue;
       this.queueName = queueName;
       this.sessionEndpoint = sessionEndpoint;

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -130,31 +130,18 @@
    }
 
    // SessionDelegate implementation --------------------------------
-
-   /*
-    * Separation of concerns.
-    * This code DOES NOT belong in the createConsumerDelegate() method
-    */
+      
    public ConsumerDelegate failOverConsumer(JBossDestination jmsDestination,
                                             String selectorString,
                                             boolean noLocal,  String subscriptionName,
                                             boolean connectionConsumer,
-                                            long oldChannelID, int nodeId) throws JMSException
+                                            long oldChannelID) throws JMSException
    {
+      //TODO we must ensure that the server side failover has completed first before
+      //letting this method run
+      
       try
       {
-
-         // this code needs to be transfered to PostOffices, JGroups fail detection
-         if (jmsDestination.isTopic())
-         {
-            ((ClusteredPostOffice)topicPostOffice).failOver(nodeId);
-         }
-         else
-         if (jmsDestination.isQueue())
-         {
-            ((ClusteredPostOffice)queuePostOffice).failOver(nodeId);
-         }
-
          // fail over channel
          PostOffice postOfficeToUse = null;
          if (jmsDestination.isTopic())
@@ -177,34 +164,34 @@
          {
             throw new IllegalStateException("Can't find failed over channel " + oldChannelID);
          }
-
-          // TODO - Remove this log.info before merging into trunk
-          if (binding.getQueue() instanceof RemoteQueueStub)
-          {
-              log.info("OldChannelId=" + oldChannelID + " while currentChannelId=" + ((RemoteQueueStub)binding.getQueue()).getChannelID());
-          }
-          else
-          {
-             log.info("OldChannelId=" + oldChannelID + " while currentChannelId=" + ((PagingFilteredQueue)binding.getQueue()).getChannelID());
-          }
-
-          int consumerID = connectionEndpoint.getServerPeer().getNextObjectID();
-
-          int prefetchSize = connectionEndpoint.getPrefetchSize();
-
-          ServerConsumerEndpoint ep =
-             new ServerConsumerEndpoint(consumerID, (PagingFilteredQueue)binding.getQueue(), binding.getQueue().getName(),
-                                        this, selectorString, noLocal, jmsDestination, prefetchSize, nodeId);
-
-          JMSDispatcher.instance.registerTarget(new Integer(consumerID), new ConsumerAdvised(ep));
-
-          ClientConsumerDelegate stub = new ClientConsumerDelegate(consumerID, binding.getQueue().getChannelID(), prefetchSize);
-
-          putConsumerEndpoint(consumerID, ep); // caching consumer locally
-
-          connectionEndpoint.getServerPeer().putConsumerEndpoint(consumerID, ep); // cachin consumer in server peer
-
-          return stub;
+         
+         // TODO - Remove this log.info before merging into trunk
+         if (binding.getQueue() instanceof RemoteQueueStub)
+         {
+            log.info("OldChannelId=" + oldChannelID + " while currentChannelId=" + ((RemoteQueueStub)binding.getQueue()).getChannelID());
+         }
+         else
+         {
+            log.info("OldChannelId=" + oldChannelID + " while currentChannelId=" + ((PagingFilteredQueue)binding.getQueue()).getChannelID());
+         }
+         
+         int consumerID = connectionEndpoint.getServerPeer().getNextObjectID();
+         
+         int prefetchSize = connectionEndpoint.getPrefetchSize();
+         
+         ServerConsumerEndpoint ep =
+            new ServerConsumerEndpoint(consumerID, (PagingFilteredQueue)binding.getQueue(), binding.getQueue().getName(),
+                     this, selectorString, noLocal, jmsDestination, prefetchSize);
+         
+         JMSDispatcher.instance.registerTarget(new Integer(consumerID), new ConsumerAdvised(ep));
+         
+         ClientConsumerDelegate stub = new ClientConsumerDelegate(consumerID, binding.getQueue().getChannelID(), prefetchSize);
+         
+         putConsumerEndpoint(consumerID, ep); // caching consumer locally
+         
+         connectionEndpoint.getServerPeer().putConsumerEndpoint(consumerID, ep); // cachin consumer in server peer
+         
+         return stub;
       }
       catch (Throwable t)
       {
@@ -463,7 +450,7 @@
 
          ServerConsumerEndpoint ep =
             new ServerConsumerEndpoint(consumerID, (PagingFilteredQueue)binding.getQueue(), binding.getQueue().getName(),
-                                       this, selectorString, noLocal, jmsDestination, prefetchSize, nodeId);
+                                       this, selectorString, noLocal, jmsDestination, prefetchSize);
           
          JMSDispatcher.instance.registerTarget(new Integer(consumerID), new ConsumerAdvised(ep));
                      

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/SessionEndpoint.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/SessionEndpoint.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/SessionEndpoint.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -46,15 +46,11 @@
  */
 public interface SessionEndpoint extends Closeable
 {
-
-   /** I'm using basically the same siganture as @link{createConsumerDelegate) as some of the aspects like StateCreation
-    *  will need these parameters on the right order. We would need to create another aspect method and I prefered reuse the
-    *  same aspect for this similar feature. */
    ConsumerDelegate failOverConsumer(JBossDestination jmsDestination,
                                      String selectorString,
                                      boolean noLocal,  String subscriptionName,
                                      boolean connectionConsumer,
-                                     long oldchannelID, int nodeId) throws JMSException;
+                                     long oldchannelID) throws JMSException;
 
    ConsumerDelegate createConsumerDelegate(JBossDestination destination, String selector,
                                            boolean noLocal, String subscriptionName,

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -95,11 +95,11 @@
                                             String selectorString,
                                             boolean noLocal,  String subscriptionName,
                                             boolean connectionConsumer,
-                                            long oldChannelID, int nodeId) throws JMSException
+                                            long oldChannelID) throws JMSException
    {
       return endpoint.failOverConsumer(jmsDestination, selectorString, noLocal,
                                        subscriptionName, connectionConsumer,
-                                       oldChannelID, nodeId);
+                                       oldChannelID);
    }
 
    public BrowserDelegate createBrowserDelegate(JBossDestination queue, String messageSelector)

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/remoting/MetaDataConstants.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/remoting/MetaDataConstants.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/jms/server/remoting/MetaDataConstants.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -46,4 +46,12 @@
    public static final String VERSION_NUMBER = "VERSION_NUMBER";
    
    public static final String JMS_CLIENT_VM_ID = "JMS_CLIENT_VM_ID";
+   
+   public static final String CF_DELEGATES = "CF_DELEGATES";
+   
+   public static final String SERVER_ID = "SERVER_ID";
+   
+   public static final String REMOTING_CONNECTION = "REMOTING_CONNECTION";
+   
+   public static final String CF_FAILOVER_INDEXES = "CF_FAIL_IND";
 }

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -23,17 +23,19 @@
 
 import javax.management.ObjectName;
 import javax.transaction.TransactionManager;
-import org.jboss.jms.client.JBossConnectionFactory;
+
 import org.jboss.jms.selector.SelectorFactory;
 import org.jboss.jms.server.QueuedExecutorPool;
 import org.jboss.jms.server.ServerPeer;
 import org.jboss.jms.util.ExceptionUtil;
 import org.jboss.messaging.core.FilterFactory;
+import org.jboss.messaging.core.plugin.contract.FailoverMapper;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
 import org.jboss.messaging.core.plugin.contract.MessagingComponent;
 import org.jboss.messaging.core.plugin.contract.PersistenceManager;
 import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
 import org.jboss.messaging.core.tx.TransactionRepository;
 import org.w3c.dom.Element;
@@ -199,16 +201,6 @@
    {
       this.messagePullPolicy = messagePullPolicy;
    }
-
-   public String listBindings()
-   {
-       return postOffice.printBindingInformation();
-   }
-
-   public void failOver(int failedNodeId) throws Exception
-   {
-       postOffice.failOver(failedNodeId);
-   }
    
    // ServiceMBeanSupport overrides ---------------------------------
    
@@ -226,10 +218,7 @@
          TransactionManager tm = getTransactionManagerReference();
                            
          ServerPeer serverPeer = (ServerPeer)server.getAttribute(serverPeerObjectName, "Instance");
-
-         // Getting connectionDelegates information
-         JBossConnectionFactory[] factories = (JBossConnectionFactory[]) serverPeer.getConnectionFactoryManager().getAllConnectionFactories();
-
+         
          MessageStore ms = serverPeer.getMessageStore();
          
          TransactionRepository tr = serverPeer.getTxRepository();
@@ -249,7 +238,9 @@
          ClusterRouterFactory rf = (ClusterRouterFactory)clazz.newInstance();
          
          FilterFactory ff = new SelectorFactory();
-
+         
+         FailoverMapper mapper = new DefaultFailoverMapper();
+            
          postOffice =  new DefaultClusteredPostOffice(ds, tm, sqlProperties, createTablesOnStartup,
                                                nodeId, officeName, ms,
                                                pm, tr, ff, pool, 
@@ -257,6 +248,7 @@
                                                syncChannelConfig, asyncChannelConfig,
                                                stateTimeout, castTimeout,
                                                pullPolicy, rf,
+                                               mapper,
                                                statsSendPeriod);
          
          postOffice.start();

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -22,11 +22,9 @@
 package org.jboss.messaging.core.plugin.contract;
 
 import java.util.Collection;
-import org.jboss.jms.server.ConnectionFactoryManager;
-import org.jboss.jms.server.connectionfactory.JNDIBindings;
+
 import org.jboss.messaging.core.plugin.postoffice.Binding;
 import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.messaging.core.plugin.postoffice.cluster.NodeAddressInfo;
 
 /**
  * 
@@ -41,16 +39,7 @@
  */
 public interface ClusteredPostOffice extends PostOffice
 {
-
    /**
-    *   Sets this ClusteredPostOffice as responsible for rebind the ClusteredConnectionFactories when the
-    * membership changes.
-    * @param jndiMapper
-    * @param clusteredConnectionJndiBindings
-    */
-   public void setClusteredConnectionInformation(ConnectionFactoryManager jndiMapper,
-                                                 JNDIBindings clusteredConnectionJndiBindings);
-   /**
     * Bind a queue to the post office under a specific condition
     * such that it is available across the cluster
     * @param condition The condition to be used when routing references
@@ -70,9 +59,5 @@
 
    Collection listAllBindingsForCondition(String condition) throws Exception;
 
-   public void failOver(int nodeId) throws Exception;
-
    Binding getBindingforChannelId(long channelId) throws Exception;
-
-   NodeAddressInfo[] getClusterNodes();
 }

Added: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/FailoverMapper.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/FailoverMapper.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/FailoverMapper.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.contract;
+
+import java.util.List;
+
+/**
+ * A FailoverMapper
+ * 
+ * Determines the mapping between a set of nodes and their failover nodes
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface FailoverMapper
+{
+   List generateMapping(List nodes);
+      
+}

Added: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/ReplicationListener.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/ReplicationListener.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/ReplicationListener.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.contract;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * A ReplicationListener
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface ReplicationListener
+{
+   void onReplicationChange(Serializable key, Map replicants);
+}

Added: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/contract/Replicator.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.contract;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * A Replicator
+ * 
+ * This is used for replicating arbitrary data across a cluster.
+ * 
+ * Data is structured as follows:
+ * 
+ * There is an arbitrary key to identify the data, e.g. the connection factory name
+ * Then, for that key, there is an entry for each node id.
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Replicator
+{
+   void putReplicant(Serializable key, Serializable replicant) throws Exception;
+   
+   boolean removeReplicant(Serializable key) throws Exception;
+   
+   Map getReplicants(Serializable key) throws Exception;
+   
+   void registerListener(ReplicationListener listener);
+   
+   void unregisterListener(ReplicationListener listener);
+   
+   /**
+    * Gets the current failover node id for the specified node id
+    * @param nodeId The node to get the failover node id for
+    * @return the failover node id
+    */
+   int getFailoverNodeForNode(int nodeId);   
+}

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRequest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRequest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRequest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -78,11 +78,6 @@
             request = new QueueStatsRequest();
             break;
          }
-         case SendNodeIdRequest.TYPE:
-         {
-            request = new SendNodeIdRequest();
-            break;
-         }
          case SendTransactionRequest.TYPE:
          {
             request = new SendTransactionRequest();
@@ -99,8 +94,20 @@
             break;
          }
          case LeaveClusterRequest.TYPE:
+         {
             request = new LeaveClusterRequest();
             break;
+         }
+         case PutReplicantRequest.TYPE:
+         {
+            request = new PutReplicantRequest();
+            break;
+         }
+         case RemoveReplicantRequest.TYPE:
+         {
+            request = new RemoveReplicantRequest();
+            break;
+         }
          default:
          {
             throw new IllegalArgumentException("Invalid type: " + type);

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -21,26 +21,29 @@
  */
 package org.jboss.messaging.core.plugin.postoffice.cluster;
 
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.PrintWriter;
+import java.io.Serializable;
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
+
 import javax.sql.DataSource;
 import javax.transaction.TransactionManager;
-import org.jboss.jms.server.ConnectionFactoryManager;
+
 import org.jboss.jms.server.QueuedExecutorPool;
-import org.jboss.jms.server.connectionfactory.JNDIBindings;
 import org.jboss.logging.Logger;
 import org.jboss.messaging.core.Delivery;
 import org.jboss.messaging.core.Filter;
@@ -48,8 +51,11 @@
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.Queue;
 import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
+import org.jboss.messaging.core.plugin.contract.FailoverMapper;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
 import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.plugin.contract.ReplicationListener;
+import org.jboss.messaging.core.plugin.contract.Replicator;
 import org.jboss.messaging.core.plugin.postoffice.Binding;
 import org.jboss.messaging.core.plugin.postoffice.DefaultBinding;
 import org.jboss.messaging.core.plugin.postoffice.DefaultPostOffice;
@@ -69,6 +75,8 @@
 import org.jgroups.blocks.RequestHandler;
 import org.w3c.dom.Element;
 
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
 /**
  * 
  * A DefaultClusteredPostOffice
@@ -79,13 +87,19 @@
  * $Id$
  *
  */
-public class DefaultClusteredPostOffice extends DefaultPostOffice implements ClusteredPostOffice, PostOfficeInternal
+public class DefaultClusteredPostOffice extends DefaultPostOffice
+   implements ClusteredPostOffice, PostOfficeInternal, Replicator
 {
    private static final Logger log = Logger.getLogger(DefaultClusteredPostOffice.class);
    
+   // Key for looking up node id -> address info mapping from replicated data
+   private static final String ADDRESS_INFO_KEY = "address_info";
+   
    //Used for failure testing
    private boolean failBeforeCommit;
+   
    private boolean failAfterCommit;
+   
    private boolean failHandleResult;
      
    private boolean trace = log.isTraceEnabled();
@@ -112,11 +126,15 @@
    
    private View currentView;
    
-   //Map < Address, NodeAddressInfo>
-   private Map nodeIdAddressesMap;
+   private Map replicatedData;   
    
+   private Set replicationListeners;
+      
    private Map holdingArea;
    
+   //Map < node, failover node>
+   private Map failoverMap;
+   
    private Element syncChannelConfigE;
    
    private Element asyncChannelConfigE;
@@ -132,11 +150,9 @@
    private MessagePullPolicy messagePullPolicy;
    
    private ClusterRouterFactory routerFactory;
+   
+   private FailoverMapper failoverMapper;
 
-   private ConnectionFactoryManager jndiMapper;
-
-   private JNDIBindings clusteredConnectionJndiBindings; 
-
    private Map routerMap;
 
    /** List of failed over bindings.
@@ -146,7 +162,7 @@
    private StatsSender statsSender;
 
    private boolean started;
-      
+     
    public DefaultClusteredPostOffice()
    {        
       init();
@@ -154,9 +170,13 @@
    
    private void init()
    {
-      this.nodeIdAddressesMap = new HashMap();
+      holdingArea = new HashMap();
       
-      this.holdingArea = new HashMap();
+      replicatedData = new HashMap();      
+      
+      replicationListeners = new HashSet();
+      
+      failoverMap = new LinkedHashMap();
    }
    
    /*
@@ -175,11 +195,12 @@
             long stateTimeout, long castTimeout,
             MessagePullPolicy redistributionPolicy,
             ClusterRouterFactory rf,
+            FailoverMapper failoverMapper,
             long statsSendPeriod) throws Exception
    {            
       this(ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms,
            pm, tr, filterFactory, pool, groupName, stateTimeout, castTimeout, redistributionPolicy,
-           rf, statsSendPeriod);
+           rf, failoverMapper, statsSendPeriod);
       
       this.syncChannelConfigE = syncChannelConfig;      
       this.asyncChannelConfigE = asyncChannelConfig;
@@ -201,11 +222,12 @@
                               long stateTimeout, long castTimeout,
                               MessagePullPolicy redistributionPolicy,                      
                               ClusterRouterFactory rf,
+                              FailoverMapper failoverMapper,
                               long statsSendPeriod) throws Exception
    {            
       this(ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms,
            pm, tr, filterFactory, pool, groupName, stateTimeout, castTimeout, redistributionPolicy,
-           rf, statsSendPeriod);
+           rf, failoverMapper, statsSendPeriod);
 
       this.syncChannelConfigS = syncChannelConfig;      
       this.asyncChannelConfigS = asyncChannelConfig;     
@@ -222,6 +244,7 @@
                                long stateTimeout, long castTimeout,                             
                                MessagePullPolicy redistributionPolicy,                               
                                ClusterRouterFactory rf,
+                               FailoverMapper failoverMapper,
                                long statsSendPeriod)
    {
       super (ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms, pm, tr, filterFactory,
@@ -239,6 +262,8 @@
       
       this.routerFactory = rf;
       
+      this.failoverMapper = failoverMapper;
+      
       routerMap = new HashMap();
 
       failedBindings = new LinkedHashMap();
@@ -296,12 +321,10 @@
       
       Address asyncAddress = asyncChannel.getLocalAddress();
 
-      NodeAddressInfo info = new NodeAddressInfo(nodeId, syncAddress, asyncAddress);
+      PostOfficeAddressInfo info = new PostOfficeAddressInfo(syncAddress, asyncAddress);
       
-      handleAddressNodeMapping(info, nodeId);
+      putReplicant(ADDRESS_INFO_KEY, info);
       
-      syncSendRequest(new SendNodeIdRequest(info, nodeId));           
-      
       statsSender.start();
       
       started = true;   
@@ -333,13 +356,6 @@
    
    // PostOffice implementation ---------------------------------------        
 
-   public void setClusteredConnectionInformation(ConnectionFactoryManager jndiMapper,
-                                                 JNDIBindings clusteredConnectionJndiBindings)
-   {
-      this.jndiMapper = jndiMapper;
-      this.clusteredConnectionJndiBindings=clusteredConnectionJndiBindings;
-   }
-
    public Binding bindClusteredQueue(String condition, LocalClusteredQueue queue) throws Exception
    {
       if (trace)
@@ -372,20 +388,20 @@
    }
 
    public Binding unbindClusteredQueue(String queueName) throws Throwable
-  {
-     if (trace)
-     {
-        log.trace(this.nodeId + " unbind clustered queue: " + queueName);
-     }
-
-     Binding binding = (Binding)super.unbindQueue(queueName);
-
-     UnbindRequest request = new UnbindRequest(this.nodeId, queueName);
-
-     syncSendRequest(request);
-
-     return binding;
-  }
+   {
+      if (trace)
+      {
+         log.trace(this.nodeId + " unbind clustered queue: " + queueName);
+      }
+      
+      Binding binding = (Binding)super.unbindQueue(queueName);
+      
+      UnbindRequest request = new UnbindRequest(this.nodeId, queueName);
+      
+      syncSendRequest(request);
+      
+      return binding;
+   }
    
    public boolean route(MessageReference ref, String condition, Transaction tx) throws Exception
    {
@@ -569,16 +585,143 @@
    {
       return listBindingsForConditionInternal(condition, false);
    }
+   
+   public int getFailoverNodeForNode(int nodeId)
+   {
+      Integer failoverNode = (Integer)failoverMap.get(new Integer(nodeId));
+      
+      if (failoverNode == null)
+      {
+         throw new IllegalArgumentException("Cannot find failover node for node " + nodeId);
+      }
+      
+      return failoverNode.intValue();
+   }
 
-   public NodeAddressInfo[] getClusterNodes()
+   // Replicator implementation --------------------------------------------------------------------------
+   
+   public Map getReplicants(Serializable key) throws Exception
    {
-      ArrayList nodesList = new ArrayList();
-      nodesList.addAll(nodeIdAddressesMap.values());
-      return (NodeAddressInfo[])nodesList.toArray(new NodeAddressInfo[nodesList.size()]);
+      lock.readLock().acquire();
+      
+      try
+      {
+         Map m = (Map)replicatedData.get(key);
+         
+         return m == null ? null : Collections.unmodifiableMap(m);
+      }
+      finally
+      {
+         lock.readLock().release();
+      }
    }
 
+   public void putReplicant(Serializable key, Serializable replicant) throws Exception
+   {
+      putReplicantFromCluster(this.nodeId, key, replicant);
+      
+      PutReplicantRequest request = new PutReplicantRequest(this.nodeId, key, replicant);
+      
+      syncSendRequest(request);
+   }
+   
+   public boolean removeReplicant(Serializable key) throws Exception
+   {
+      if (removeReplicantFromCluster(this.nodeId, key))
+      {      
+         RemoveReplicantRequest request = new RemoveReplicantRequest(this.nodeId, key);
+         
+         syncSendRequest(request);
+         
+         return true;
+      }
+      else
+      {
+         return false;
+      }
+   }
+   
+   public void registerListener(ReplicationListener listener)
+   {
+      if (replicationListeners.contains(listener))
+      {
+         throw new IllegalArgumentException("Listener " + listener + " is already registered");
+      }
+      replicationListeners.add(listener);
+   }
+   
+   public void unregisterListener(ReplicationListener listener)
+   {
+      boolean removed = replicationListeners.remove(listener);
+      
+      if (!removed)
+      {
+         throw new IllegalArgumentException("Cannot find listener " + listener + " to remove");
+      }
+   }
+    
    // PostOfficeInternal implementation ------------------------------------------------------------------
    
+   public void putReplicantFromCluster(int nodeId, Serializable key, Serializable replicant) throws Exception
+   {
+      lock.writeLock().acquire();
+      
+      try
+      {         
+         Map m = (Map)replicatedData.get(key);
+         
+         if (m == null)
+         {
+            m = new HashMap();
+            
+            replicatedData.put(key, m);
+         }
+         
+         m.put(new Integer(nodeId), replicant); 
+         
+         notifyListeners(key, m);         
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+   
+   public boolean removeReplicantFromCluster(int nodeId, Serializable key) throws Exception
+   {
+      lock.writeLock().acquire();
+      
+      try
+      {
+         Map m = (Map)replicatedData.get(key);
+         
+         if (m == null)
+         {
+            return false;
+         }
+         
+         Object obj = m.remove(new Integer(nodeId));
+         
+         if (obj == null)
+         {
+            return false;
+         }
+         
+         if (m.isEmpty())
+         {
+            replicatedData.remove(key);
+         }
+         
+         notifyListeners(key, m);         
+         
+         return true;
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+     
    /*
     * Called when another node adds a binding
     */
@@ -597,9 +740,9 @@
       {                     
          //Sanity
 
-         if (!nodeIdAddressesMap.containsKey(new Integer(nodeId)))
+         if (!knowAboutNodeId(nodeId))
          {
-            throw new IllegalStateException("Cannot find address for node: " + nodeId);
+            throw new IllegalStateException("Don't know about node id: " + nodeId);
          }
          
          // We currently only allow one binding per name per node
@@ -642,9 +785,9 @@
       try
       {         
          // Sanity
-         if (!nodeIdAddressesMap.containsKey(new Integer(nodeId)))
+         if (!knowAboutNodeId(nodeId))
          {
-            throw new IllegalStateException("Cannot find address for node: " + nodeId);
+            throw new IllegalStateException("Don't know about node id: " + nodeId);
          }
          
          removeBinding(nodeId, queueName);         
@@ -655,40 +798,6 @@
       }
    }
    
-   public void handleAddressNodeMapping(NodeAddressInfo info, int nodeId) throws Exception
-   {
-      lock.writeLock().acquire();
-
-      // TODO: Remove this info before merging into trunk
-      log.info("Received new NodeAddressInfo->" + info);
-      
-      if (trace)
-      {
-         log.trace("Adding NodeAddressInfo=" + info.toString());
-      }
-      
-      try
-      { 
-         nodeIdAddressesMap.put(new Integer(nodeId), info);
-
-         try
-         {
-            registerDatasources();
-         }
-         catch (Throwable e)
-         {
-            log.error("Caught Exception in MembershipListener", e);
-            IllegalStateException e2 = new IllegalStateException(e.getMessage());
-            e2.initCause(e);
-            throw e2;
-         }
-      }
-      finally                                                                  
-      {
-         lock.writeLock().release();
-      }
-   }
-   
    public void routeFromCluster(org.jboss.messaging.core.Message message, String routingKey,
                                 Map queueNameNodeIdMap) throws Exception
    {
@@ -1118,7 +1227,78 @@
       }      
    }
    
+   /*
+    * Removes all non durable binding data, and any local replicant data for the specified
+    * node
+    */
+   public void removeDataForNode(int parameterNodeId) throws Exception
+   {
+      log.info("Node " + parameterNodeId + " requested to leave cluster");
+      
+      lock.writeLock().acquire();
+
+      try
+      {          
+         Map nameMap = (Map)nameMaps.get(new Integer(parameterNodeId));
+
+         if (nameMap != null)
+         {
+            List toRemove = new ArrayList();
+            
+            Iterator iter = nameMap.values().iterator();
+            
+            while (iter.hasNext())
+            {
+               Binding binding = (Binding)iter.next();
+               
+               if (!binding.getQueue().isRecoverable())
+               {
+                  //We only remove the non durable bindings - we still need to be able to handle
+                  //messages for a durable subscription "owned" by a node that is not active any more!
+                  toRemove.add(binding);
+               }
+            }
+            
+            iter = toRemove.iterator();
+            
+            while (iter.hasNext())
+            {
+               Binding binding = (Binding)iter.next();
+               
+               removeBinding(parameterNodeId, binding.getQueue().getName());
+            }
+         }
+         
+         //We need to remove any replicant data for the node
+         //this includes the node-address info
+         Iterator iter = replicatedData.entrySet().iterator();
+         
+         while (iter.hasNext())
+         {
+            Map.Entry entry = (Map.Entry)iter.next();
+            
+            String key = (String)entry.getKey();
+            
+            Map replicants = (Map)entry.getValue();
+            
+            replicants.remove(new Integer(parameterNodeId));
+            
+            if (replicants.isEmpty())
+            {
+               iter.remove();
+            }     
+            
+            //Need to trigger listeners
+            notifyListeners(key, replicants);
+         }                  
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
    
+   
    public int getNodeId()
    {
       return nodeId;
@@ -1126,7 +1306,20 @@
                         
    // Public ------------------------------------------------------------------------------------------
       
-   //Used for testing only
+   //MUST ONLY be used for testing
+   public int getNumberOfNodesInCluster()
+   {
+      if (currentView != null)
+      {
+         return currentView.size();
+      }
+      else
+      {
+         return 0;
+      }
+   }
+   
+   //MUST ONLY be used for testing
    public void setFail(boolean beforeCommit, boolean afterCommit, boolean handleResult)
    {
       this.failBeforeCommit = beforeCommit;
@@ -1134,39 +1327,69 @@
       this.failHandleResult = handleResult;
    }
    
-   //Used for testing only
+   //MUST ONLY be used for testing
    public Collection getHoldingTransactions()
    {
       return holdingArea.values();
    }
 
-
-   public void failOver(int nodeId) throws Exception
+   /**
+    * This method fails over all the queues from node <nodeId> onto this node
+    * It is triggered when a JGroups view change occurs due to a member leaving and 
+    * it's determined the member didn't leave cleanly
+    * 
+    * @param nodeId
+    * @throws Exception
+    */
+   private void failOver(int nodeId) throws Exception
    {
       // todo - remove this log.info before merging into trunk
       log.info("Preparing failover against node " + nodeId);
+      
       //Need to lock
       lock.writeLock().acquire();
 
       try
       {
          log.info("Preparing failover against node " + nodeId);
+         
+         //Get the map of queues for the failed node
+         
          Map subMaps = (Map)nameMaps.get(new Integer(nodeId));
          if (subMaps==null || subMaps.size()==0)
          {
             log.warn("Couldn't find any binding to failOver from serverId=" +nodeId);
             return;
          }
+                  
+         //Compile a list of the queue names to remove
+         //Note that any non durable bindings will already have been removed (in removeDataForNode()) when the
+         //node leave was detected, so if there are any non durable bindings left here then
+         //this is an error
+         
+         //We iterate through twice to avoid ConcurrentModificationException
          ArrayList namesToRemove = new ArrayList();
-         for (Iterator iterNames = subMaps.entrySet().iterator();iterNames.hasNext();)
+         for (Iterator iterNames = subMaps.entrySet().iterator(); iterNames.hasNext();)
          {
             Map.Entry entry = (Map.Entry)iterNames.next();
+            
             Binding binding = (Binding )entry.getValue();
+            
+            //Sanity check
+            if (!binding.getQueue().isRecoverable())
+            {
+               throw new IllegalStateException("Find non recoverable queue in map, these should have been removed!");
+            }
+            
+            //Sanity check
             if (!binding.getQueue().isClustered())
             {
                throw new IllegalStateException("Queue is not clustered!: " + binding.getQueue().getName());
             }
+            
             ClusteredQueue queue = (ClusteredQueue) binding.getQueue();
+            
+            //Sanity check
             if (queue.isLocal())
             {
                throw new IllegalStateException("Queue is local!: " + binding.getQueue().getName());
@@ -1174,39 +1397,69 @@
             namesToRemove.add(entry);
          }
 
-         for (Iterator iterNames = namesToRemove.iterator();iterNames.hasNext();)
+         for (Iterator iterNames = namesToRemove.iterator(); iterNames.hasNext();)
          {
             Map.Entry entry = (Map.Entry)iterNames.next();
+                        
             Binding binding = (Binding)entry.getValue();
+            
             RemoteQueueStub stub = (RemoteQueueStub)binding.getQueue();
-            this.removeBinding(nodeId,(String)entry.getKey());
+            
+            String queueName = (String)entry.getKey();
+                        
+            //First the binding is removed from the in memory condition and name maps
+            this.removeBinding(nodeId, queueName);
 
-            this.deleteBinding(nodeId,(String)entry.getKey());
+            //Then deleted from the database
+            this.deleteBinding(nodeId, queueName);
 
-            UnbindRequest unbindRequest = new UnbindRequest(nodeId, stub.getName());
+            //Then an unbind request is sent - this cause other nodes to also remove it from the in memory
+            //condition and name maps
+            UnbindRequest unbindRequest = new UnbindRequest(nodeId, queueName);
+            
             syncSendRequest(unbindRequest);
 
-            // A failed over queue will have the flag failover set only if there isn't another local queue with the same name
-            // In case this node doesn't have that queue, we will simply assume the queue as nothing else had happened.
-            boolean failed = this.internalGetBindingForQueueName(stub.getName()) != null;
+            //If there is already a queue registered with the same name, then we set a flag "failed" on the
+            //binding and then the queue will go into a special list of failed bindings
+            //otherwise we treat at as a normal queue
+            //This is because we cannot deal with more than one queue with the same name
+            //Any new consumers will always only connect to queues in the main name map
+            //This may mean that queues in the failed map have messages stranded in them if consumers
+            //disconnect (since no more can reconnect)
+            //However we message redistribution activated other queues will be able to consume from them.
+            //TODO allow message redistribution for queues in the failed list
+            boolean failed = this.internalGetBindingForQueueName(queueName) != null;
 
             if (!failed)
             {
-               log.info("The current node didn't have a queue " + stub.getName() + " so it's assuming the queue as a regular queue");
+               log.info("The current node didn't have a queue " + queueName + " so it's assuming the queue as a regular queue");
             }
-
+           
+            //Create a new binding
             Binding newBinding = this.createBinding(this.nodeId, binding.getCondition(),
-               stub.getName(), stub.getChannelID(),
-               stub.getFilter(), stub.isRecoverable(), failed);
+                                                    stub.getName(), stub.getChannelID(),
+                                                    stub.getFilter(), stub.isRecoverable(), failed);
 
+            //Insert it into the database
             insertBinding(newBinding);
 
             LocalClusteredQueue clusteredQueue = (LocalClusteredQueue )newBinding.getQueue();
+            
             clusteredQueue.deactivate();
             clusteredQueue.load();
             clusteredQueue.activate();
+            
+            //Add the new binding in memory
             addBinding(newBinding);
+            
+            //Send a bind request so other nodes add it too
             sendBindRequest(binding.getCondition(), clusteredQueue,newBinding);
+            
+            //FIXME there is a problem in the above code.
+            //If the server crashes between deleting the binding from the database
+            //and creating the new binding in the database, then the binding will be completely
+            //lost from the database when the server is resurrected.
+            //To remedy, both db operations need to be done in the same JBDC tx
          }
       }
       finally
@@ -1221,6 +1474,8 @@
 
       try
       {
+         //First look in the failed map
+         //Failed bindings are stored in the failed map by channel id
          Map channelMap = (Map)failedBindings.get(new Integer(nodeId));
          Binding binding = null;
          if (channelMap != null)
@@ -1230,6 +1485,7 @@
 
          if (binding == null)
          {
+            //Not found in the failed map - look in the name map
             Map nameMap = (Map)nameMaps.get(new Integer(nodeId));
 
             if (nameMap != null)
@@ -1258,8 +1514,6 @@
       }
    }
 
-
-
    public String printBindingInformation()
    {
       StringWriter buffer = new StringWriter();
@@ -1332,17 +1586,17 @@
 
       out.println("</table>");
 
-      out.println("Clustered Information");
+//      out.println("Clustered Information");
+//
+//      NodeAddressInfo info[] = getClusterNodes();
+//
+//      out.println("<table border=1><tr><td>Node</td><td>AsyncChannel</td><td>SyncChannel</td></tr>");
+//      for (int i = 0; i < info.length; i++)
+//      {
+//         out.println("<tr><td>" + info[i].getNodeId() + "</td><td>" + info[i].getAsyncChannelAddress() + "</td><td>" + info[i].getSyncChannelAddress() + "</td>");
+//      }
+//      out.println("</table>");
 
-      NodeAddressInfo info[] = getClusterNodes();
-
-      out.println("<table border=1><tr><td>Node</td><td>AsyncChannel</td><td>SyncChannel</td></tr>");
-      for (int i = 0; i < info.length; i++)
-      {
-         out.println("<tr><td>" + info[i].getNodeId() + "</td><td>" + info[i].getAsyncChannelAddress() + "</td><td>" + info[i].getSyncChannelAddress() + "</td>");
-      }
-      out.println("</table>");
-
       return buffer.toString();
    }
 
@@ -1508,6 +1762,18 @@
 
     // Private ------------------------------------------------------------------------------------------
 
+    private void notifyListeners(Serializable key, Map replicants)
+    {
+       Iterator iter = replicationListeners.iterator();
+       
+       while (iter.hasNext())
+       {
+          ReplicationListener listener = (ReplicationListener)iter.next();
+          
+          listener.onReplicationChange(key, replicants);
+       }
+    } 
+    
    /*
     * Multicast a sync request
     */
@@ -1527,19 +1793,27 @@
    }
    
 
+   //TODO - this is a bit tortuous - needs optimising
    private Integer getNodeIdForSyncAddress(Address address) throws Exception
    {
       lock.readLock().acquire();
       try
       { 
-         Iterator iter = nodeIdAddressesMap.entrySet().iterator();
+         Map map = this.getReplicants(ADDRESS_INFO_KEY);
          
+         if (map == null)
+         {
+            throw new IllegalStateException("Cannot find node id -> address mapping");
+         }
+         
+         Iterator iter = map.entrySet().iterator();
+         
          Integer nodeId = null;
          while (iter.hasNext())
          {
             Map.Entry entry = (Map.Entry)iter.next();
             
-            NodeAddressInfo info = (NodeAddressInfo)entry.getValue();
+            PostOfficeAddressInfo info = (PostOfficeAddressInfo)entry.getValue();
             
             if (info.getSyncChannelAddress().equals(address))
             {
@@ -1553,54 +1827,33 @@
          lock.readLock().release();
       }
    }
-
-
-   public void removeBindingsForAddress(int parameterNodeId) throws Exception
+   
+   private boolean knowAboutNodeId(int nodeId)
    {
-      log.info("Node " + parameterNodeId + " requested to leave cluster");
-      Integer nodeId = new Integer(parameterNodeId);
-      lock.writeLock().acquire();
-
-      try
-      {          
-         Map nameMap = (Map)nameMaps.get(nodeId);
-
-         if (nameMap != null)
-         {
-            List toRemove = new ArrayList();
-            
-            Iterator iter = nameMap.values().iterator();
-            
-            while (iter.hasNext())
-            {
-               Binding binding = (Binding)iter.next();
-               
-               if (!binding.getQueue().isRecoverable())
-               {
-                  //We only remove the non durable bindings - we still need to be able to handle
-                  //messages for a durable subscription "owned" by a node that is not active any more!
-                  toRemove.add(binding);
-               }
-            }
-            
-            iter = toRemove.iterator();
-            
-            while (iter.hasNext())
-            {
-               Binding binding = (Binding)iter.next();
-               
-               removeBinding(nodeId.intValue(), binding.getQueue().getName());
-            }
-         }
-         
-         //Remove the address mapping
-         nodeIdAddressesMap.remove(nodeId);
+      //The nodeid->Address info mapping is stored in the replicated data
+      
+      Map nodeIdAddressMapping = (Map)replicatedData.get(ADDRESS_INFO_KEY);
+      
+      if (nodeIdAddressMapping == null)
+      {
+         return false;
       }
-      finally
+      else
       {
-         lock.writeLock().release();
+         Object obj = nodeIdAddressMapping.get(new Integer(nodeId));
+         
+         return obj != null;
       }
    }
+
+   /**
+    * Is the current node the failover node for node <nodeId>?
+    * @param nodeId
+    */
+   private boolean isFailoverNodeForNode(int nodeId)
+   {
+      return this.nodeId == getFailoverNodeForNode(nodeId);
+   }
       
    private byte[] getStateAsBytes() throws Exception
    {
@@ -1630,7 +1883,7 @@
          }
       }
       
-      SharedState state = new SharedState(bindings, nodeIdAddressesMap);
+      SharedState state = new SharedState(bindings, replicatedData);
       
       byte[] bytes = StreamUtils.toBytes(state); 
            
@@ -1645,7 +1898,7 @@
       
       StreamUtils.fromBytes(state, bytes);
       
-      if (trace) { log.trace(this.nodeId + " received " + state.getBindings().size() + " bindings and map " + state.getNodeIdAddressMap()); }
+      if (trace) { log.trace(this.nodeId + " received " + state.getBindings().size() + " bindings and map " + state.getReplicatedData()); }
       
       nameMaps.clear();
       
@@ -1674,9 +1927,25 @@
          addBinding(binding);         
       }
       
-      this.nodeIdAddressesMap.clear();
+      //Copy the map
+      this.replicatedData.clear();
       
-      this.nodeIdAddressesMap.putAll(state.getNodeIdAddressMap());
+      iter = state.getReplicatedData().entrySet().iterator();
+      
+      while (iter.hasNext())
+      {
+         Map.Entry entry = (Map.Entry)iter.next();
+         
+         Serializable key = (Serializable)entry.getKey();
+         
+         Map replicants = (Map)entry.getValue();
+         
+         Map m = new HashMap();
+         
+         m.putAll(replicants);
+         
+         replicatedData.put(key, m);
+      }
    }
    
 
@@ -1712,8 +1981,15 @@
 
       try
       {
-         NodeAddressInfo info = (NodeAddressInfo)nodeIdAddressesMap.get(new Integer(nodeId));
+         Map map = this.getReplicants(ADDRESS_INFO_KEY);
          
+         if (map == null)
+         {
+            throw new IllegalStateException("Cannot find address mapping");
+         }
+         
+         PostOfficeAddressInfo info = (PostOfficeAddressInfo)map.get(new Integer(nodeId));
+         
          if (info != null)
          {
             if (sync)
@@ -1736,6 +2012,53 @@
       }
    }
    
+   /*
+    * Given a JGroups view, generate a map of node to failover node
+    * The mapping is determined by a pluggable policy
+    */
+   private void generateFailoverMap(View view) throws Exception
+   {
+      List nodes = new ArrayList();
+      
+      Iterator iter = view.getMembers().iterator();
+      
+      while (iter.hasNext())
+      {
+         Address address = (Address)iter.next();
+         
+         //Convert to node id
+         //TODO this should be optimised - currently the implementation of the lookup
+         //is a bit tortuous
+         
+         Integer n = this.getNodeIdForSyncAddress(address);
+         
+         if (n == null)
+         {
+            throw new IllegalStateException("Cannot find node id for address: " + address);
+         }
+         
+         nodes.add(n);                  
+      }
+            
+      List failoverNodes = failoverMapper.generateMapping(nodes);
+      
+      //Now put this in the map of node -> failover node
+      
+      failoverMap.clear();
+      
+      iter = nodes.iterator();
+      Iterator iter2 = failoverNodes.iterator();
+      
+      while (iter.hasNext())
+      {
+         Integer node = (Integer)iter.next();
+         
+         Integer failoverNode = (Integer)iter2.next();
+         
+         failoverMap.put(node, failoverNode);
+      }            
+   }
+   
    // Inner classes -------------------------------------------------------------------
     
    /*
@@ -1777,8 +2100,7 @@
       public void setState(byte[] bytes)
       { 
          if (bytes != null)
-         {
-            
+         {            
             try
             {
                lock.writeLock().acquire();         
@@ -1831,8 +2153,10 @@
       {
          if (trace) { log.trace(nodeId + " Got new view, size=" + view.size()); }
 
-         log.info("JBoss Messaging DefaultClusteredPostOffice Accepted new view:" + view);;
+         log.info("JBoss Messaging DefaultClusteredPostOffice Accepted new view:" + view);
          
+         //JGroups will make sure this method is never called by more than one thread concurrently
+         
          if (currentView != null)
          {
             Iterator iter = currentView.getMembers().iterator();
@@ -1843,34 +2167,48 @@
                
                if (!view.containsMember(address))
                {
-                  //Member must have left                  
-                  //We don't remove bindings for ourself
-                  
+                  //Member must have left                                    
                   if (trace) { log.trace(nodeId + " it seems that member " + address + " has left the group"); }
                   
                   Address currentAddress = syncChannel.getLocalAddress();
                   
+                  //We don't remove bindings for ourself                  
                   if (!address.equals(currentAddress))
                   {                  
                      try
                      {
                         Integer nodeId = getNodeIdForSyncAddress(address);
+                        
+                        //Perform a check - the member might have crashed and left uncommitted transactions
+                        //we need to resolve this - this should be performed irrespective of
+                        //whether the node crashed or left cleanly
+                        if (trace) { log.trace(DefaultClusteredPostOffice.this.nodeId + " Performing cleanup for node " + nodeId); }
 
+                        check(nodeId);
+                        
+                        //Remove any non durable binding and replicant data for the exited node
+                        //this should be performed irrespective of whether the node crashed or left cleanly
+                        removeDataForNode(nodeId.intValue());
+                        
                         // nodeId==null means the server left the cluster without a problem. It sent a message before
                         // leaving the cluster
                         if (nodeId != null)
                         {
-                           if (trace) { log.trace(DefaultClusteredPostOffice.this.nodeId + " Performing cleanup for node " + nodeId); }
+                           //This means the node has crashed
+                           if (trace) { log.trace("The node " + nodeId + " crashed"); }
+                                                      
+                           //If we are the failover node for the failed node then we should perform failover
+                           if (isFailoverNodeForNode(nodeId.intValue()))
+                           {
+                              failOver(nodeId.intValue());                              
+                           }
 
-                           //Perform a check - the member might have crashed and left uncommitted transactions
-                           //we need to resolve this
-                           check(nodeId);
-
-                           //removeBindingsForAddress(nodeId);
-                           failOver(nodeId.intValue());
-
-                           if (trace) { log.trace(DefaultClusteredPostOffice.this.nodeId + " cleanup complete"); }
+                           if (trace) { log.trace(DefaultClusteredPostOffice.this.nodeId + " failover complete"); }
                         }
+                        else
+                        {
+                           if (trace) { log.trace("The node " + nodeId + " left cleanly"); }
+                        }
                      }
                      catch (Throwable e)
                      {
@@ -1893,19 +2231,7 @@
          return null;
       }     
    }
-
-
-   private void registerDatasources() throws Exception
-   {
-      if (jndiMapper!=null)
-      {
-         jndiMapper.registerClusteredConnectionFactory(this,clusteredConnectionJndiBindings);
-      }
-   }
-
-
-
-   
+  
    /*
     * This class is used to listen for messages on the async channel
     */

Added: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultFailoverMapper.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultFailoverMapper.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultFailoverMapper.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,73 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.messaging.core.plugin.contract.FailoverMapper;
+
+/**
+ * A DefaultFailoverMapper
+ * 
+ * Generates the mapping by looking to the element to the right and wrapping around to the first
+ * element in the list
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class DefaultFailoverMapper implements FailoverMapper
+{
+
+   public List generateMapping(List nodes)
+   {
+      List failoverNodes = new ArrayList(nodes.size());
+      
+      if (!(nodes instanceof ArrayList))
+      {
+         //So we can ensure fast index based access
+         nodes = new ArrayList(nodes);
+      }
+      
+      int s = nodes.size();
+      
+      for (int i = 0; i < s; i++)
+      {
+         int j = i++;
+         
+         if (j == s)
+         {
+            j = 0;
+         }
+         
+         Object failoverNode = nodes.get(j);
+         
+         failoverNodes.add(failoverNode);
+      }
+      
+      return failoverNodes;
+   }
+
+}

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicy.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicy.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicy.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -41,7 +41,6 @@
 {
    private static final Logger log = Logger.getLogger(DefaultMessagePullPolicy.class);
    
-   
    public ClusteredQueue chooseQueue(List queues)
    {
       Iterator iter = queues.iterator();

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/LeaveClusterRequest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/LeaveClusterRequest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/LeaveClusterRequest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -30,7 +30,7 @@
 
    Object execute(PostOfficeInternal office) throws Throwable
    {
-      office.removeBindingsForAddress(nodeId);
+      office.removeDataForNode(nodeId);
       return null;
    }
 

Deleted: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NodeAddressInfo.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NodeAddressInfo.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NodeAddressInfo.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -1,151 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import org.jboss.messaging.util.Streamable;
-import org.jgroups.Address;
-import org.jgroups.stack.IpAddress;
-
-/**
- * A NodeAddressInfo
- * Note: I have made this class public as I'm using on ConnectionFactoriesServer to prepare ConnectionFactories before being sent to clients
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class NodeAddressInfo implements Streamable
-{
-   private Address syncChannelAddress;
-   
-   private Address asyncChannelAddress;
-
-   private int nodeId;
-
-   public NodeAddressInfo()
-   {     
-   }
-   
-   NodeAddressInfo(int nodeId, Address syncChannelAddress, Address asyncChannelAddress)
-   {
-      this.nodeId = nodeId;
-
-      this.syncChannelAddress = syncChannelAddress;
-      
-      this.asyncChannelAddress = asyncChannelAddress;
-   }
-
-
-   public int getNodeId()
-   {
-      return nodeId;
-   }
-
-   Address getSyncChannelAddress()
-   {
-      return syncChannelAddress;
-   }
-   
-   Address getAsyncChannelAddress()
-   {
-      return asyncChannelAddress;
-   }
-
-
-   public void read(DataInputStream in) throws Exception
-   {
-      nodeId = in.readInt();
-
-      syncChannelAddress = new IpAddress();
-      
-      syncChannelAddress.readFrom(in);
-      
-      asyncChannelAddress = new IpAddress();
-      
-      asyncChannelAddress.readFrom(in);
-
-      byte[] byteInput = new byte[in.readInt()];
-
-      in.read(byteInput);
-   }
-
-   public void write(DataOutputStream out) throws Exception
-   {
-      out.writeInt(nodeId);
-
-      if (!(syncChannelAddress instanceof IpAddress))
-      {
-         throw new IllegalStateException("Address must be IpAddress");
-      }
-      
-      if (!(asyncChannelAddress instanceof IpAddress))
-      {
-         throw new IllegalStateException("Address must be IpAddress");
-      }
-      
-      syncChannelAddress.writeTo(out);
-      
-      asyncChannelAddress.writeTo(out);
-
-   }
-
-
-   private static byte[] writeRequest(Object obj) throws Exception
-   {
-      ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
-
-      ObjectOutputStream objout = new ObjectOutputStream(baos);
-
-      objout.writeObject(obj);
-
-      objout.flush();
-
-      return baos.toByteArray();
-   }
-
-   private static Object readRequest(byte[] bytes) throws Exception
-   {
-      ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
-      ObjectInputStream objinput = new ObjectInputStream(bais);
-
-      return objinput.readObject();
-   }
-
-
-   public String toString()
-   {
-      StringBuffer buffer = new StringBuffer();
-      buffer.append("nodeId=" + nodeId + ", syncChannelAddress=" + syncChannelAddress +
-           ", asyncChannelAddress=" + asyncChannelAddress +", ");
-
-      return buffer.toString();
-   }
-
-}

Copied: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeAddressInfo.java (from rev 1662, branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NodeAddressInfo.java)
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NodeAddressInfo.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeAddressInfo.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+
+import org.jboss.messaging.util.Streamable;
+import org.jgroups.Address;
+import org.jgroups.stack.IpAddress;
+
+/**
+ * 
+ * A PostOfficeAddressInfo
+ * 
+ * Holds the addresses used by a clustered post office
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class PostOfficeAddressInfo implements Streamable, Serializable
+{
+   private static final long serialVersionUID = 8462102430717730566L;
+
+   private Address syncChannelAddress;
+   
+   private Address asyncChannelAddress;
+
+   public PostOfficeAddressInfo()
+   {     
+   }
+   
+   PostOfficeAddressInfo(Address syncChannelAddress, Address asyncChannelAddress)
+   {
+      this.syncChannelAddress = syncChannelAddress;
+      
+      this.asyncChannelAddress = asyncChannelAddress;
+   }
+
+   Address getSyncChannelAddress()
+   {
+      return syncChannelAddress;
+   }
+   
+   Address getAsyncChannelAddress()
+   {
+      return asyncChannelAddress;
+   }
+
+
+   public void read(DataInputStream in) throws Exception
+   {
+      syncChannelAddress = new IpAddress();
+      
+      syncChannelAddress.readFrom(in);
+      
+      asyncChannelAddress = new IpAddress();
+      
+      asyncChannelAddress.readFrom(in);
+
+      byte[] byteInput = new byte[in.readInt()];
+
+      in.read(byteInput);
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      if (!(syncChannelAddress instanceof IpAddress))
+      {
+         throw new IllegalStateException("Address must be IpAddress");
+      }
+      
+      if (!(asyncChannelAddress instanceof IpAddress))
+      {
+         throw new IllegalStateException("Address must be IpAddress");
+      }
+      
+      syncChannelAddress.writeTo(out);
+      
+      asyncChannelAddress.writeTo(out);
+   }
+
+   public String toString()
+   {
+      StringBuffer buffer = new StringBuffer();
+      buffer.append("syncChannelAddress=" + syncChannelAddress +
+           ", asyncChannelAddress=" + asyncChannelAddress +", ");
+
+      return buffer.toString();
+   }
+}

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeInternal.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeInternal.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeInternal.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -21,8 +21,10 @@
  */
 package org.jboss.messaging.core.plugin.postoffice.cluster;
 
+import java.io.Serializable;
 import java.util.List;
 import java.util.Map;
+
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
 
@@ -48,11 +50,12 @@
    void removeBindingFromCluster(int nodeId, String queueName)
       throws Exception;
 
-   void removeBindingsForAddress(int nodeId) throws Exception;
+   void removeDataForNode(int nodeId) throws Exception;
    
-   void handleAddressNodeMapping(NodeAddressInfo info, int nodeId)
-      throws Exception;
+   void putReplicantFromCluster(int nodeId, Serializable key, Serializable replicant) throws Exception;
    
+   boolean removeReplicantFromCluster(int nodeId, Serializable key) throws Exception;
+   
    void routeFromCluster(Message message, String routingKey, Map queueNameNodeIdMap) throws Exception;
    
    void asyncSendRequest(ClusterRequest request) throws Exception;

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesRequest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesRequest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesRequest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -23,8 +23,6 @@
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
-import java.util.Iterator;
-import java.util.List;
 
 import org.jboss.logging.Logger;
 import org.jboss.messaging.core.Delivery;

Added: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PutReplicantRequest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PutReplicantRequest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PutReplicantRequest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+
+import org.jboss.messaging.util.StreamUtils;
+
+
+/**
+ * 
+ * A PutReplicantRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class PutReplicantRequest extends ClusterRequest
+{
+   static final int TYPE = 12;
+
+   private int nodeId;
+   
+   private Serializable key;
+   
+   private Serializable replicant;
+   
+   PutReplicantRequest()
+   {      
+   }
+   
+   PutReplicantRequest(int nodeId, Serializable key, Serializable replicant)
+   {
+      this.nodeId = nodeId;  
+      
+      this.key = key;
+      
+      this.replicant = replicant;
+   }
+   
+   Object execute(PostOfficeInternal office) throws Exception
+   {
+      office.putReplicantFromCluster(nodeId, key, replicant);
+      
+      return null;
+   }
+   
+   byte getType()
+   {
+      return TYPE;
+   }
+
+   public void read(DataInputStream in) throws Exception
+   {
+      nodeId = in.readInt();
+      
+      key = (Serializable)StreamUtils.readObject(in, true);
+      
+      replicant = (Serializable)StreamUtils.readObject(in, true);
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeInt(nodeId);   
+      
+      StreamUtils.writeObject(out, key, true, true);
+      
+      StreamUtils.writeObject(out, replicant, true, true);
+   }
+}

Added: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoveReplicantRequest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoveReplicantRequest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoveReplicantRequest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+
+import org.jboss.messaging.util.StreamUtils;
+
+class RemoveReplicantRequest extends ClusterRequest
+{
+   static final int TYPE = 13;
+
+   private int nodeId;
+   
+   private Serializable key;
+
+   RemoveReplicantRequest()
+   {      
+   }
+   
+   RemoveReplicantRequest(int nodeId, Serializable key)
+   {
+      this.nodeId = nodeId;  
+      
+      this.key = key;
+   }
+   
+   Object execute(PostOfficeInternal office) throws Exception
+   {
+      office.removeReplicantFromCluster(nodeId, key);
+      
+      return null;
+   }
+   
+   byte getType()
+   {
+      return TYPE;
+   }
+
+   public void read(DataInputStream in) throws Exception
+   {
+      nodeId = in.readInt();
+      
+      key = (Serializable)StreamUtils.readObject(in, true);
+   }
+
+   public void write(DataOutputStream out) throws Exception
+   {
+      out.writeInt(nodeId);   
+      
+      StreamUtils.writeObject(out, key, true, true);
+   }
+}

Deleted: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendNodeIdRequest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendNodeIdRequest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendNodeIdRequest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -1,83 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-
-/**
- * A SendNodeIdRequest
- * 
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-class SendNodeIdRequest extends ClusterRequest
-{
-   static final int TYPE = 7;
-
-   private NodeAddressInfo info;
-   
-   private int nodeId;
-   
-   SendNodeIdRequest()
-   {      
-   }
-   
-   SendNodeIdRequest(NodeAddressInfo info, int nodeId)
-   {
-      this.info = info;
-      
-      this.nodeId = nodeId;      
-   }
-   
-   Object execute(PostOfficeInternal office) throws Exception
-   {
-      office.handleAddressNodeMapping(info, nodeId);
-      
-      return null;
-   }
-   
-   byte getType()
-   {
-      return TYPE;
-   }
-
-   public void read(DataInputStream in) throws Exception
-   {
-      info = new NodeAddressInfo();
-      
-      info.read(in);
-      
-      nodeId = in.readInt();
-   }
-
-   public void write(DataOutputStream out) throws Exception
-   {
-      info.write(out);
-      
-      out.writeInt(nodeId);   
-   }
-}

Modified: branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SharedState.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SharedState.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SharedState.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -23,16 +23,21 @@
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.jboss.messaging.util.StreamUtils;
 import org.jboss.messaging.util.Streamable;
 
 /**
  * A SharedState
+ * 
+ * This encapsulates the shared state maintained across the cluster
+ * This comprise the bindings, and the arbitrary replicated data
  *
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision: 1.1 $</tt>
@@ -44,17 +49,17 @@
 {  
    private List bindings;
    
-   private Map nodeIdAddressMap;
+   private Map replicatedData;
    
    SharedState()
    {      
    }
    
-   SharedState(List bindings, Map nodeIdAddressMap)
+   SharedState(List bindings, Map replicatedData)
    {
       this.bindings = bindings;
       
-      this.nodeIdAddressMap = nodeIdAddressMap;
+      this.replicatedData = replicatedData;
    }
    
    List getBindings()
@@ -62,42 +67,46 @@
       return bindings;
    }
    
-   Map getNodeIdAddressMap()
+   Map getReplicatedData()
    {
-      return nodeIdAddressMap;
+      return replicatedData;
    }
 
    public void read(DataInputStream in) throws Exception
    {
       int size = in.readInt();      
+      
       bindings = new ArrayList(size);
+      
       for (int i = 0; i < size; i++)
       {
          BindingInfo bb = new BindingInfo();
+         
          bb.read(in);
+         
          bindings.add(bb);
       }
       
       size = in.readInt();
       
-      nodeIdAddressMap = new HashMap(size);
+      replicatedData = new HashMap(size);
       
       for (int i = 0; i < size; i++)
       {
-         int nodeId = in.readInt();
+         Serializable key = (Serializable)StreamUtils.readObject(in, true);
          
-         NodeAddressInfo info = new NodeAddressInfo();
+         HashMap replicants = StreamUtils.readMap(in, false);
          
-         info.read(in);
-         
-         nodeIdAddressMap.put(new Integer(nodeId), info);
+         replicatedData.put(key, replicants);
       }
    }
 
    public void write(DataOutputStream out) throws Exception
    {
       out.writeInt(bindings.size());
+      
       Iterator iter = bindings.iterator();
+      
       while (iter.hasNext())
       {
          BindingInfo info = (BindingInfo)iter.next();
@@ -105,21 +114,21 @@
          info.write(out);
       }
       
-      out.writeInt(nodeIdAddressMap.size());
+      out.writeInt(replicatedData.size());
       
-      iter = nodeIdAddressMap.entrySet().iterator();
+      iter = replicatedData.entrySet().iterator();
       
       while (iter.hasNext())
       {
          Map.Entry entry = (Map.Entry)iter.next();
          
-         Integer nodeId = (Integer)entry.getKey();
+         Serializable key = (Serializable)entry.getKey();         
          
-         out.writeInt(nodeId.intValue());
+         StreamUtils.writeObject(out, key, true, true);
          
-         NodeAddressInfo info = (NodeAddressInfo)entry.getValue();
+         Map replicants = (Map)entry.getValue();
          
-         info.write(out);
+         StreamUtils.writeMap(out, replicants, false);
       }
    }
 }

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ClusterecConnectionTest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ClusterecConnectionTest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ClusterecConnectionTest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -3,10 +3,11 @@
 import javax.jms.Destination;
 import javax.jms.MessageProducer;
 import javax.jms.Session;
+
 import org.jboss.jms.client.JBossConnection;
 import org.jboss.jms.client.JBossConnectionFactory;
 import org.jboss.jms.client.delegate.ClientConnectionDelegate;
-import org.jboss.jms.client.ha.ClusteredConnectionFactoryDelegate;
+import org.jboss.jms.client.delegate.ClusteredClientConnectionFactoryDelegate;
 import org.jboss.jms.client.state.ConnectionState;
 
 /**
@@ -26,7 +27,7 @@
       JBossConnectionFactory factory = (JBossConnectionFactory)this.ctx1.lookup("/HAConnectionFactory");
       JBossConnection conn = (JBossConnection) factory.createConnection();
 
-      ClusteredConnectionFactoryDelegate delegate = (ClusteredConnectionFactoryDelegate)factory.getDelegate();
+      ClusteredClientConnectionFactoryDelegate delegate = (ClusteredClientConnectionFactoryDelegate)factory.getDelegate();
 
       assertEquals(2,delegate.getDelegates().length);
 

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ReconnectClusteredTest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ReconnectClusteredTest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ReconnectClusteredTest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -18,396 +18,396 @@
 public class ReconnectClusteredTest extends HATestBase
 {
 
-    public void testSimpleReconnect() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
+//    public void testSimpleReconnect() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        assertFalse(state.isStarted());
+//        conn.start();
+//        assertTrue(state.isStarted());
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        conn.stop();
+//        assertFalse(state.isStarted());
+//
+//    }
+//
+//    public void testSimpleReconnectWithClientID() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.setClientID("someClient");
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        assertFalse(state.isStarted());
+//        conn.start();
+//        assertTrue(state.isStarted());
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        // force recovering the clientID from server
+//        state.setClientID(null);
+//        assertEquals ("someClient",conn.getClientID());
+//
+//        conn.stop();
+//        assertFalse(state.isStarted());
+//
+//    }
+//
+//    public void testWithSession() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        Session session = conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//    }
+//
+//    public void testSimpleWithOneProducerOnTopic() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
+//        MessageProducer producer = session.createProducer(destination);
+//
+//        Message message = session.createTextMessage("Hello Before");
+//        producer.send(message);
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        message = session.createTextMessage("Hello After");
+//        producer.send(message);
+//    }
+//
+//    public void testSimpleWithOneProducerOnQueue() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        Destination destination = (Destination)getCtx1().lookup("queue/testQueue");
+//        MessageProducer producer = session.createProducer(destination);
+//
+//        Message message = session.createTextMessage("Hello Before");
+//        producer.send(message);
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        message = session.createTextMessage("Hello After");
+//        producer.send(message);
+//    }
+//
+//    public void testTopicCluster() throws Exception
+//    {
+//        log.info("++testTopicCluster");
+//
+//        log.info(">>Lookup Queue");
+//        Destination destination = (Destination)getCtx1().lookup("topic/testDistributedTopic");
+//
+//        JBossConnection connFirstServer = (JBossConnection)this.factoryServer1.createConnection();
+//        connFirstServer.start();
+//        JBossSession sessionFirstServer = (JBossSession)connFirstServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//
+//
+//        JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
+//        connSecondServer.start();
+//        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//
+//        MessageProducer producer = sessionFirstServer.createProducer(destination);
+//
+//        MessageConsumer consumer = sessionSecondServer.createConsumer(destination);
+//
+//        producer.send(sessionFirstServer.createTextMessage("Hello"));
+//
+//        assertNotNull(consumer.receive(2000));
+//    }
+//
+//    public void testTopicSubscriber() throws Exception
+//    {
+//        log.info("++testTopicSubscriber");
+//
+//        log.info(">>Lookup Queue");
+//        Destination destination = (Destination)getCtx1().lookup("topic/testDistributedTopic");
+//
+//        log.info("Creating connection server1");
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.setClientID("testClient");
+//        conn.start();
+//
+//        JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
+//        ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
+//        SessionState sessionState = (SessionState)clientSessionDelegate.getState();
+//
+//        MessageConsumer consumerHA = session.createDurableSubscriber((Topic)destination,"T1");
+//        JBossMessageConsumer jbossConsumerHA =(JBossMessageConsumer)consumerHA;
+//
+//        org.jboss.jms.client.delegate.ClientConsumerDelegate clientDelegate = (org.jboss.jms.client.delegate.ClientConsumerDelegate)jbossConsumerHA.getDelegate();
+//        ConsumerState consumerState = (ConsumerState)clientDelegate.getState();
+//
+//        log.info("subscriptionName=" + consumerState.getSubscriptionName());
+//
+//
+//        log.info(">>Creating Producer");
+//        MessageProducer producer = session.createProducer(destination);
+//        log.info(">>creating Message");
+//        Message message = session.createTextMessage("Hello Before");
+//        log.info(">>sending Message");
+//        producer.send(message);
+//        session.commit();
+//
+//        receiveMessage("consumerHA",consumerHA,true,false);
+//
+//        session.commit();
+//        //if (true) return;
+//
+//        Object txID = sessionState.getCurrentTxId();
+//
+//        producer.send(session.createTextMessage("Hello again before failover"));
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//
+//        JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
+//
+//        log.info(">>Creating alternate connection");
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
+//        log.info("NewConnectionCreated=" + conn2);
+//
+//        log.info(">>Failling over");
+//        assertSame(originalRemoting,delegate.getRemotingConnection());
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        try {
+//            originalRemoting.stop();
+//        } catch (Throwable throwable) {
+//            throwable.printStackTrace();
+//        }
+//
+//
+//        assertNotSame(originalRemoting,delegate.getRemotingConnection());
+//
+//        //System.out.println("Kill server1"); Thread.sleep(10000);
+//
+//        message = session.createTextMessage("Hello After");
+//        log.info(">>Sending new message");
+//        producer.send(message);
+//
+//        assertEquals(txID,sessionState.getCurrentTxId());
+//        System.out.println("TransactionID on client = " + txID);
+//        log.info(">>Final commit");
+//
+//       /* JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
+//        connSecondServer.start();
+//        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination); */
+//
+//        session.commit();
+//
+//        /* receiveMessage("consumerSecondServer",consumerSecondServer,true,false);
+//        receiveMessage("consumerSecondServer",consumerSecondServer,true,false);
+//        receiveMessage("consumerSecondServer",consumerSecondServer,true,true); */
+//
+//        log.info("Calling alternate receiver");
+//        receiveMessage("consumerHA",consumerHA,true,false);
+//        receiveMessage("consumerHA",consumerHA,true,false);
+//        receiveMessage("consumerHA",consumerHA,true,true);
+//
+//
+//        session.commit();
+//
+//    }
+//
+//   public void testQueueHA() throws Exception
+//   {
+//       log.info("++testTopicSubscriber");
+//
+//       log.info(">>Lookup Queue");
+//       Destination destination = (Destination)getCtx1().lookup("queue/testDistributedQueue");
+//
+//       log.info("Creating connection server1");
+//       JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//       conn.setClientID("testClient");
+//       conn.start();
+//
+//       JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
+//       ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
+//       SessionState sessionState = (SessionState)clientSessionDelegate.getState();
+//
+//       MessageConsumer consumerHA = session.createConsumer(destination);
+//       JBossMessageConsumer jbossConsumerHA =(JBossMessageConsumer)consumerHA;
+//
+//       org.jboss.jms.client.delegate.ClientConsumerDelegate clientDelegate = (org.jboss.jms.client.delegate.ClientConsumerDelegate)jbossConsumerHA.getDelegate();
+//       ConsumerState consumerState = (ConsumerState)clientDelegate.getState();
+//
+//       log.info("subscriptionName=" + consumerState.getSubscriptionName());
+//
+//
+//       log.info(">>Creating Producer");
+//       MessageProducer producer = session.createProducer(destination);
+//       log.info(">>creating Message");
+//       Message message = session.createTextMessage("Hello Before");
+//       log.info(">>sending Message");
+//       producer.send(message);
+//       session.commit();
+//
+//       session.commit();
+//       //if (true) return;
+//
+//       Object txID = sessionState.getCurrentTxId();
+//
+//       ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//
+//       JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
+//
+//       log.info(">>Creating alternate connection");
+//       JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
+//       log.info("NewConnectionCreated=" + conn2);
+//
+//       log.info(">>Failling over");
+//       assertSame(originalRemoting,delegate.getRemotingConnection());
+//       conn.getDelegate().failOver(conn2.getDelegate());
+//
+//       try {
+//           originalRemoting.stop();
+//       } catch (Throwable throwable) {
+//           throwable.printStackTrace();
+//       }
+//
+//
+//       assertNotSame(originalRemoting,delegate.getRemotingConnection());
+//
+//       //System.out.println("Kill server1"); Thread.sleep(10000);
+//       assertEquals(txID,sessionState.getCurrentTxId());
+//       System.out.println("TransactionID on client = " + txID);
+//       log.info(">>Final commit");
+//
+//       session.commit();
+//
+//       log.info("Calling alternate receiver");
+//       receiveMessage("consumerHA",consumerHA,true,false);
+//       receiveMessage("consumerHA",consumerHA,true,true);
+//
+//       session.commit();
+//
+//       for (int i=0;i<30;i++)
+//       {
+//          log.info("Message Sent " + i);
+//          producer.send(session.createTextMessage("Message " + i));
+//       }
+//      session.commit();
+//
+//      Thread.sleep(5000);
+//
+//       TextMessage messageLoop = null;
+//       while (!((messageLoop = (TextMessage) consumerHA.receive(5000)) == null))
+//       {
+//          log.info("Message received = " + messageLoop.getText());
+//       }
+//
+//   }
+//
+//
+//    private void receiveMessage(String text, MessageConsumer consumer, boolean shouldAssert, boolean shouldBeNull) throws Exception
+//    {
+//        MessageProxy message = (MessageProxy)consumer.receive(3000);
+//        TextMessage txtMessage = (TextMessage)message;
+//        if (message!=null)
+//        {
+//            log.info(text + ": messageID from messageReceived=" + message.getMessage().getMessageID() + " message = " + message + " content=" + txtMessage.getText());
+//        }
+//        else
+//        {
+//            log.info(text + ": Message received was null");
+//        }
+//        if (shouldAssert)
+//        {
+//            if (shouldBeNull)
+//            {
+//                assertNull(message);
+//            }
+//            else
+//            {
+//                assertNotNull(message);
+//            }
+//        }
+//    }
+//
+//   public void testSimplestDurableSubscription() throws Exception
+//   {
+//      ConnectionFactory cf = factoryServer1;
+//      Topic topic = (Topic)getCtx1().lookup("topic/testDistributedTopic");
+//
+//      Connection conn = cf.createConnection();
+//
+//      conn.setClientID("brookeburke");
+//
+//      conn.start();
+//
+//      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+//      MessageProducer prod = s.createProducer(topic);
+//      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+//
+//      log.info("      ******************                       s.createDurableSubscriber(topic, \"monicabelucci\")                 ****************************");
+//      MessageConsumer firstconsumer = (MessageConsumer)s.createDurableSubscriber(topic, "monicabelucci");
+//
+//
+//      System.out.println("\n\n****************************************   consumer=" + firstconsumer.toString() + "\n\n");
+//      Object message=firstconsumer.receive(2000);
+//
+//      log.info(" \n\n*******************************                          message Received=" + message + "\n\n");
+//
+//      prod.send(s.createTextMessage("k"));
+//
+//      conn.close();
+//
+//      conn = cf.createConnection();
+//      conn.setClientID("brookeburke");
+//
+//      log.info("      ******************                       conn.createSession(...);                                                       ****************************");
+//      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+//
+//
+//      log.info("      ******************                       s.createDurableSubscriber(topic, \"monicabelucci\")                 ****************************");
+//      MessageConsumer durable = s.createDurableSubscriber(topic, "monicabelucci");
+//
+//       log.info("      ******************                       conn.start();                                                       ****************************");
+//       conn.start();
+//
+//      log.info("      ******************                       TextMessage tm = (TextMessage)durable.receive();                    ****************************");
+//      TextMessage tm = (TextMessage)durable.receive();
+//      assertEquals("k", tm.getText());
+//
+//      log.info("      ******************                       Message m = durable.receive(1000); (expected to be null)            ****************************");
+//      Message m = durable.receive(1000);
+//
+//       prod = s.createProducer(topic);
+//       prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+//       prod.send(s.createTextMessage("Hello"));
+//
+//       Connection conn2 = factoryServer2.createConnection();
+//       conn2.setClientID("clientTest");
+//
+//       Session session = conn2.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//       conn2.start();
+//
+//       MessageConsumer consumer2 = session.createDurableSubscriber(topic,"spongebog");
+//       System.out.println("Consumer2=" + consumer2);
+//
+//
+//   }
 
-        assertFalse(state.isStarted());
-        conn.start();
-        assertTrue(state.isStarted());
 
-        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        conn.stop();
-        assertFalse(state.isStarted());
-
-    }
-
-    public void testSimpleReconnectWithClientID() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        conn.setClientID("someClient");
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        assertFalse(state.isStarted());
-        conn.start();
-        assertTrue(state.isStarted());
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        // force recovering the clientID from server
-        state.setClientID(null);
-        assertEquals ("someClient",conn.getClientID());
-
-        conn.stop();
-        assertFalse(state.isStarted());
-
-    }
-
-    public void testWithSession() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        Session session = conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-    }
-
-    public void testSimpleWithOneProducerOnTopic() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
-        MessageProducer producer = session.createProducer(destination);
-
-        Message message = session.createTextMessage("Hello Before");
-        producer.send(message);
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        message = session.createTextMessage("Hello After");
-        producer.send(message);
-    }
-
-    public void testSimpleWithOneProducerOnQueue() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        Destination destination = (Destination)getCtx1().lookup("queue/testQueue");
-        MessageProducer producer = session.createProducer(destination);
-
-        Message message = session.createTextMessage("Hello Before");
-        producer.send(message);
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        message = session.createTextMessage("Hello After");
-        producer.send(message);
-    }
-
-    public void testTopicCluster() throws Exception
-    {
-        log.info("++testTopicCluster");
-
-        log.info(">>Lookup Queue");
-        Destination destination = (Destination)getCtx1().lookup("topic/testDistributedTopic");
-
-        JBossConnection connFirstServer = (JBossConnection)this.factoryServer1.createConnection();
-        connFirstServer.start();
-        JBossSession sessionFirstServer = (JBossSession)connFirstServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-
-
-        JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
-        connSecondServer.start();
-        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-
-        MessageProducer producer = sessionFirstServer.createProducer(destination);
-
-        MessageConsumer consumer = sessionSecondServer.createConsumer(destination);
-
-        producer.send(sessionFirstServer.createTextMessage("Hello"));
-
-        assertNotNull(consumer.receive(2000));
-    }
-
-    public void testTopicSubscriber() throws Exception
-    {
-        log.info("++testTopicSubscriber");
-
-        log.info(">>Lookup Queue");
-        Destination destination = (Destination)getCtx1().lookup("topic/testDistributedTopic");
-
-        log.info("Creating connection server1");
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        conn.setClientID("testClient");
-        conn.start();
-
-        JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
-        ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
-        SessionState sessionState = (SessionState)clientSessionDelegate.getState();
-
-        MessageConsumer consumerHA = session.createDurableSubscriber((Topic)destination,"T1");
-        JBossMessageConsumer jbossConsumerHA =(JBossMessageConsumer)consumerHA;
-
-        org.jboss.jms.client.delegate.ClientConsumerDelegate clientDelegate = (org.jboss.jms.client.delegate.ClientConsumerDelegate)jbossConsumerHA.getDelegate();
-        ConsumerState consumerState = (ConsumerState)clientDelegate.getState();
-
-        log.info("subscriptionName=" + consumerState.getSubscriptionName());
-
-
-        log.info(">>Creating Producer");
-        MessageProducer producer = session.createProducer(destination);
-        log.info(">>creating Message");
-        Message message = session.createTextMessage("Hello Before");
-        log.info(">>sending Message");
-        producer.send(message);
-        session.commit();
-
-        receiveMessage("consumerHA",consumerHA,true,false);
-
-        session.commit();
-        //if (true) return;
-
-        Object txID = sessionState.getCurrentTxId();
-
-        producer.send(session.createTextMessage("Hello again before failover"));
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-
-        JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
-
-        log.info(">>Creating alternate connection");
-        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
-        log.info("NewConnectionCreated=" + conn2);
-
-        log.info(">>Failling over");
-        assertSame(originalRemoting,delegate.getRemotingConnection());
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        try {
-            originalRemoting.stop();
-        } catch (Throwable throwable) {
-            throwable.printStackTrace();
-        }
-
-
-        assertNotSame(originalRemoting,delegate.getRemotingConnection());
-
-        //System.out.println("Kill server1"); Thread.sleep(10000);
-
-        message = session.createTextMessage("Hello After");
-        log.info(">>Sending new message");
-        producer.send(message);
-
-        assertEquals(txID,sessionState.getCurrentTxId());
-        System.out.println("TransactionID on client = " + txID);
-        log.info(">>Final commit");
-
-       /* JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
-        connSecondServer.start();
-        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination); */
-
-        session.commit();
-
-        /* receiveMessage("consumerSecondServer",consumerSecondServer,true,false);
-        receiveMessage("consumerSecondServer",consumerSecondServer,true,false);
-        receiveMessage("consumerSecondServer",consumerSecondServer,true,true); */
-
-        log.info("Calling alternate receiver");
-        receiveMessage("consumerHA",consumerHA,true,false);
-        receiveMessage("consumerHA",consumerHA,true,false);
-        receiveMessage("consumerHA",consumerHA,true,true);
-
-
-        session.commit();
-
-    }
-
-   public void testQueueHA() throws Exception
-   {
-       log.info("++testTopicSubscriber");
-
-       log.info(">>Lookup Queue");
-       Destination destination = (Destination)getCtx1().lookup("queue/testDistributedQueue");
-
-       log.info("Creating connection server1");
-       JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-       conn.setClientID("testClient");
-       conn.start();
-
-       JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
-       ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
-       SessionState sessionState = (SessionState)clientSessionDelegate.getState();
-
-       MessageConsumer consumerHA = session.createConsumer(destination);
-       JBossMessageConsumer jbossConsumerHA =(JBossMessageConsumer)consumerHA;
-
-       org.jboss.jms.client.delegate.ClientConsumerDelegate clientDelegate = (org.jboss.jms.client.delegate.ClientConsumerDelegate)jbossConsumerHA.getDelegate();
-       ConsumerState consumerState = (ConsumerState)clientDelegate.getState();
-
-       log.info("subscriptionName=" + consumerState.getSubscriptionName());
-
-
-       log.info(">>Creating Producer");
-       MessageProducer producer = session.createProducer(destination);
-       log.info(">>creating Message");
-       Message message = session.createTextMessage("Hello Before");
-       log.info(">>sending Message");
-       producer.send(message);
-       session.commit();
-
-       session.commit();
-       //if (true) return;
-
-       Object txID = sessionState.getCurrentTxId();
-
-       ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-
-       JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
-
-       log.info(">>Creating alternate connection");
-       JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
-       log.info("NewConnectionCreated=" + conn2);
-
-       log.info(">>Failling over");
-       assertSame(originalRemoting,delegate.getRemotingConnection());
-       conn.getDelegate().failOver(conn2.getDelegate());
-
-       try {
-           originalRemoting.stop();
-       } catch (Throwable throwable) {
-           throwable.printStackTrace();
-       }
-
-
-       assertNotSame(originalRemoting,delegate.getRemotingConnection());
-
-       //System.out.println("Kill server1"); Thread.sleep(10000);
-       assertEquals(txID,sessionState.getCurrentTxId());
-       System.out.println("TransactionID on client = " + txID);
-       log.info(">>Final commit");
-
-       session.commit();
-
-       log.info("Calling alternate receiver");
-       receiveMessage("consumerHA",consumerHA,true,false);
-       receiveMessage("consumerHA",consumerHA,true,true);
-
-       session.commit();
-
-       for (int i=0;i<30;i++)
-       {
-          log.info("Message Sent " + i);
-          producer.send(session.createTextMessage("Message " + i));
-       }
-      session.commit();
-
-      Thread.sleep(5000);
-
-       TextMessage messageLoop = null;
-       while (!((messageLoop = (TextMessage) consumerHA.receive(5000)) == null))
-       {
-          log.info("Message received = " + messageLoop.getText());
-       }
-
-   }
-
-
-    private void receiveMessage(String text, MessageConsumer consumer, boolean shouldAssert, boolean shouldBeNull) throws Exception
-    {
-        MessageProxy message = (MessageProxy)consumer.receive(3000);
-        TextMessage txtMessage = (TextMessage)message;
-        if (message!=null)
-        {
-            log.info(text + ": messageID from messageReceived=" + message.getMessage().getMessageID() + " message = " + message + " content=" + txtMessage.getText());
-        }
-        else
-        {
-            log.info(text + ": Message received was null");
-        }
-        if (shouldAssert)
-        {
-            if (shouldBeNull)
-            {
-                assertNull(message);
-            }
-            else
-            {
-                assertNotNull(message);
-            }
-        }
-    }
-
-   public void testSimplestDurableSubscription() throws Exception
-   {
-      ConnectionFactory cf = factoryServer1;
-      Topic topic = (Topic)getCtx1().lookup("topic/testDistributedTopic");
-
-      Connection conn = cf.createConnection();
-
-      conn.setClientID("brookeburke");
-
-      conn.start();
-
-      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      MessageProducer prod = s.createProducer(topic);
-      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
-
-      log.info("      ******************                       s.createDurableSubscriber(topic, \"monicabelucci\")                 ****************************");
-      MessageConsumer firstconsumer = (MessageConsumer)s.createDurableSubscriber(topic, "monicabelucci");
-
-
-      System.out.println("\n\n****************************************   consumer=" + firstconsumer.toString() + "\n\n");
-      Object message=firstconsumer.receive(2000);
-
-      log.info(" \n\n*******************************                          message Received=" + message + "\n\n");
-
-      prod.send(s.createTextMessage("k"));
-
-      conn.close();
-
-      conn = cf.createConnection();
-      conn.setClientID("brookeburke");
-
-      log.info("      ******************                       conn.createSession(...);                                                       ****************************");
-      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-
-      log.info("      ******************                       s.createDurableSubscriber(topic, \"monicabelucci\")                 ****************************");
-      MessageConsumer durable = s.createDurableSubscriber(topic, "monicabelucci");
-
-       log.info("      ******************                       conn.start();                                                       ****************************");
-       conn.start();
-
-      log.info("      ******************                       TextMessage tm = (TextMessage)durable.receive();                    ****************************");
-      TextMessage tm = (TextMessage)durable.receive();
-      assertEquals("k", tm.getText());
-
-      log.info("      ******************                       Message m = durable.receive(1000); (expected to be null)            ****************************");
-      Message m = durable.receive(1000);
-
-       prod = s.createProducer(topic);
-       prod.setDeliveryMode(DeliveryMode.PERSISTENT);
-       prod.send(s.createTextMessage("Hello"));
-
-       Connection conn2 = factoryServer2.createConnection();
-       conn2.setClientID("clientTest");
-
-       Session session = conn2.createSession(false,Session.AUTO_ACKNOWLEDGE);
-       conn2.start();
-
-       MessageConsumer consumer2 = session.createDurableSubscriber(topic,"spongebog");
-       System.out.println("Consumer2=" + consumer2);
-
-
-   }
-
-
 }

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ReconnectNonClusteredTest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ReconnectNonClusteredTest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/ha/ReconnectNonClusteredTest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -18,373 +18,373 @@
 public class ReconnectNonClusteredTest extends HATestBase
 {
 
-    public void testSimpleReconnect() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        assertFalse(state.isStarted());
-        conn.start();
-        assertTrue(state.isStarted());
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        conn.stop();
-        assertFalse(state.isStarted());
-
-    }
-
-    public void testSimpleReconnectWithClientID() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        conn.setClientID("someClient");
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        assertFalse(state.isStarted());
-        conn.start();
-        assertTrue(state.isStarted());
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        // force recovering the clientID from server
-        state.setClientID(null);
-        assertEquals ("someClient",conn.getClientID());
-
-        conn.stop();
-        assertFalse(state.isStarted());
-
-    }
-
-    public void testWithSession() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        Session session = conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-    }
-
-    public void testSimpleWithOneProducerOnTopic() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
-        MessageProducer producer = session.createProducer(destination);
-
-        Message message = session.createTextMessage("Hello Before");
-        producer.send(message);
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        System.out.println("Kill server1");
-        Thread.sleep(10000);
-
-
-        message = session.createTextMessage("Hello After");
-        producer.send(message);
-    }
-
-    public void testSimpleWithOneProducerOnQueue() throws Exception
-    {
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        Destination destination = (Destination)getCtx1().lookup("queue/testQueue");
-        MessageProducer producer = session.createProducer(destination);
-
-        Message message = session.createTextMessage("Hello Before");
-        producer.send(message);
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        System.out.println("Kill server1");
-        Thread.sleep(10000);
-
-
-        message = session.createTextMessage("Hello After");
-        producer.send(message);
-    }
-
-    public void testSimpleWithOneProducerTransacted() throws Exception
-    {
-        log.info("++testSimpleWithOneProducerTransacted");
-
-        log.info(">>Lookup Queue");
-        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
-
-        log.info("Creating connections used for assertion (not failed over)");
-        JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
-        connSecondServer.start();
-        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination);
-
-        JBossConnection connFirstServer = (JBossConnection)this.factoryServer1.createConnection();
-        connFirstServer.start();
-        JBossSession sessionFirstServer = (JBossSession)connFirstServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        MessageConsumer consumerFirstServer = sessionFirstServer.createConsumer(destination);
-
-
-        log.info("Creating connection server1");
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-
-        log.info("ConnectionCreated=" + conn);
-        log.info(">>Creating Sessions");
-
-        JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
-        ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
-        SessionState sessionState = (SessionState)clientSessionDelegate.getState();
-        log.info(">>Creating Producer");
-        MessageProducer producer = session.createProducer(destination);
-        log.info(">>Creating Producer - ");
-        log.info(">>creating Message");
-        Message message = session.createTextMessage("Hello Before");
-        log.info(">>sending Message");
-        producer.send(message);
-
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-        log.info("sending first commit");
-        session.commit();
-        Object txID = sessionState.getCurrentTxId();
-
-        assertNotNull(consumerFirstServer.receive(2000));
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-        producer.send(session.createTextMessage("Hello again before failover"));
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-
-        JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        log.info(">>Creating alternate connection");
-        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
-        log.info("NewConnectionCreated=" + conn2);
-
-        log.info(">>Failling over");
-        assertSame(originalRemoting,delegate.getRemotingConnection());
-        conn.getDelegate().failOver(conn2.getDelegate());
-        /*try {
-            originalRemoting.stop();
-        } catch (Throwable throwable) {
-            throwable.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-        } */
-
-        assertNotSame(originalRemoting,delegate.getRemotingConnection());
-
-        //System.out.println("Kill server1"); Thread.sleep(10000);
-
-        message = session.createTextMessage("Hello After");
-        log.info(">>Sending new message");
-        producer.send(message);
-
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-        assertEquals(txID,sessionState.getCurrentTxId());
-        System.out.println("TransactionID on client = " + txID);
-        log.info(">>Final commit");
-        session.commit();
-
-        log.info("Checking receive on second server");
-        assertNotNull(consumerSecondServer.receive(1000));
-        assertNotNull(consumerSecondServer.receive(1000));
-        log.info("Checking receive on first server");
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-    }
-
-    public void testSimpleWithOneProducerTransactedWithoutHA() throws Exception
-    {
-        log.info("++testSimpleWithOneProducerTransacted");
-
-        log.info(">>Lookup Queue");
-        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
-
-        log.info("Creating connections used for assertion (not failed over)");
-        JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
-        connSecondServer.start();
-        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination);
-
-        JBossConnection connFirstServer = (JBossConnection)this.factoryServer1.createConnection();
-        connFirstServer.start();
-        JBossSession sessionFirstServer = (JBossSession)connFirstServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        MessageConsumer consumerFirstServer = sessionFirstServer.createConsumer(destination);
-
-
-        log.info("Creating connection server1");
-        JBossConnection  conn = (JBossConnection)this.factoryServer2.createConnection();
-
-        log.info("ConnectionCreated=" + conn);
-        log.info(">>Creating Sessions");
-
-        JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
-        ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
-        SessionState sessionState = (SessionState)clientSessionDelegate.getState();
-        System.out.println("Size of callbackHandlers=" + sessionState.getCallbackHandlers().size());
-        Object txID = sessionState.getCurrentTxId();
-        log.info(">>Creating Producer");
-        MessageProducer producer = session.createProducer(destination);
-        log.info(">>Creating Producer - ");
-        log.info(">>creating Message");
-        Message message = session.createTextMessage("Hello Before");
-        log.info(">>sending Message");
-        producer.send(message);
-
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-        log.info("sending first commit");
-        //session.commit();
-
-        assertNull(consumerFirstServer.receive(2000));
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-        TextMessageProxy messagetxt = (TextMessageProxy)session.createTextMessage("Hello again before failover");
-        producer.send(messagetxt);
-        System.out.println("Id=" + messagetxt.getMessage().getConnectionID());
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-
-        JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        log.info(">>Failling over");
-        //System.out.println("Kill server1"); Thread.sleep(10000);
-
-        message = session.createTextMessage("Hello After");
-        log.info(">>Sending new message");
-        producer.send(message);
-
-        assertNull(consumerFirstServer.receive(1000));
-        assertNull(consumerSecondServer.receive(1000));
-
-        assertEquals(txID,sessionState.getCurrentTxId());
-        System.out.println("TransactionID on client = " + txID);
-        log.info(">>Final commit");
-        session.commit();
-
-        log.info("Checking receive on second server");
-        assertNull(consumerFirstServer.receive(1000));
-        assertNotNull(consumerSecondServer.receive(3000));
-        assertNotNull(consumerSecondServer.receive(1000));
-        assertNotNull(consumerSecondServer.receive(1000));
-        log.info("Checking receive on first server");
-        assertNull(consumerSecondServer.receive(1000));
-
-    }
-
-    public void testTopicSubscriber() throws Exception
-    {
-        log.info("++testSimpleWithOneProducerTransacted");
-
-        log.info(">>Lookup Queue");
-        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
-
-        JBossConnection connFirstServer = (JBossConnection)this.factoryServer1.createConnection();
-        connFirstServer.start();
-        JBossSession sessionFirstServer = (JBossSession)connFirstServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-
-
-        log.info("Creating connection server1");
-        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
-        conn.start();
-
-        log.info("ConnectionCreated=" + conn);
-        log.info(">>Creating Sessions");
-
-        JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
-        ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
-        SessionState sessionState = (SessionState)clientSessionDelegate.getState();
-        MessageConsumer consumerHA = session.createConsumer(destination);
-        log.info(">>Creating Producer");
-        MessageProducer producer = session.createProducer(destination);
-        log.info(">>creating Message");
-        Message message = session.createTextMessage("Hello Before");
-        log.info(">>sending Message");
-        producer.send(message);
-        session.commit();
-
-        assertNotNull(consumerHA.receive(3000));
-        session.commit();
-
-        Object txID = sessionState.getCurrentTxId();
-
-        producer.send(session.createTextMessage("Hello again before failover"));
-
-        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
-
-        JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
-
-        ConnectionState state = (ConnectionState)delegate.getState();
-
-        log.info(">>Creating alternate connection");
-        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
-        log.info("NewConnectionCreated=" + conn2);
-
-        log.info(">>Failling over");
-        assertSame(originalRemoting,delegate.getRemotingConnection());
-        conn.getDelegate().failOver(conn2.getDelegate());
-
-        try {
-            originalRemoting.stop();
-        } catch (Throwable throwable) {
-            throwable.printStackTrace();
-        }
-
-
-        assertNotSame(originalRemoting,delegate.getRemotingConnection());
-
-        //System.out.println("Kill server1"); Thread.sleep(10000);
-
-        message = session.createTextMessage("Hello After");
-        log.info(">>Sending new message");
-        producer.send(message);
-
-        assertEquals(txID,sessionState.getCurrentTxId());
-        System.out.println("TransactionID on client = " + txID);
-        log.info(">>Final commit");
-
-        JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
-        connSecondServer.start();
-        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-        MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination);
-
-        session.commit();
-
-        //assertNotNull(consumerSecondServer.receive(3000));
-        assertNotNull(consumerSecondServer.receive(3000));
-        assertNotNull(consumerSecondServer.receive(3000));
-        assertNull(consumerSecondServer.receive(3000));
-
-        log.info("Calling alternate receiver");
-        //assertNotNull(consumerHA.receive(1000));
-        assertNotNull(consumerHA.receive(1000));
-        assertNotNull(consumerHA.receive(1000));
-        assertNull(consumerHA.receive(1000));
-
-    }
+//    public void testSimpleReconnect() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        assertFalse(state.isStarted());
+//        conn.start();
+//        assertTrue(state.isStarted());
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        conn.stop();
+//        assertFalse(state.isStarted());
+//
+//    }
+//
+//    public void testSimpleReconnectWithClientID() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.setClientID("someClient");
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        assertFalse(state.isStarted());
+//        conn.start();
+//        assertTrue(state.isStarted());
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        // force recovering the clientID from server
+//        state.setClientID(null);
+//        assertEquals ("someClient",conn.getClientID());
+//
+//        conn.stop();
+//        assertFalse(state.isStarted());
+//
+//    }
+//
+//    public void testWithSession() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        Session session = conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//    }
+//
+//    public void testSimpleWithOneProducerOnTopic() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
+//        MessageProducer producer = session.createProducer(destination);
+//
+//        Message message = session.createTextMessage("Hello Before");
+//        producer.send(message);
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        System.out.println("Kill server1");
+//        Thread.sleep(10000);
+//
+//
+//        message = session.createTextMessage("Hello After");
+//        producer.send(message);
+//    }
+//
+//    public void testSimpleWithOneProducerOnQueue() throws Exception
+//    {
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        Destination destination = (Destination)getCtx1().lookup("queue/testQueue");
+//        MessageProducer producer = session.createProducer(destination);
+//
+//        Message message = session.createTextMessage("Hello Before");
+//        producer.send(message);
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        System.out.println("Kill server1");
+//        Thread.sleep(10000);
+//
+//
+//        message = session.createTextMessage("Hello After");
+//        producer.send(message);
+//    }
+//
+//    public void testSimpleWithOneProducerTransacted() throws Exception
+//    {
+//        log.info("++testSimpleWithOneProducerTransacted");
+//
+//        log.info(">>Lookup Queue");
+//        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
+//
+//        log.info("Creating connections used for assertion (not failed over)");
+//        JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
+//        connSecondServer.start();
+//        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination);
+//
+//        JBossConnection connFirstServer = (JBossConnection)this.factoryServer1.createConnection();
+//        connFirstServer.start();
+//        JBossSession sessionFirstServer = (JBossSession)connFirstServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        MessageConsumer consumerFirstServer = sessionFirstServer.createConsumer(destination);
+//
+//
+//        log.info("Creating connection server1");
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//
+//        log.info("ConnectionCreated=" + conn);
+//        log.info(">>Creating Sessions");
+//
+//        JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
+//        ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
+//        SessionState sessionState = (SessionState)clientSessionDelegate.getState();
+//        log.info(">>Creating Producer");
+//        MessageProducer producer = session.createProducer(destination);
+//        log.info(">>Creating Producer - ");
+//        log.info(">>creating Message");
+//        Message message = session.createTextMessage("Hello Before");
+//        log.info(">>sending Message");
+//        producer.send(message);
+//
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//        log.info("sending first commit");
+//        session.commit();
+//        Object txID = sessionState.getCurrentTxId();
+//
+//        assertNotNull(consumerFirstServer.receive(2000));
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//        producer.send(session.createTextMessage("Hello again before failover"));
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//
+//        JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        log.info(">>Creating alternate connection");
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
+//        log.info("NewConnectionCreated=" + conn2);
+//
+//        log.info(">>Failling over");
+//        assertSame(originalRemoting,delegate.getRemotingConnection());
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//        /*try {
+//            originalRemoting.stop();
+//        } catch (Throwable throwable) {
+//            throwable.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+//        } */
+//
+//        assertNotSame(originalRemoting,delegate.getRemotingConnection());
+//
+//        //System.out.println("Kill server1"); Thread.sleep(10000);
+//
+//        message = session.createTextMessage("Hello After");
+//        log.info(">>Sending new message");
+//        producer.send(message);
+//
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//        assertEquals(txID,sessionState.getCurrentTxId());
+//        System.out.println("TransactionID on client = " + txID);
+//        log.info(">>Final commit");
+//        session.commit();
+//
+//        log.info("Checking receive on second server");
+//        assertNotNull(consumerSecondServer.receive(1000));
+//        assertNotNull(consumerSecondServer.receive(1000));
+//        log.info("Checking receive on first server");
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//    }
+//
+//    public void testSimpleWithOneProducerTransactedWithoutHA() throws Exception
+//    {
+//        log.info("++testSimpleWithOneProducerTransacted");
+//
+//        log.info(">>Lookup Queue");
+//        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
+//
+//        log.info("Creating connections used for assertion (not failed over)");
+//        JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
+//        connSecondServer.start();
+//        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination);
+//
+//        JBossConnection connFirstServer = (JBossConnection)this.factoryServer1.createConnection();
+//        connFirstServer.start();
+//        JBossSession sessionFirstServer = (JBossSession)connFirstServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        MessageConsumer consumerFirstServer = sessionFirstServer.createConsumer(destination);
+//
+//
+//        log.info("Creating connection server1");
+//        JBossConnection  conn = (JBossConnection)this.factoryServer2.createConnection();
+//
+//        log.info("ConnectionCreated=" + conn);
+//        log.info(">>Creating Sessions");
+//
+//        JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
+//        ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
+//        SessionState sessionState = (SessionState)clientSessionDelegate.getState();
+//        System.out.println("Size of callbackHandlers=" + sessionState.getCallbackHandlers().size());
+//        Object txID = sessionState.getCurrentTxId();
+//        log.info(">>Creating Producer");
+//        MessageProducer producer = session.createProducer(destination);
+//        log.info(">>Creating Producer - ");
+//        log.info(">>creating Message");
+//        Message message = session.createTextMessage("Hello Before");
+//        log.info(">>sending Message");
+//        producer.send(message);
+//
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//        log.info("sending first commit");
+//        //session.commit();
+//
+//        assertNull(consumerFirstServer.receive(2000));
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//        TextMessageProxy messagetxt = (TextMessageProxy)session.createTextMessage("Hello again before failover");
+//        producer.send(messagetxt);
+//        System.out.println("Id=" + messagetxt.getMessage().getConnectionID());
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//
+//        JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        log.info(">>Failling over");
+//        //System.out.println("Kill server1"); Thread.sleep(10000);
+//
+//        message = session.createTextMessage("Hello After");
+//        log.info(">>Sending new message");
+//        producer.send(message);
+//
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//        assertEquals(txID,sessionState.getCurrentTxId());
+//        System.out.println("TransactionID on client = " + txID);
+//        log.info(">>Final commit");
+//        session.commit();
+//
+//        log.info("Checking receive on second server");
+//        assertNull(consumerFirstServer.receive(1000));
+//        assertNotNull(consumerSecondServer.receive(3000));
+//        assertNotNull(consumerSecondServer.receive(1000));
+//        assertNotNull(consumerSecondServer.receive(1000));
+//        log.info("Checking receive on first server");
+//        assertNull(consumerSecondServer.receive(1000));
+//
+//    }
+//
+//    public void testTopicSubscriber() throws Exception
+//    {
+//        log.info("++testSimpleWithOneProducerTransacted");
+//
+//        log.info(">>Lookup Queue");
+//        Destination destination = (Destination)getCtx1().lookup("topic/testTopic");
+//
+//        JBossConnection connFirstServer = (JBossConnection)this.factoryServer1.createConnection();
+//        connFirstServer.start();
+//        JBossSession sessionFirstServer = (JBossSession)connFirstServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//
+//
+//        log.info("Creating connection server1");
+//        JBossConnection  conn = (JBossConnection)this.factoryServer1.createConnection();
+//        conn.start();
+//
+//        log.info("ConnectionCreated=" + conn);
+//        log.info(">>Creating Sessions");
+//
+//        JBossSession session = (JBossSession)conn.createSession(true,Session.AUTO_ACKNOWLEDGE);
+//        ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate)session.getDelegate();
+//        SessionState sessionState = (SessionState)clientSessionDelegate.getState();
+//        MessageConsumer consumerHA = session.createConsumer(destination);
+//        log.info(">>Creating Producer");
+//        MessageProducer producer = session.createProducer(destination);
+//        log.info(">>creating Message");
+//        Message message = session.createTextMessage("Hello Before");
+//        log.info(">>sending Message");
+//        producer.send(message);
+//        session.commit();
+//
+//        assertNotNull(consumerHA.receive(3000));
+//        session.commit();
+//
+//        Object txID = sessionState.getCurrentTxId();
+//
+//        producer.send(session.createTextMessage("Hello again before failover"));
+//
+//        ClientConnectionDelegate delegate = (ClientConnectionDelegate)conn.getDelegate();
+//
+//        JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
+//
+//        ConnectionState state = (ConnectionState)delegate.getState();
+//
+//        log.info(">>Creating alternate connection");
+//        JBossConnection conn2 = (JBossConnection)this.factoryServer2.createConnection();
+//        log.info("NewConnectionCreated=" + conn2);
+//
+//        log.info(">>Failling over");
+//        assertSame(originalRemoting,delegate.getRemotingConnection());
+//        conn.getDelegate().failOver(conn2.getDelegate());
+//
+//        try {
+//            originalRemoting.stop();
+//        } catch (Throwable throwable) {
+//            throwable.printStackTrace();
+//        }
+//
+//
+//        assertNotSame(originalRemoting,delegate.getRemotingConnection());
+//
+//        //System.out.println("Kill server1"); Thread.sleep(10000);
+//
+//        message = session.createTextMessage("Hello After");
+//        log.info(">>Sending new message");
+//        producer.send(message);
+//
+//        assertEquals(txID,sessionState.getCurrentTxId());
+//        System.out.println("TransactionID on client = " + txID);
+//        log.info(">>Final commit");
+//
+//        JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
+//        connSecondServer.start();
+//        JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//        MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination);
+//
+//        session.commit();
+//
+//        //assertNotNull(consumerSecondServer.receive(3000));
+//        assertNotNull(consumerSecondServer.receive(3000));
+//        assertNotNull(consumerSecondServer.receive(3000));
+//        assertNull(consumerSecondServer.receive(3000));
+//
+//        log.info("Calling alternate receiver");
+//        //assertNotNull(consumerHA.receive(1000));
+//        assertNotNull(consumerHA.receive(1000));
+//        assertNotNull(consumerHA.receive(1000));
+//        assertNull(consumerHA.receive(1000));
+//
+//    }
 }

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeTest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeTest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeTest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -21,18 +21,20 @@
   */
 package org.jboss.test.messaging.core.plugin.postoffice.cluster;
 
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+
 import org.jboss.messaging.core.FilterFactory;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.local.PagingFilteredQueue;
 import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
+import org.jboss.messaging.core.plugin.contract.FailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.Binding;
 import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
 import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
@@ -44,6 +46,8 @@
 import org.jboss.test.messaging.core.plugin.postoffice.DefaultPostOfficeTest;
 import org.jboss.test.messaging.util.CoreMessageFactory;
 
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
 /**
  * 
  * A DefaultClusteredPostOfficeTest
@@ -2240,13 +2244,15 @@
       
       ClusterRouterFactory rf = new DefaultRouterFactory();
       
+      FailoverMapper mapper = new DefaultFailoverMapper();
+      
       DefaultClusteredPostOffice postOffice = 
          new DefaultClusteredPostOffice(sc.getDataSource(), sc.getTransactionManager(),
                                  sc.getClusteredPostOfficeSQLProperties(), true, nodeId, "Clustered", ms, pm, tr, ff, pool,
                                  groupName,
                                  JGroupsUtil.getControlStackProperties(),
                                  JGroupsUtil.getDataStackProperties(),
-                                 5000, 5000, pullPolicy, rf, 1000);
+                                 5000, 5000, pullPolicy, rf, mapper, 1000);
       
       postOffice.start();      
       

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOfficeWithDefaultRouterTest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -25,9 +25,11 @@
 import java.util.List;
 import org.jboss.messaging.core.FilterFactory;
 import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
+import org.jboss.messaging.core.plugin.contract.FailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.Binding;
 import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
 import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
@@ -376,13 +378,15 @@
       
       ClusterRouterFactory rf = new DefaultRouterFactory();
       
+      FailoverMapper mapper = new DefaultFailoverMapper();
+      
       DefaultClusteredPostOffice postOffice = 
          new DefaultClusteredPostOffice(sc.getDataSource(), sc.getTransactionManager(),
                                  sc.getClusteredPostOfficeSQLProperties(), true, nodeId, "Clustered", ms, pm, tr, ff, pool,
                                  groupName,
                                  JGroupsUtil.getControlStackProperties(),
                                  JGroupsUtil.getDataStackProperties(),
-                                 5000, 5000, redistPolicy, rf, 1000);
+                                 5000, 5000, redistPolicy, rf, mapper, 1000);
       
       postOffice.start();      
       

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -34,10 +34,12 @@
 import org.jboss.messaging.core.Receiver;
 import org.jboss.messaging.core.SimpleDelivery;
 import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
+import org.jboss.messaging.core.plugin.contract.FailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouter;
 import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.ClusteredQueue;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouter;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
@@ -352,13 +354,15 @@
       
       ClusterRouterFactory rf = new DefaultRouterFactory();
       
+      FailoverMapper mapper = new DefaultFailoverMapper();
+      
       DefaultClusteredPostOffice postOffice = 
          new DefaultClusteredPostOffice(sc.getDataSource(), sc.getTransactionManager(),
                                  sc.getClusteredPostOfficeSQLProperties(), true, nodeId, "Clustered", ms, pm, tr, ff, pool,
                                  groupName,
                                  JGroupsUtil.getControlStackProperties(),
                                  JGroupsUtil.getDataStackProperties(),
-                                 5000, 5000, redistPolicy, rf, 1000);
+                                 5000, 5000, redistPolicy, rf, mapper, 1000);
       
       postOffice.start();      
       

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RecoveryTest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RecoveryTest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RecoveryTest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -27,9 +27,11 @@
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
+import org.jboss.messaging.core.plugin.contract.FailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.Binding;
 import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
 import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
@@ -353,13 +355,15 @@
       
       ClusterRouterFactory rf = new DefaultRouterFactory();
       
+      FailoverMapper mapper = new DefaultFailoverMapper();
+      
       DefaultClusteredPostOffice postOffice = 
          new DefaultClusteredPostOffice(sc.getDataSource(), sc.getTransactionManager(),
                                  sc.getClusteredPostOfficeSQLProperties(), true, nodeId, "Clustered", ms, pm, tr, ff, pool,
                                  groupName,
                                  JGroupsUtil.getControlStackProperties(),
                                  JGroupsUtil.getDataStackProperties(),
-                                 5000, 5000, redistPolicy, rf, 1000);
+                                 5000, 5000, redistPolicy, rf, mapper, 1000);
       
       postOffice.start();      
       

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -35,9 +35,11 @@
 import org.jboss.messaging.core.Receiver;
 import org.jboss.messaging.core.SimpleDelivery;
 import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
+import org.jboss.messaging.core.plugin.contract.FailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.Binding;
 import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultFailoverMapper;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultMessagePullPolicy;
 import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultRouterFactory;
 import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
@@ -1144,13 +1146,15 @@
       
       ClusterRouterFactory rf = new DefaultRouterFactory();
       
+      FailoverMapper mapper = new DefaultFailoverMapper();
+      
       DefaultClusteredPostOffice postOffice = 
          new DefaultClusteredPostOffice(sc.getDataSource(), sc.getTransactionManager(),
                                  sc.getClusteredPostOfficeSQLProperties(), true, nodeId, "Clustered", ms, pm, tr, ff, pool,
                                  groupName,
                                  JGroupsUtil.getControlStackProperties(),
                                  JGroupsUtil.getDataStackProperties(),
-                                 10000, 10000, pullPolicy, rf, 1000);
+                                 10000, 10000, pullPolicy, rf, mapper, 1000);
       
       postOffice.start();      
       

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/jms/clustering/HATest.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/jms/clustering/HATest.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/jms/clustering/HATest.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -62,205 +62,205 @@
    }
 
 
-   public void testTopicSubscriber() throws Exception
-   {
-      try
-      {
-         log.info("++testTopicSubscriber");
+//   public void testTopicSubscriber() throws Exception
+//   {
+//      try
+//      {
+//         log.info("++testTopicSubscriber");
+//
+//         log.info(">>Lookup Queue");
+//         Destination destination = (Destination) ic1.lookup("topic/testDistributedTopic");
+//
+//         log.info("Creating connection server1");
+//         JBossConnection conn = (JBossConnection) cf1.createConnection();
+//         conn.setClientID("testClient");
+//         conn.start();
+//
+//         JBossSession session = (JBossSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
+//         ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate) session.getDelegate();
+//         SessionState sessionState = (SessionState) clientSessionDelegate.getState();
+//
+//         MessageConsumer consumerHA = session.createDurableSubscriber((Topic) destination, "T1");
+//         JBossMessageConsumer jbossConsumerHA = (JBossMessageConsumer) consumerHA;
+//
+//         org.jboss.jms.client.delegate.ClientConsumerDelegate clientDelegate = (org.jboss.jms.client.delegate.ClientConsumerDelegate) jbossConsumerHA.getDelegate();
+//         ConsumerState consumerState = (ConsumerState) clientDelegate.getState();
+//
+//         log.info("subscriptionName=" + consumerState.getSubscriptionName());
+//
+//
+//         log.info(">>Creating Producer");
+//         MessageProducer producer = session.createProducer(destination);
+//         log.info(">>creating Message");
+//         Message message = session.createTextMessage("Hello Before");
+//         log.info(">>sending Message");
+//         producer.send(message);
+//         session.commit();
+//
+//         receiveMessage("consumerHA", consumerHA, true, false);
+//
+//         session.commit();
+//         //if (true) return;
+//
+//         Object txID = sessionState.getCurrentTxId();
+//
+//         producer.send(session.createTextMessage("Hello again before failover"));
+//
+//         ClientConnectionDelegate delegate = (ClientConnectionDelegate) conn.getDelegate();
+//
+//         JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
+//
+//         log.info(">>Creating alternate connection");
+//         JBossConnection conn2 = (JBossConnection) cf2.createConnection();
+//         log.info("NewConnectionCreated=" + conn2);
+//
+//         log.info(">>Failling over");
+//         assertSame(originalRemoting, delegate.getRemotingConnection());
+//         conn.getDelegate().failOver(conn2.getDelegate());
+//
+//
+//
+//         try
+//         {
+//            originalRemoting.stop();
+//         } catch (Throwable throwable)
+//         {
+//            throwable.printStackTrace();
+//         }
+//
+//         ServerManagement.stop(0, false);
+//
+//         assertNotSame(originalRemoting, delegate.getRemotingConnection());
+//
+//         //System.out.println("Kill server1"); Thread.sleep(10000);
+//
+//         message = session.createTextMessage("Hello After");
+//         log.info(">>Sending new message");
+//         producer.send(message);
+//
+//         assertEquals(txID, sessionState.getCurrentTxId());
+//         System.out.println("TransactionID on client = " + txID);
+//         log.info(">>Final commit");
+//
+//         /* JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
+//          connSecondServer.start();
+//          JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
+//          MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination); */
+//
+//         session.commit();
+//
+//         /* receiveMessage("consumerSecondServer",consumerSecondServer,true,false);
+//        receiveMessage("consumerSecondServer",consumerSecondServer,true,false);
+//        receiveMessage("consumerSecondServer",consumerSecondServer,true,true); */
+//
+//         log.info("Calling alternate receiver");
+//         receiveMessage("consumerHA", consumerHA, true, false);
+//         receiveMessage("consumerHA", consumerHA, true, false);
+//         receiveMessage("consumerHA", consumerHA, true, true);
+//
+//
+//         session.commit();
+//
+//      }
+//      finally
+//      {
+//         // restart the server as it was probably stopped (tearDown will need that)
+//         ServerManagement.start("all", 0, true);
+//      }
+//   }
+//
+//   public void testQueueHA() throws Exception
+//   {
+//      log.info("++testTopicSubscriber");
+//
+//      log.info(">>Lookup Queue");
+//      Destination destination = (Destination) ic1.lookup("queue/testDistributedQueue");
+//
+//      log.info("Creating connection server1");
+//      JBossConnection conn = (JBossConnection) cf1.createConnection();
+//      conn.setClientID("testClient");
+//      conn.start();
+//
+//      JBossSession session = (JBossSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
+//      ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate) session.getDelegate();
+//      SessionState sessionState = (SessionState) clientSessionDelegate.getState();
+//
+//      MessageConsumer consumerHA = session.createConsumer(destination);
+//      JBossMessageConsumer jbossConsumerHA = (JBossMessageConsumer) consumerHA;
+//
+//      org.jboss.jms.client.delegate.ClientConsumerDelegate clientDelegate = (org.jboss.jms.client.delegate.ClientConsumerDelegate) jbossConsumerHA.getDelegate();
+//      ConsumerState consumerState = (ConsumerState) clientDelegate.getState();
+//
+//      log.info("subscriptionName=" + consumerState.getSubscriptionName());
+//
+//
+//      log.info(">>Creating Producer");
+//      MessageProducer producer = session.createProducer(destination);
+//      log.info(">>creating Message");
+//      Message message = session.createTextMessage("Hello Before");
+//      log.info(">>sending Message");
+//      producer.send(message);
+//      session.commit();
+//
+//      session.commit();
+//      //if (true) return;
+//
+//      Object txID = sessionState.getCurrentTxId();
+//
+//      ClientConnectionDelegate delegate = (ClientConnectionDelegate) conn.getDelegate();
+//
+//      JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
+//
+//      log.info(">>Creating alternate connection");
+//      JBossConnection conn2 = (JBossConnection) cf2.createConnection();
+//      log.info("NewConnectionCreated=" + conn2);
+//
+//      log.info(">>Failling over");
+//      assertSame(originalRemoting, delegate.getRemotingConnection());
+//      conn.getDelegate().failOver(conn2.getDelegate());
+//
+//      try
+//      {
+//         originalRemoting.stop();
+//      } catch (Throwable throwable)
+//      {
+//         throwable.printStackTrace();
+//      }
+//
+//
+//      assertNotSame(originalRemoting, delegate.getRemotingConnection());
+//
+//      //System.out.println("Kill server1"); Thread.sleep(10000);
+//      assertEquals(txID, sessionState.getCurrentTxId());
+//      System.out.println("TransactionID on client = " + txID);
+//      log.info(">>Final commit");
+//
+//      session.commit();
+//
+//      log.info("Calling alternate receiver");
+//      receiveMessage("consumerHA", consumerHA, true, false);
+//      receiveMessage("consumerHA", consumerHA, true, true);
+//
+//      session.commit();
+//
+//      for (int i = 0; i < 30; i++)
+//      {
+//         log.info("Message Sent " + i);
+//         producer.send(session.createTextMessage("Message " + i));
+//      }
+//      session.commit();
+//
+//      Thread.sleep(5000);
+//
+//      TextMessage messageLoop = null;
+//      while (!((messageLoop = (TextMessage) consumerHA.receive(5000)) == null))
+//      {
+//         log.info("Message received = " + messageLoop.getText());
+//      }
+//
+//   }
 
-         log.info(">>Lookup Queue");
-         Destination destination = (Destination) ic1.lookup("topic/testDistributedTopic");
 
-         log.info("Creating connection server1");
-         JBossConnection conn = (JBossConnection) cf1.createConnection();
-         conn.setClientID("testClient");
-         conn.start();
-
-         JBossSession session = (JBossSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
-         ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate) session.getDelegate();
-         SessionState sessionState = (SessionState) clientSessionDelegate.getState();
-
-         MessageConsumer consumerHA = session.createDurableSubscriber((Topic) destination, "T1");
-         JBossMessageConsumer jbossConsumerHA = (JBossMessageConsumer) consumerHA;
-
-         org.jboss.jms.client.delegate.ClientConsumerDelegate clientDelegate = (org.jboss.jms.client.delegate.ClientConsumerDelegate) jbossConsumerHA.getDelegate();
-         ConsumerState consumerState = (ConsumerState) clientDelegate.getState();
-
-         log.info("subscriptionName=" + consumerState.getSubscriptionName());
-
-
-         log.info(">>Creating Producer");
-         MessageProducer producer = session.createProducer(destination);
-         log.info(">>creating Message");
-         Message message = session.createTextMessage("Hello Before");
-         log.info(">>sending Message");
-         producer.send(message);
-         session.commit();
-
-         receiveMessage("consumerHA", consumerHA, true, false);
-
-         session.commit();
-         //if (true) return;
-
-         Object txID = sessionState.getCurrentTxId();
-
-         producer.send(session.createTextMessage("Hello again before failover"));
-
-         ClientConnectionDelegate delegate = (ClientConnectionDelegate) conn.getDelegate();
-
-         JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
-
-         log.info(">>Creating alternate connection");
-         JBossConnection conn2 = (JBossConnection) cf2.createConnection();
-         log.info("NewConnectionCreated=" + conn2);
-
-         log.info(">>Failling over");
-         assertSame(originalRemoting, delegate.getRemotingConnection());
-         conn.getDelegate().failOver(conn2.getDelegate());
-
-
-
-         try
-         {
-            originalRemoting.stop();
-         } catch (Throwable throwable)
-         {
-            throwable.printStackTrace();
-         }
-
-         ServerManagement.stop(0, false);
-
-         assertNotSame(originalRemoting, delegate.getRemotingConnection());
-
-         //System.out.println("Kill server1"); Thread.sleep(10000);
-
-         message = session.createTextMessage("Hello After");
-         log.info(">>Sending new message");
-         producer.send(message);
-
-         assertEquals(txID, sessionState.getCurrentTxId());
-         System.out.println("TransactionID on client = " + txID);
-         log.info(">>Final commit");
-
-         /* JBossConnection connSecondServer = (JBossConnection)this.factoryServer2.createConnection();
-          connSecondServer.start();
-          JBossSession sessionSecondServer = (JBossSession)connSecondServer.createSession(false,Session.AUTO_ACKNOWLEDGE);
-          MessageConsumer consumerSecondServer = sessionSecondServer.createConsumer(destination); */
-
-         session.commit();
-
-         /* receiveMessage("consumerSecondServer",consumerSecondServer,true,false);
-        receiveMessage("consumerSecondServer",consumerSecondServer,true,false);
-        receiveMessage("consumerSecondServer",consumerSecondServer,true,true); */
-
-         log.info("Calling alternate receiver");
-         receiveMessage("consumerHA", consumerHA, true, false);
-         receiveMessage("consumerHA", consumerHA, true, false);
-         receiveMessage("consumerHA", consumerHA, true, true);
-
-
-         session.commit();
-
-      }
-      finally
-      {
-         // restart the server as it was probably stopped (tearDown will need that)
-         ServerManagement.start("all", 0, true);
-      }
-   }
-
-   public void testQueueHA() throws Exception
-   {
-      log.info("++testTopicSubscriber");
-
-      log.info(">>Lookup Queue");
-      Destination destination = (Destination) ic1.lookup("queue/testDistributedQueue");
-
-      log.info("Creating connection server1");
-      JBossConnection conn = (JBossConnection) cf1.createConnection();
-      conn.setClientID("testClient");
-      conn.start();
-
-      JBossSession session = (JBossSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
-      ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate) session.getDelegate();
-      SessionState sessionState = (SessionState) clientSessionDelegate.getState();
-
-      MessageConsumer consumerHA = session.createConsumer(destination);
-      JBossMessageConsumer jbossConsumerHA = (JBossMessageConsumer) consumerHA;
-
-      org.jboss.jms.client.delegate.ClientConsumerDelegate clientDelegate = (org.jboss.jms.client.delegate.ClientConsumerDelegate) jbossConsumerHA.getDelegate();
-      ConsumerState consumerState = (ConsumerState) clientDelegate.getState();
-
-      log.info("subscriptionName=" + consumerState.getSubscriptionName());
-
-
-      log.info(">>Creating Producer");
-      MessageProducer producer = session.createProducer(destination);
-      log.info(">>creating Message");
-      Message message = session.createTextMessage("Hello Before");
-      log.info(">>sending Message");
-      producer.send(message);
-      session.commit();
-
-      session.commit();
-      //if (true) return;
-
-      Object txID = sessionState.getCurrentTxId();
-
-      ClientConnectionDelegate delegate = (ClientConnectionDelegate) conn.getDelegate();
-
-      JMSRemotingConnection originalRemoting = delegate.getRemotingConnection();
-
-      log.info(">>Creating alternate connection");
-      JBossConnection conn2 = (JBossConnection) cf2.createConnection();
-      log.info("NewConnectionCreated=" + conn2);
-
-      log.info(">>Failling over");
-      assertSame(originalRemoting, delegate.getRemotingConnection());
-      conn.getDelegate().failOver(conn2.getDelegate());
-
-      try
-      {
-         originalRemoting.stop();
-      } catch (Throwable throwable)
-      {
-         throwable.printStackTrace();
-      }
-
-
-      assertNotSame(originalRemoting, delegate.getRemotingConnection());
-
-      //System.out.println("Kill server1"); Thread.sleep(10000);
-      assertEquals(txID, sessionState.getCurrentTxId());
-      System.out.println("TransactionID on client = " + txID);
-      log.info(">>Final commit");
-
-      session.commit();
-
-      log.info("Calling alternate receiver");
-      receiveMessage("consumerHA", consumerHA, true, false);
-      receiveMessage("consumerHA", consumerHA, true, true);
-
-      session.commit();
-
-      for (int i = 0; i < 30; i++)
-      {
-         log.info("Message Sent " + i);
-         producer.send(session.createTextMessage("Message " + i));
-      }
-      session.commit();
-
-      Thread.sleep(5000);
-
-      TextMessage messageLoop = null;
-      while (!((messageLoop = (TextMessage) consumerHA.receive(5000)) == null))
-      {
-         log.info("Message received = " + messageLoop.getText());
-      }
-
-   }
-
-
    private void receiveMessage(String text, MessageConsumer consumer, boolean shouldAssert, boolean shouldBeNull) throws Exception
    {
       MessageProxy message = (MessageProxy) consumer.receive(3000);

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -833,7 +833,8 @@
       log.info("getNumberOfNodesOnCluster being called:: sc=" + sc);
       DefaultClusteredPostOffice postOffice = (DefaultClusteredPostOffice)
             sc.getAttribute(queuePostOfficeObjectName, "Instance");
-      return postOffice.getClusterNodes().length;
+      
+      return postOffice.getNumberOfNodesInCluster();
    }
 
    // Public --------------------------------------------------------

Modified: branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java
===================================================================
--- branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java	2006-11-30 08:15:30 UTC (rev 1662)
+++ branches/Branch_Client_Failover_Experiment/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java	2006-11-30 15:27:59 UTC (rev 1663)
@@ -378,7 +378,6 @@
       return server.getUserTransaction();
    }
 
-
    public int getNumberOfNodesOnCluster() throws Exception
    {
       return server.getNumberOfNodesOnCluster();




More information about the jboss-cvs-commits mailing list