[jboss-cvs] JBossAS SVN: r78432 - in branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158: cluster/src/main/org/jboss/invocation/jrmp/interfaces and 6 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Sep 11 11:15:59 EDT 2008


Author: galder.zamarreno at jboss.com
Date: 2008-09-11 11:15:58 -0400 (Thu, 11 Sep 2008)
New Revision: 78432

Modified:
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/ha/framework/interfaces/TransactionSticky.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/invocation/jrmp/interfaces/JRMPInvokerProxyHA.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/invocation/unified/interfaces/UnifiedInvokerHAProxy.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/proxy/ejb/RetryInterceptor.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ClientUserTransaction.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ClientUserTransactionObjectFactory.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ServerVMClientUserTransaction.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/server/UserTransactionSessionImpl.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaTransactionSticky.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaMockUtils.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaTransactionStickyUnitTestCase.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaUnitTestCase.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaTransactionStickyUnitTestCase.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java
   branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/transaction/src/main/org/jboss/tm/TransactionPropagationContextUtil.java
Log:
[JBPAPP-1158] Fix several issues that could cause transaction sticky functionality not to work properly. See individual JIRAs for further details about the changes.

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/ha/framework/interfaces/TransactionSticky.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/ha/framework/interfaces/TransactionSticky.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/ha/framework/interfaces/TransactionSticky.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -49,7 +49,7 @@
       
       if (trace)
       {
-         log.trace("transaction sticky load balance policy delegates to: " + delegateLoadBalancePolicy);
+         log.trace("Transaction sticky load balance policy delegates to: " + delegateLoadBalancePolicy);
       }
    }
 
@@ -66,11 +66,11 @@
    {
       trace = log.isTraceEnabled();
       Object txStickyTarget = routingDecision.getTransientValue("TX_STICKY_TARGET");
-      if (txStickyTarget != null && clusterFamily.getTargets().contains(txStickyTarget))
+      if (txStickyTarget != null)
       {
          if (trace) 
          {
-            log.trace("transaction bound target exists: " + txStickyTarget);
+            log.trace("Transaction bound target exists: " + txStickyTarget);
          } 
          
          return txStickyTarget;
@@ -102,7 +102,7 @@
       
       if (trace) 
       {
-         log.trace("new target chosen: " + newTarget);
+         log.trace("New target chosen: " + newTarget);
       }
       
       invocation.getTransientPayload().put("TX_STICKY_TARGET", newTarget);

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/invocation/jrmp/interfaces/JRMPInvokerProxyHA.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/invocation/jrmp/interfaces/JRMPInvokerProxyHA.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/invocation/jrmp/interfaces/JRMPInvokerProxyHA.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -138,11 +138,24 @@
          {
             if (trace)
             {
-               log.trace("checking tx failover authorisation map with tpc " + tpc);
+               log.trace("Checking tx failover authorisation map with tpc " + tpc);
             }
             
-            /* if the map contains the tpc, then we can't allow a failover */
-            return ! txFailoverAuthorizations.containsKey (tpc);               
+            /* If the map contains the tpc, then we can't allow a failover */
+            boolean failoverAuthorised = ! txFailoverAuthorizations.containsKey(tpc);
+            
+            if (failoverAuthorised)
+            {
+               if (trace) 
+               {
+                  log.trace("Failover authorised, so we remove the sticky target associated with tpc " + tpc);
+               }
+               
+               txFailoverAuthorizations.put(tpc, null);
+               invocation.getTransientPayload().put("TX_STICKY_TARGET", null);
+            }
+            
+            return failoverAuthorised;     
          }
       }
       else
@@ -160,14 +173,14 @@
          {
             if (trace)
             {
-               log.trace("after reaching the server, transaction propagation context (tpc) is " + tpc);
+               log.trace("After reaching the server, transaction propagation context (tpc) is " + tpc);
             }
             
             Object stickyTarget = invocation.getTransientValue("TX_STICKY_TARGET");
             
             if (trace && stickyTarget != null)
             {
-               log.trace("remember transaction bound target[" + stickyTarget + "] for tpc[" + tpc + "]");
+               log.trace("Remember transaction bound target[" + stickyTarget + "] for tpc[" + tpc + "]");
             }
             
             txFailoverAuthorizations.put(tpc, stickyTarget);
@@ -398,7 +411,7 @@
     * target associated to it and add it to the invocation transient payload so 
     * that the load balance policy can choose the right target.
     */
-   protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc)
+   protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc) throws GenericClusteringException
    {
       if (tpc != null)
       {
@@ -406,19 +419,27 @@
          {
             if (trace)
             {
-               log.trace("in the proxy, transaction propagation context (tpc) is " + tpc);
+               log.trace("In the proxy, transaction propagation context (tpc) is " + tpc);
             }
 
             Object stickyTarget = txFailoverAuthorizations.get(tpc);
                
             if (stickyTarget != null)
             {
-               if (trace)
+               if (familyClusterInfo.getTargets().contains(stickyTarget))
                {
-                  log.trace("put transaction bound target [" + stickyTarget + "] into transient payload");
+                  if (trace) 
+                  {
+                     log.trace("Put transaction bound target into transient payload: " + stickyTarget);                  
+                  }
+                  
+                  invocation.getTransientPayload().put("TX_STICKY_TARGET", stickyTarget);                  
                }
-               
-               invocation.getTransientPayload().put("TX_STICKY_TARGET", stickyTarget);
+               else
+               {
+                  throw new GenericClusteringException(GenericClusteringException.COMPLETED_YES, 
+                     "Transaction sticky target is no longer available, so invocation needs to be halted");
+               }
             }
          }
       }

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/invocation/unified/interfaces/UnifiedInvokerHAProxy.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/invocation/unified/interfaces/UnifiedInvokerHAProxy.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/cluster/src/main/org/jboss/invocation/unified/interfaces/UnifiedInvokerHAProxy.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -30,7 +30,9 @@
 import java.rmi.RemoteException;
 import java.rmi.ServerException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.WeakHashMap;
 import org.jboss.ha.framework.interfaces.ClusteringTargetsRepository;
 import org.jboss.ha.framework.interfaces.FamilyClusterInfo;
@@ -67,7 +69,7 @@
 
    private FamilyClusterInfo familyClusterInfo = null;
 
-   public static final WeakHashMap txFailoverAuthorizations = new WeakHashMap();
+   public static final Map txFailoverAuthorizations = Collections.synchronizedMap(new WeakHashMap());
 
    /** Trace level logging flag only set when the proxy is created or read from JNDI */
    private static boolean trace = false;
@@ -104,15 +106,31 @@
       Object tpc = getTransactionPropagationContext();
       if(tpc != null)
       {
+         if (trace)
+         {
+            log.trace("Checking tx failover authorisation map with tpc " + tpc);
+         }
+
+         /* Synchronise on tpc because we're updating the map if it doesn't 
+          * contain tpc upon failover (putIfAbsent type of operation). This is 
+          * still needed even if the collection is synchronized. */
          synchronized(tpc)
          {
-            if (trace)
+            /* If the map contains the tpc, then we can't allow a failover */
+            boolean failoverAuthorised = ! txFailoverAuthorizations.containsKey(tpc);
+            
+            if (failoverAuthorised)
             {
-               log.trace("checking tx failover authorisation map with tpc " + tpc);
+               if (trace) 
+               {
+                  log.trace("Failover authorised, so we remove the sticky target associated with tpc " + tpc);
+               }
+               
+               txFailoverAuthorizations.put(tpc, null);
+               invocation.getTransientPayload().put("TX_STICKY_TARGET", null);
             }
-
-            /* if the map contains the tpc, then we can't allow a failover */
-            return ! txFailoverAuthorizations.containsKey(tpc);
+            
+            return failoverAuthorised;         
          }
       }
       
@@ -124,22 +142,19 @@
       Object tpc = getTransactionPropagationContext();
       if(tpc != null)
       {
-         synchronized(tpc)
+         if (trace)
          {
-            if (trace)
-            {
-               log.trace("after reaching the server, transaction propagation context (tpc) is " + tpc);
-            }
-            
-            Object stickyTarget = invocation.getTransientValue("TX_STICKY_TARGET");
-            
-            if (trace && stickyTarget != null)
-            {
-               log.trace("remember transaction bound target[" + stickyTarget + "] for tpc[" + tpc + "]");
-            }
-            
-            txFailoverAuthorizations.put(tpc, stickyTarget);
+            log.trace("After reaching the server, transaction propagation context (tpc) is " + tpc);
          }
+         
+         Object stickyTarget = invocation.getTransientValue("TX_STICKY_TARGET");
+         
+         if (trace && stickyTarget != null)
+         {
+            log.trace("Remember transaction bound target[" + stickyTarget + "] for tpc[" + tpc + "]");
+         }
+         
+         txFailoverAuthorizations.put(tpc, stickyTarget);
       }
    }
 
@@ -195,9 +210,6 @@
       //
       int failoverCounter = 0;
       invocation.setValue("FAILOVER_COUNTER", new Integer(failoverCounter), PayloadKey.AS_IS);
-
-      // If transaction sticky, put chosen target
-      putIfExistsTransactionTarget(invocation, getTransactionPropagationContext());      
       
       Object response = null;
       Exception lastException = null;
@@ -217,6 +229,9 @@
                log.trace(printPossibleTargets());
             }
 
+            // If transaction sticky, put chosen target
+            putIfExistsTransactionTarget(invocation, getTransactionPropagationContext());      
+
             Client clientInstance = getClient(invocation);
 
             if (trace)
@@ -529,6 +544,10 @@
    protected Object getTransactionPropagationContext()
    {
       TransactionPropagationContextFactory tpcFactory = TransactionPropagationContextUtil.getTPCFactoryClientSide();
+      if (trace)
+      {
+         log.trace("Using tpc factory " + tpcFactory);
+      }      
       return (tpcFactory == null) ? null : tpcFactory.getTransactionPropagationContext();
    }
    
@@ -536,30 +555,39 @@
     * Called at the beginning of the invocation to check whether the current tpc
     * is already present in the tx failover map. If it is, get the chosen 
     * target associated to it and add it to the invocation transient payload so 
-    * that the load balance policy can choose the right target.
+    * that the load balance policy can choose the right target  as long as the 
+    * target is available in the cluster family. Otherwise, invocation needs to 
+    * be halted because a previous invocation within the transaction succeeded 
+    * (tx sticky target was set), so we can't failover to a different node.
     */
-   protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc)
+   protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc) throws GenericClusteringException
    {
       if (tpc != null)
       {
-         synchronized (tpc)
+         if (trace)
          {
-            if (trace)
-            {
-               log.trace("in the proxy, transaction propagation context (tpc) is " + tpc);
-            }
+            log.trace("In the proxy, transaction propagation context (tpc) is " + tpc);
+            log.trace("Contains key returns " + txFailoverAuthorizations.containsKey(tpc));
+         }
 
-            Object stickyTarget = txFailoverAuthorizations.get(tpc);
-               
-            if (stickyTarget != null)
+         Object stickyTarget = txFailoverAuthorizations.get(tpc);
+            
+         if (stickyTarget != null)
+         {
+            if (familyClusterInfo.getTargets().contains(stickyTarget))
             {
-               if (trace)
+               if (trace) 
                {
-                  log.trace("put transaction bound target [" + stickyTarget + "] into transient payload");
+                  log.trace("Put transaction bound target into transient payload: " + stickyTarget);                  
                }
                
-               invocation.getTransientPayload().put("TX_STICKY_TARGET", stickyTarget);
+               invocation.getTransientPayload().put("TX_STICKY_TARGET", stickyTarget);                  
             }
+            else
+            {
+               throw new GenericClusteringException(GenericClusteringException.COMPLETED_YES, 
+                  "Transaction sticky target is no longer available, so invocation needs to be halted");
+            }
          }
       }
    }

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/proxy/ejb/RetryInterceptor.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/proxy/ejb/RetryInterceptor.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/proxy/ejb/RetryInterceptor.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -27,6 +27,7 @@
 import java.util.Hashtable;
 import java.util.Properties;
 import javax.naming.InitialContext;
+import javax.naming.NamingException;
 
 import org.jboss.invocation.Invocation;
 import org.jboss.invocation.InvocationContext;
@@ -238,10 +239,12 @@
       Invoker newInvoker = null;
       while( retry == true )
       {
+         InitialContext namingCtx = null;
+         
          try
          {
             Thread.sleep(sleepTime);
-            InitialContext namingCtx = new InitialContext(retryProps);
+            namingCtx = new InitialContext(retryProps);
             if( trace )
                log.trace("Looking for invoker: "+jndiName);
             newInvoker = (Invoker) namingCtx.lookup(jndiName);
@@ -263,6 +266,22 @@
                break;
             }
          }
+         finally
+         {
+            // JBAS-5906 -- clean up after ourselves
+            if (namingCtx != null)
+            {
+               try
+               {
+                  namingCtx.close();
+               }
+               catch (NamingException e)
+               {
+                  log.warn("Problem closing naming context used for reaquiring invoker: " + 
+                        e.getClass() + " -- " + e.getLocalizedMessage());
+               }
+            }
+         }
       }
       if( trace )
          log.trace("End reestablishInvokerProxy");

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ClientUserTransaction.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ClientUserTransaction.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ClientUserTransaction.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -46,6 +46,7 @@
 
 import org.jboss.tm.usertx.interfaces.UserTransactionSession;
 import org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory;
+import org.jboss.logging.Logger;
 import org.jboss.naming.NamingContextFactory;
 
 /**
@@ -60,6 +61,7 @@
  * here.
  * @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
  * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  * @version $Revision$
  */
 public class ClientUserTransaction
@@ -75,15 +77,17 @@
    /**
     * Our singleton instance.
     */
-   private static ClientUserTransaction singleton = null;
+   private static ClientUserTransaction singleton = new ClientUserTransaction();
+   
+   private static final Logger log = Logger.getLogger(ClientUserTransaction.class);
 
+   private static boolean trace = log.isTraceEnabled();   
+   
    /**
     * Return a reference to the singleton instance.
     */
    public static ClientUserTransaction getSingleton()
    {
-      if (singleton == null)
-         singleton = new ClientUserTransaction();
       return singleton;
    }
 
@@ -397,6 +401,12 @@
          ret = new ThreadInfo();
          threadInfo.set(ret);
       }
+      
+      if (trace)
+      {
+         log.trace("Thread local: " + threadInfo); 
+         log.trace("Thread info holder: " + ret);
+      }
 
       return ret;
    }
@@ -430,6 +440,11 @@
       protected void finalize()
          throws Throwable
       {
+         if (trace)
+         {
+            log.trace("Tpc stack: finalize " + this);
+         }
+         
          try
          {
             while (!tpcStack.isEmpty())
@@ -460,6 +475,11 @@
       void push(Object tpc)
       {
          tpcStack.addLast(tpc);
+         trace = log.isTraceEnabled(); // Only check for trace enabled once per transaction
+         if (trace)
+         {
+            log.trace("Tpc stack: added " + this + " tpc=" + tpc);
+         }         
       }
 
       /**
@@ -467,7 +487,11 @@
        */
       void pop()
       {
-         tpcStack.removeLast();
+         Object tpc = tpcStack.removeLast();
+         if (trace)
+         {
+            log.trace("Tpc stack: removed " + this + " tpc=" + tpc);
+         }
       }
 
       /**
@@ -475,7 +499,12 @@
        */
       Object getTpc()
       {
-         return (tpcStack.isEmpty()) ? null : tpcStack.getLast();
+         Object tpc = (tpcStack.isEmpty()) ? null : tpcStack.getLast();
+         if (trace)
+         {
+            log.trace("Tpc stack: peek " + this + " tpc=" + tpc);
+         }
+         return tpc;
       }
 
       /**

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ClientUserTransactionObjectFactory.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ClientUserTransactionObjectFactory.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ClientUserTransactionObjectFactory.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -26,10 +26,8 @@
 import java.util.Hashtable;
 
 import javax.naming.Context;
-import javax.naming.InitialContext;
 import javax.naming.Reference;
 import javax.naming.Name;
-import javax.naming.NamingException;
 import javax.naming.spi.ObjectFactory;
 
 import javax.transaction.UserTransaction;
@@ -40,41 +38,31 @@
  *  usage for standalone clients.
  *      
  *  @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
+ *  @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  *  @version $Revision$
  */
 public class ClientUserTransactionObjectFactory
    implements ObjectFactory
 {
    /**
-    *  The <code>UserTransaction</code> this factory will return.
-    *  This is evaluated lazily in {@link #getUserTransaction()}.
-    */
-   static private UserTransaction userTransaction = null;
-
-   /**
     *  Get the <code>UserTransaction</code> this factory will return.
     *  This may return a cached value from a previous call.
     */
    static private UserTransaction getUserTransaction()
    {
-      if (userTransaction == null) {
-         // See if we have a local TM
-         try {
-            new InitialContext().lookup("java:/TransactionManager");
-
-            // We execute in the server.
-            userTransaction = ServerVMClientUserTransaction.getSingleton();
-         } catch (NamingException ex) {
-            // We execute in a stand-alone client.
-            ClientUserTransaction cut = ClientUserTransaction.getSingleton();
-
-            // Tell the proxy that this is the factory for
-            // transaction propagation contexts.
-            TransactionPropagationContextUtil.setTPCFactory(cut);
-            userTransaction = cut;
-         }
+      UserTransaction userTransaction = null;
+      ServerVMClientUserTransaction serverUserTransaction = ServerVMClientUserTransaction.getSingleton();
+      if (serverUserTransaction.isServer())
+      {
+         userTransaction = serverUserTransaction;
       }
-      return userTransaction;
+      else
+      {
+         ClientUserTransaction cut = ClientUserTransaction.getSingleton();
+         TransactionPropagationContextUtil.setTPCFactory(cut);
+         userTransaction = cut;
+      }
+      return userTransaction;    
    }
 
    public Object getObjectInstance(Object obj, Name name,

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ServerVMClientUserTransaction.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ServerVMClientUserTransaction.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/client/ServerVMClientUserTransaction.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -46,6 +46,7 @@
  *  <code>TransactionManager</code> of the server.
  *
  *  @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
+ *  @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  *  @version $Revision$
  */
 public class ServerVMClientUserTransaction
@@ -102,6 +103,11 @@
 
    // Public --------------------------------------------------------
 
+   public boolean isServer()
+   {
+       return tm != null;
+   }   
+   
    //Registration for TransactionStartedListeners.
 
    public void registerTxStartedListener(UserTransactionStartedListener txStartedListener)

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/server/UserTransactionSessionImpl.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/server/UserTransactionSessionImpl.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/server/src/main/org/jboss/tm/usertx/server/UserTransactionSessionImpl.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -22,7 +22,9 @@
 package org.jboss.tm.usertx.server;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.Map;
 
 import java.rmi.RemoteException;
 
@@ -49,6 +51,7 @@
  *  It handles transactions on behalf of a single client.
  * @author Ole Husgaard
  * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  * @version $Revision$
  */
 public class UserTransactionSessionImpl
@@ -60,7 +63,7 @@
    /**
     *  Maps the TPCs of all active transactions to their transactions.
     */
-   private static WeakValueHashMap activeTx = new WeakValueHashMap();
+   private static Map activeTx = Collections.synchronizedMap(new WeakValueHashMap());
    private static UserTransactionSessionImpl instance = new UserTransactionSessionImpl();
 
    public static UserTransactionSession getInstance()
@@ -71,7 +74,7 @@
    /**
     *  Get a reference to the transaction manager.
     */
-   protected static TransactionManager getTransactionManager()
+   protected synchronized static TransactionManager getTransactionManager()
    {
       if (tm == null)
       {
@@ -89,17 +92,13 @@
    }
 
    /** Cache a reference to the TPC Factory. */
-   private static TransactionPropagationContextFactory tpcFactory = null;
+   private static TransactionPropagationContextFactory tpcFactory = TransactionPropagationContextUtil.getTPCFactory();
    
    /**
     *  Get a reference to the TPC Factory
     */
    protected static TransactionPropagationContextFactory getTPCFactory()
    {
-      if (tpcFactory == null)
-      {
-         tpcFactory = TransactionPropagationContextUtil.getTPCFactory();
-      }
       return tpcFactory;
    }  
 
@@ -165,20 +164,16 @@
       TransactionManager tm = getTransactionManager();
       tm.resume(tx);
 
-      boolean finished = true;
-      
       try
       {
          tm.commit();
       }
       catch (java.lang.SecurityException ex)
       {
-         finished = false;
          throw ex;
       }
       catch (java.lang.IllegalStateException ex)
       {
-         finished = false;
          throw ex;
       }
       finally
@@ -259,25 +254,28 @@
    {
       log.debug("Lost connection to UserTransaction client.");
       
-      if (!activeTx.isEmpty())
+      synchronized (activeTx)
       {
-         log.error("Lost connection to UserTransaction clients: " +
-         "Rolling back " + activeTx.size() +
-         " active transaction(s).");
-         Collection txs = activeTx.values();
-         Iterator iter = txs.iterator();
-         while (iter.hasNext())
+         if (!activeTx.isEmpty())
          {
-            Transaction tx = (Transaction)iter.next();
-            try
+            log.error("Lost connection to UserTransaction clients: " +
+            "Rolling back " + activeTx.size() +
+            " active transaction(s).");
+            Collection txs = activeTx.values();
+            Iterator iter = txs.iterator();
+            while (iter.hasNext())
             {
-               tx.rollback();
+               Transaction tx = (Transaction)iter.next();
+               try
+               {
+                  tx.rollback();
+               }
+               catch (Exception ex)
+               {
+                  log.error("rollback failed", ex);
+               }
             }
-            catch (Exception ex)
-            {
-               log.error("rollback failed", ex);
-            }
-         }
+         }         
       }
    }
    

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaTransactionSticky.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaTransactionSticky.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaTransactionSticky.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -22,17 +22,21 @@
 package org.jboss.test.cluster.invokerha;
 
 import java.rmi.server.UID;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import javax.transaction.Transaction;
 
+import org.jboss.ha.framework.interfaces.GenericClusteringException;
 import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
 import org.jboss.ha.framework.interfaces.TransactionStickyFirstAvailable;
 import org.jboss.ha.framework.interfaces.TransactionStickyFirstAvailableIdenticalAllProxies;
 import org.jboss.ha.framework.interfaces.TransactionStickyRandomRobin;
 import org.jboss.ha.framework.interfaces.TransactionStickyRoundRobin;
 import org.jboss.invocation.Invocation;
+import org.jboss.invocation.InvokerProxyHA;
 import org.jboss.logging.Logger;
 import org.jboss.test.cluster.invokerha.InvokerHaTransactionalMockUtils.MockTransaction;
 
@@ -41,7 +45,7 @@
  * 
  * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  */
-public class AbstractInvokerHaTransactionSticky extends AbstractInvokerHa
+public abstract class AbstractInvokerHaTransactionSticky extends AbstractInvokerHa
 {
    private static final Logger log = Logger.getLogger(AbstractInvokerHaTransactionSticky.class);
    
@@ -83,6 +87,11 @@
       transactionalSuccessfulCalls(TransactionStickyRandomRobin.class, true);
    }
    
+   public void testTransactionalCallsWithNodeShutdown() throws Exception
+   {
+      transactionalCallsWithNodeShutdown(TransactionStickyRandomRobin.class);
+   }
+   
    public void testSuccessfulCallsRoundRobin() throws Exception
    {
       /* test transaction sticky round robin lbp without transactions, should 
@@ -189,6 +198,26 @@
       
    }
    
+   protected void transactionalCallsWithNodeShutdown(Class<? extends LoadBalancePolicy> policyClass)
+   {
+      log.debug("transactional calls with node shutdown [policy=" + policyClass + "]");
+      
+      try
+      {
+         UID uid = new UID();
+         createNewProxies(0, policyClass, true);
+         transactionalMockUtils.getTpcf().setUid(uid);
+         performTransactionalCallsWithNodeShutdown(null, policyClass);
+      }
+      catch(Exception e)
+      {
+         /* catching to log the error properly (JUnit in eclipse does not show 
+          * correctly exceptions from invokers) and fail */
+         log.error("Error", e);
+         fail();
+      }      
+   }   
+   
    protected void successfulCalls(Class<? extends LoadBalancePolicy> policyClass)
    {
       log.debug("successfull calls [policy=" + policyClass);
@@ -252,6 +281,42 @@
       return chosenTargets;
    }
    
+   protected void performTransactionalCallsWithNodeShutdown(Transaction tx,
+         Class<? extends LoadBalancePolicy> policyClass) throws Exception
+   {
+      Invocation inv;
+      
+      Set<Object> chosenTargetsDateTimeTeller = new HashSet<Object>(1);
+      
+      /* create invocation to date time teller */
+      inv = infrastructure.createDateTimeTellerInvocation(tx, null);
+      /* invoke on proxy passing the invocation */
+      log.debug(timeTellerProxy.invoke(inv));
+      /* assert post conditions after invocation */
+      chosenTargetsDateTimeTeller = assertSuccessfulPostConditions(inv, chosenTargetsDateTimeTeller);
+      
+      List<Object> newReplicants = undeployChosenTargetNode(chosenTargetsDateTimeTeller.toArray()[0]);      
+      ((InvokerProxyHA)timeTellerProxy).updateClusterInfo((ArrayList<Object>)newReplicants, 3);
+      
+      inv = infrastructure.createDateTimeTellerInvocation(tx, null);
+      try
+      {
+         log.debug(timeTellerProxy.invoke(inv));
+         fail("Should have thrown an exception because sticky target is no longer available");
+      }
+      catch(Exception e)
+      {
+         log.debug("Expected exception", e);
+         assertTrue(e instanceof GenericClusteringException || e.getCause() instanceof GenericClusteringException);
+      }
+   }
+   
+   /**
+    * Undeploy chosen target from the cluster and return the list of remaining 
+    * targets in cluster.
+    */
+   protected abstract List undeployChosenTargetNode(Object chosenTarget);   
+   
    protected void assertChosenTargetsInBetweenTx(Class<? extends LoadBalancePolicy> policyClass, Set<?> chosenTargetsTx1, Set<?> chosenTargetsTx2, boolean newProxiesInBetweenTransactions)
    {
       if (policyClass.equals(TransactionStickyRoundRobin.class))

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -26,7 +26,7 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
-import java.util.WeakHashMap;
+import java.util.Map;
 
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
@@ -286,6 +286,11 @@
       }
    }
    
+   public List<? extends InvokerHA> getReplicants()
+   {
+      return replicants;
+   }   
+   
    /**
     * Simulate the deployment of an mbean in a list of invoker endpoints.
     * 
@@ -374,7 +379,7 @@
        * 
        * @return WeakHashMap containing the tx failover authorisations.
        */
-      WeakHashMap getTxFailoverAuthorizationsMap();
+      Map getTxFailoverAuthorizationsMap();
       
       /**
        * Creates an instance of invoker endpoint.

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaMockUtils.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaMockUtils.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaMockUtils.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -23,6 +23,7 @@
 
 import java.util.ArrayList;
 
+import org.jboss.ha.framework.interfaces.GenericClusteringException;
 import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
 import org.jboss.invocation.Invocation;
 import org.jboss.invocation.Invoker;
@@ -124,7 +125,7 @@
       }
       
       @Override
-      protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc)
+      protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc) throws GenericClusteringException
       {
          InvokerHaFailureType failureType = (InvokerHaFailureType)invocation.getValue("FAILURE_TYPE");
          if (failureType != null)

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaTransactionStickyUnitTestCase.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaTransactionStickyUnitTestCase.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaTransactionStickyUnitTestCase.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -21,6 +21,9 @@
  */
 package org.jboss.test.cluster.invokerha;
 
+import java.util.List;
+
+import org.jboss.invocation.InvokerHA;
 import org.jboss.test.cluster.invokerha.JRMPInvokerHaUnitTestCase.JRMPInvokerHaFactory;
 import org.jboss.test.cluster.invokerha.AbstractInvokerHaTransactionSticky;
 
@@ -43,6 +46,14 @@
       super.tearDown();
    }   
    
+   @Override
+   protected List undeployChosenTargetNode(Object chosenTarget)
+   {
+      List<? extends InvokerHA> replicants = infrastructure.getReplicants();
+      replicants.remove(chosenTarget);
+      return replicants;
+   }
+   
    public static class JRMPInvokerHaTransactionStickyFactory extends JRMPInvokerHaFactory
    {
       @Override

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaUnitTestCase.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaUnitTestCase.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/JRMPInvokerHaUnitTestCase.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -21,7 +21,7 @@
  */
 package org.jboss.test.cluster.invokerha;
 
-import java.util.WeakHashMap;
+import java.util.Map;
 
 import org.jboss.invocation.InvokerHA;
 import org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxyHA;
@@ -63,7 +63,7 @@
          return new InvokerHaInfrastructure(serverCount, this);
       }
       
-      public WeakHashMap getTxFailoverAuthorizationsMap()
+      public Map getTxFailoverAuthorizationsMap()
       {
          return JRMPInvokerProxyHA.txFailoverAuthorizations;
       }

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -30,6 +30,7 @@
 import javax.management.MBeanServer;
 import javax.net.SocketFactory;
 
+import org.jboss.ha.framework.interfaces.GenericClusteringException;
 import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
 import org.jboss.invocation.Invocation;
 import org.jboss.invocation.Invoker;
@@ -144,7 +145,7 @@
       }
 
       @Override
-      protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc)
+      protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc) throws GenericClusteringException
       {
          InvokerHaFailureType failureType = (InvokerHaFailureType)invocation.getValue("FAILURE_TYPE");
          if (failureType != null)

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaTransactionStickyUnitTestCase.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaTransactionStickyUnitTestCase.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaTransactionStickyUnitTestCase.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -21,7 +21,11 @@
  */
 package org.jboss.test.cluster.invokerha;
 
+import java.util.List;
+
+import org.jboss.remoting.InvokerLocator;
 import org.jboss.test.cluster.invokerha.UnifiedInvokerHaUnitTestCase.UnifiedInvokerHaFactory;
+import org.jboss.test.cluster.invokerha.UnifiedInvokerHaUnitTestCase.UnifiedInvokerHaInfrastructure;
 import org.jboss.test.cluster.invokerha.AbstractInvokerHaTransactionSticky;
 
 /**
@@ -43,6 +47,14 @@
       super.tearDown();
    }   
    
+   @Override
+   protected List undeployChosenTargetNode(Object chosenTarget)
+   {
+      List<? extends InvokerLocator> locators = ((UnifiedInvokerHaInfrastructure)infrastructure).getLocators();
+      locators.remove(chosenTarget);
+      return locators;
+   }   
+   
    public static class UnifiedInvokerHaTransactionStickyFactory extends UnifiedInvokerHaFactory
    {
       @Override

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -23,7 +23,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.WeakHashMap;
+import java.util.Map;
 
 import javax.management.ObjectName;
 
@@ -76,7 +76,7 @@
     * Unified invoker ha factory. 
     */
    public static class UnifiedInvokerHaFactory implements InvokerHaFactory
-   {
+   {     
       public String getInvokerTypeName()
       {
          return "UnifiedInvokerHa";
@@ -87,7 +87,7 @@
          return new UnifiedInvokerHaInfrastructure(serverCount, this);
       }
       
-      public WeakHashMap getTxFailoverAuthorizationsMap()
+      public Map getTxFailoverAuthorizationsMap()
       {
          return UnifiedInvokerHAProxy.txFailoverAuthorizations;
       }
@@ -112,6 +112,8 @@
     */
    public static class UnifiedInvokerHaInfrastructure extends InvokerHaInfrastructure
    {
+      private List<InvokerLocator> locators;
+      
       public UnifiedInvokerHaInfrastructure(int serverCount, InvokerHaFactory invokerHaFactory)
       {
          super(serverCount, invokerHaFactory);
@@ -122,7 +124,7 @@
             throws Exception
       {
          /* convert replicant list into an InvokerLocator list */
-         List<InvokerLocator> locators = new ArrayList<InvokerLocator>(replicants.size());
+         locators = new ArrayList<InvokerLocator>(replicants.size());
          for (InvokerHA replicant : replicants)
          {
             locators.add(((MockUnifiedInvokerHA)replicant).getLocator());
@@ -137,5 +139,10 @@
             replicant.registerBean(targetName, target);         
          }
       }
+      
+      public List<InvokerLocator> getLocators()
+      {
+         return locators;
+      }
    }   
 }
\ No newline at end of file

Modified: branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/transaction/src/main/org/jboss/tm/TransactionPropagationContextUtil.java
===================================================================
--- branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/transaction/src/main/org/jboss/tm/TransactionPropagationContextUtil.java	2008-09-11 15:15:29 UTC (rev 78431)
+++ branches/JBPAPP_4_3_0_GA_CP02_JBPAPP-1158/transaction/src/main/org/jboss/tm/TransactionPropagationContextUtil.java	2008-09-11 15:15:58 UTC (rev 78432)
@@ -29,6 +29,7 @@
  * Comment
  *
  * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  * @version $Revision$
  */
 public class TransactionPropagationContextUtil
@@ -48,9 +49,16 @@
          try
          {
             InitialContext ctx = new InitialContext();
-            // Get the transaction propagation context factory
-            tpcFactory = (TransactionPropagationContextFactory)
-            ctx.lookup("java:/TransactionPropagationContextExporter");
+            try
+            {
+               // Get the transaction propagation context factory
+               tpcFactory = (TransactionPropagationContextFactory)
+               ctx.lookup("java:/TransactionPropagationContextExporter");
+            }
+            finally
+            {
+               ctx.close();
+            }
          }
          catch (NamingException e)
          {
@@ -72,9 +80,16 @@
          try
          {
             InitialContext ctx = new InitialContext();
-            // and the transaction propagation context importer
-            tpcImporter = (TransactionPropagationContextImporter)
-            ctx.lookup("java:/TransactionPropagationContextImporter");
+            try
+            {
+               // and the transaction propagation context importer
+               tpcImporter = (TransactionPropagationContextImporter)
+               ctx.lookup("java:/TransactionPropagationContextImporter");
+            }
+            finally
+            {
+               ctx.close();
+            }
          }
          catch (NamingException e)
          {




More information about the jboss-cvs-commits mailing list