[jboss-cvs] JBossAS SVN: r80991 - in trunk/cluster: src/main/org/jboss/invocation and 4 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Nov 14 03:55:44 EST 2008


Author: galder.zamarreno at jboss.com
Date: 2008-11-14 03:55:44 -0500 (Fri, 14 Nov 2008)
New Revision: 80991

Added:
   trunk/cluster/src/main/org/jboss/proxy/AbstractTransactionStickyInterceptor.java
   trunk/cluster/src/main/org/jboss/proxy/ClientUserTransactionStickyInterceptor.java
   trunk/cluster/src/main/org/jboss/proxy/TransactionStickyInterceptor.java
Modified:
   trunk/cluster/build.xml
   trunk/cluster/src/main/org/jboss/invocation/InvokerProxyHA.java
   trunk/cluster/src/main/org/jboss/invocation/http/interfaces/ClientMethodInterceptorHA.java
   trunk/cluster/src/main/org/jboss/invocation/http/interfaces/HttpInvokerProxyHA.java
   trunk/cluster/src/main/org/jboss/invocation/jrmp/interfaces/JRMPInvokerProxyHA.java
   trunk/cluster/src/main/org/jboss/invocation/unified/interfaces/UnifiedInvokerHAProxy.java
Log:
[JBAS-6194] Moved transaction sticky logic to client side interceptors. Added a couple of methods to InvokerProxyHA that help keep interceptors proxy independent.

Modified: trunk/cluster/build.xml
===================================================================
--- trunk/cluster/build.xml	2008-11-14 05:47:33 UTC (rev 80990)
+++ trunk/cluster/build.xml	2008-11-14 08:55:44 UTC (rev 80991)
@@ -314,6 +314,7 @@
         <include name="org/jboss/invocation/unified/interfaces/**"/>
         <include name="org/jboss/invocation/InvokerProxyHA**"/>
         <include name="org/jboss/ha/**/*Stub.class"/>
+        <include name="org/jboss/proxy/*"/>
         <include name="org/jboss/ha/framework/test/ExplicitFailoverClientInterceptor.class"/>
       </fileset>
     </jar>

Modified: trunk/cluster/src/main/org/jboss/invocation/InvokerProxyHA.java
===================================================================
--- trunk/cluster/src/main/org/jboss/invocation/InvokerProxyHA.java	2008-11-14 05:47:33 UTC (rev 80990)
+++ trunk/cluster/src/main/org/jboss/invocation/InvokerProxyHA.java	2008-11-14 08:55:44 UTC (rev 80991)
@@ -23,12 +23,15 @@
 
 import java.util.ArrayList;
 
+import org.jboss.ha.framework.interfaces.FamilyClusterInfo;
+
 /**
  * <description>
  *
  * @see <related>
  *
  * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  * @version $Revision$
  *
  * <p><b>Revisions:</b>
@@ -41,7 +44,9 @@
 
 public interface InvokerProxyHA
 {
-   public void updateClusterInfo (ArrayList targets, long viewId);
+   void updateClusterInfo (ArrayList targets, long viewId);
    
+   FamilyClusterInfo getFamilyClusterInfo();
    
+   void forbidTransactionFailover(Object tpc);
 }

Modified: trunk/cluster/src/main/org/jboss/invocation/http/interfaces/ClientMethodInterceptorHA.java
===================================================================
--- trunk/cluster/src/main/org/jboss/invocation/http/interfaces/ClientMethodInterceptorHA.java	2008-11-14 05:47:33 UTC (rev 80990)
+++ trunk/cluster/src/main/org/jboss/invocation/http/interfaces/ClientMethodInterceptorHA.java	2008-11-14 08:55:44 UTC (rev 80991)
@@ -25,11 +25,13 @@
 import java.lang.reflect.Method;
 
 import org.jboss.invocation.Invocation;
+import org.jboss.invocation.InvokerProxyHA;
 import org.jboss.proxy.Interceptor;
 
 /** Handle toString, equals, hashCode locally on the client.
  * 
  * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  * @version $Revision$
  */
 public class ClientMethodInterceptorHA extends Interceptor
@@ -50,7 +52,7 @@
    {
       Method m = mi.getMethod();
       String methodName = m.getName();
-      HttpInvokerProxyHA proxy = (HttpInvokerProxyHA) mi.getInvocationContext().getInvoker();
+      InvokerProxyHA proxy = (InvokerProxyHA) mi.getInvocationContext().getInvoker();
       // Implement local methods
       if( methodName.equals("toString") )
       {
@@ -71,11 +73,11 @@
       return getNext().invoke(mi);
    }
 
-   private String toString(HttpInvokerProxyHA proxy)
+   private String toString(InvokerProxyHA proxy)
    {
       StringBuffer tmp = new StringBuffer(proxy.toString());
       tmp.append('{');
-      tmp.append("clusterInfo="+proxy.getClusterInfo());
+      tmp.append("clusterInfo="+proxy.getFamilyClusterInfo());
       tmp.append('}');
       return tmp.toString();
    }

Modified: trunk/cluster/src/main/org/jboss/invocation/http/interfaces/HttpInvokerProxyHA.java
===================================================================
--- trunk/cluster/src/main/org/jboss/invocation/http/interfaces/HttpInvokerProxyHA.java	2008-11-14 05:47:33 UTC (rev 80990)
+++ trunk/cluster/src/main/org/jboss/invocation/http/interfaces/HttpInvokerProxyHA.java	2008-11-14 08:55:44 UTC (rev 80991)
@@ -51,6 +51,7 @@
  after an invocation if the cluster partitation view has changed.
 
 * @author Scott.Stark at jboss.org
+* @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
 * @version $Revision$
 */
 public class HttpInvokerProxyHA
@@ -110,10 +111,15 @@
       return null;
    }
 
-   public FamilyClusterInfo getClusterInfo()
+   public FamilyClusterInfo getFamilyClusterInfo()
    {
       return familyClusterInfo;
    }
+
+   public void forbidTransactionFailover(Object tpc)
+   {
+      log.debug("Transaction failover authorization not supported for HttpInvokerProxyHA - see JBAS-6196");
+   }
    
    public String getProxyFamilyName()
    {

Modified: trunk/cluster/src/main/org/jboss/invocation/jrmp/interfaces/JRMPInvokerProxyHA.java
===================================================================
--- trunk/cluster/src/main/org/jboss/invocation/jrmp/interfaces/JRMPInvokerProxyHA.java	2008-11-14 05:47:33 UTC (rev 80990)
+++ trunk/cluster/src/main/org/jboss/invocation/jrmp/interfaces/JRMPInvokerProxyHA.java	2008-11-14 08:55:44 UTC (rev 80991)
@@ -29,8 +29,10 @@
 import java.rmi.RemoteException;
 import java.rmi.ServerException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.WeakHashMap;
 
 import javax.transaction.SystemException;
@@ -70,7 +72,7 @@
    private static final long serialVersionUID = -967671822225981666L;
    private static final Logger log = Logger.getLogger(JRMPInvokerProxyHA.class);
    public static final HashSet colocation = new HashSet();
-   public static final WeakHashMap txFailoverAuthorizations = new WeakHashMap();
+   public static final Map txFailoverAuthorizations = Collections.synchronizedMap(new WeakHashMap());
 
    protected LoadBalancePolicy loadBalancePolicy;
    protected String proxyFamilyName = null;
@@ -103,6 +105,16 @@
       if (familyClusterInfo != null)
          this.familyClusterInfo.updateClusterInfo (targets, viewId);
    }
+   
+   public FamilyClusterInfo getFamilyClusterInfo()
+   {
+      return familyClusterInfo;
+   }
+   
+   public void forbidTransactionFailover(Object tpc)
+   {
+      txFailoverAuthorizations.put(tpc, null);
+   }
 
    public Object getRemoteTarget()
    {
@@ -151,34 +163,16 @@
       Object tpc = getTransactionPropagationContext();
       if (tpc != null)
       {
-         synchronized (tpc)
+         if (trace)
          {
-            if (trace)
-            {
-               log.trace("Checking tx failover authorisation map with tpc " + 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;               
+            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);            
       }
-      else
-      {
-         return true;
-      }
+
+      return true;
    }
    
    public void invocationHasReachedAServer (Invocation invocation)
@@ -186,22 +180,7 @@
       Object tpc = getTransactionPropagationContext();
       if (tpc != null)
       {
-         synchronized (tpc)
-         {
-            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);
-         }
+         forbidTransactionFailover(tpc);
       }
    }
 
@@ -218,9 +197,6 @@
       int failoverCounter = 0;
       invocation.setValue ("FAILOVER_COUNTER", new Integer(failoverCounter), PayloadKey.AS_IS);
       
-      // If transaction sticky, put chosen target
-      putIfExistsTransactionTarget(invocation, getTransactionPropagationContext());
-
       // optimize if calling another bean in same EJB-application
       if (isLocal(invocation))
       {
@@ -436,46 +412,7 @@
       
       return tpc;
    }   
-   
-   /**
-    * 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.
-    */
-   protected void putIfExistsTransactionTarget(Invocation invocation, Object tpc) throws Exception
-   {
-      if (tpc != null)
-      {
-         synchronized (tpc)
-         {
-            if (trace)
-            {
-               log.trace("In the proxy, transaction propagation context (tpc) is " + tpc);
-            }
 
-            Object stickyTarget = txFailoverAuthorizations.get(tpc);
-               
-            if (stickyTarget != null)
-            {
-               if (familyClusterInfo.getTargets().contains(stickyTarget))
-               {
-                  if (trace) 
-                  {
-                     log.trace("Put transaction bound target into transient payload: " + stickyTarget);                  
-                  }
-                  
-                  invocation.getTransientPayload().put("TX_STICKY_TARGET", stickyTarget);                  
-               }
-               else
-               {
-                  throw new ServiceUnavailableException("Transaction sticky target is no longer available, so invocation needs to be halted");
-               }
-            }
-         }
-      }
-   }
-   
    // Private -------------------------------------------------------
 
    // Inner classes -------------------------------------------------

Modified: trunk/cluster/src/main/org/jboss/invocation/unified/interfaces/UnifiedInvokerHAProxy.java
===================================================================
--- trunk/cluster/src/main/org/jboss/invocation/unified/interfaces/UnifiedInvokerHAProxy.java	2008-11-14 05:47:33 UTC (rev 80990)
+++ trunk/cluster/src/main/org/jboss/invocation/unified/interfaces/UnifiedInvokerHAProxy.java	2008-11-14 08:55:44 UTC (rev 80991)
@@ -102,51 +102,27 @@
    public boolean txContextAllowsFailover(Invocation invocation)
    {
       Object tpc = getTransactionPropagationContext();
-      if(tpc != null)
+      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 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);
-               }
-               
-               invocation.getTransientPayload().put("TX_STICKY_TARGET", null);
-            }
-            
-            return failoverAuthorised;         
-         }
-      }
-      
+         /* If the map contains the tpc, then we can't allow a failover */
+         return ! txFailoverAuthorizations.containsKey(tpc);
+      }      
+
       return true;
    }
 
-   public void invocationHasReachedAServer(Invocation invocation, Object response)
+   public void invocationHasReachedAServer(Invocation invocation)
    {
       Object tpc = getTransactionPropagationContext();
-      /* Idea here is you store the return value if there's no TPC, on the 
-       * chance it is a TPC.  This won't leak anything since it's a WeakHashMap. 
-       * When you do a txFailoverAuthorization.get() it's always passing a TPC 
-       * as the key, so you won't accidentally find some random object you put 
-       * in the map.*/
-      Object key = (tpc == null) ? response : tpc;
-      if(key != null)
+      if(tpc != null)
       {
-         rememberTransactionTarget(invocation, key);
-      }    
+         forbidTransactionFailover(tpc);
+      }   
    }
    
    public String getProxyFamilyName()
@@ -207,9 +183,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;
 
@@ -284,7 +257,7 @@
                   }
                   else
                   {
-                     invocationHasReachedAServer(invocation, null);
+                     invocationHasReachedAServer(invocation);
                      throw new ServerException("Clustering error", gcex);
                   }
                }
@@ -309,7 +282,7 @@
             }
             
             response = haResponse.response;
-            invocationHasReachedAServer(invocation, response);
+            invocationHasReachedAServer(invocation);
             return response;
 
          }
@@ -363,7 +336,7 @@
             }
             else
             {
-               invocationHasReachedAServer(invocation, null);
+               invocationHasReachedAServer(invocation);
                throw new ServerException("Clustering error", gcex);
             }
          }
@@ -466,6 +439,16 @@
          }
       }
    }
+   
+   public FamilyClusterInfo getFamilyClusterInfo()
+   {
+      return familyClusterInfo;
+   }
+   
+   public void forbidTransactionFailover(Object tpc)
+   {
+      txFailoverAuthorizations.put(tpc, null);
+   }
 
    /**
     * Externalize this instance and handle obtaining the remoteInvoker stub
@@ -541,61 +524,4 @@
       }
       return (tpcFactory == null) ? null : tpcFactory.getTransactionPropagationContext();
    }
-   
-   /**
-    * 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 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) throws Exception
-   {
-      if (tpc != null)
-      {
-         if (trace)
-         {
-            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)
-         {
-            if (familyClusterInfo.getTargets().contains(stickyTarget))
-            {
-               if (trace) 
-               {
-                  log.trace("Put transaction bound target into transient payload: " + stickyTarget);                  
-               }
-               
-               invocation.getTransientPayload().put("TX_STICKY_TARGET", stickyTarget);                  
-            }
-            else
-            {
-               throw new ServiceUnavailableException("Transaction sticky target is no longer available, so invocation needs to be halted");
-            }
-         }
-      }
-   }
-   
-   protected void rememberTransactionTarget(Invocation invocation, Object target)
-   {
-      if (trace)
-      {
-         log.trace("After reaching the server, transaction propagation context (tpc) is " + target);
-      }
-      
-      Object stickyTarget = invocation.getTransientValue("TX_STICKY_TARGET");
-      
-      if (trace && stickyTarget != null)
-      {
-         log.trace("Remember transaction bound target [" + stickyTarget + "] for tpc " + target);
-      }
-      
-      txFailoverAuthorizations.put(target, stickyTarget);
-   }
 }
\ No newline at end of file

Added: trunk/cluster/src/main/org/jboss/proxy/AbstractTransactionStickyInterceptor.java
===================================================================
--- trunk/cluster/src/main/org/jboss/proxy/AbstractTransactionStickyInterceptor.java	                        (rev 0)
+++ trunk/cluster/src/main/org/jboss/proxy/AbstractTransactionStickyInterceptor.java	2008-11-14 08:55:44 UTC (rev 80991)
@@ -0,0 +1,165 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.proxy;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.jboss.ha.framework.interfaces.FamilyClusterInfo;
+import org.jboss.invocation.Invocation;
+import org.jboss.invocation.InvokerProxyHA;
+import org.jboss.invocation.ServiceUnavailableException;
+import org.jboss.logging.Logger;
+import org.jboss.tm.TransactionPropagationContextFactory;
+import org.jboss.tm.TransactionPropagationContextUtil;
+
+/**
+ * Parent transaction sticky interceptor that encapsulates sticky target map 
+ * and exposes operations on this map.
+ * 
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+public abstract class AbstractTransactionStickyInterceptor extends Interceptor
+{
+   private static final Map txStickyTargets = Collections.synchronizedMap(new WeakHashMap());
+   
+   private FamilyClusterInfo familyClusterInfo;
+   
+   protected final Logger log = Logger.getLogger(getClass());
+   
+   protected static boolean trace = false;
+   
+   public AbstractTransactionStickyInterceptor()
+   {
+      trace = log.isTraceEnabled();
+   }
+   
+   /**
+    * Called at the beginning of the invocation to check whether the current tpc
+    * is already present in the tx sticky target. 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  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.
+    * 
+    * @param invocation Invocation object where transaction sticky will be set 
+    * if present.
+    */
+   protected void putIfExistsTransactionTarget(Invocation invocation) throws Exception
+   {
+      Object tpc = getTransactionPropagationContext();
+      
+      if (tpc != null)
+      {
+         if (trace)
+         {
+            log.trace("In the proxy, transaction propagation context (tpc) is " + tpc);
+            log.trace("Contains key returns " + txStickyTargets.containsKey(tpc));
+         }
+
+         Object stickyTarget = txStickyTargets.get(tpc);
+            
+         if (stickyTarget != null)
+         {            
+            if (getFamilyClusterInfo(invocation).getTargets().contains(stickyTarget))
+            {
+               if (trace) 
+               {
+                  log.trace("Put transaction bound target into transient payload: " + stickyTarget);                  
+               }
+               
+               invocation.getTransientPayload().put("TX_STICKY_TARGET", stickyTarget);                  
+            }
+            else
+            {
+               throw new ServiceUnavailableException("Transaction sticky target is no longer available, so invocation needs to be halted");
+            }
+         }
+      }
+   }
+   
+   /**
+    * Method called to remember the sticky target associated with a transaction
+    * context. 
+    * 
+    * @param invocation Invocation object from which the TX_STICKY_TARGET 
+    * transient value comes from.
+    * @param tpc Transaction propagation context.
+    */
+   protected void rememberTransactionTarget(Invocation invocation, Object tpc)
+   {
+      if (trace)
+      {
+         log.trace("After reaching the server, transaction propagation context (tpc) is " + tpc);
+      }
+      
+      Object stickyTarget = invocation.getTransientValue("TX_STICKY_TARGET");
+      
+      if (stickyTarget != null)
+      {
+         if (trace)
+         {
+            log.trace("Remember transaction bound target [" + stickyTarget + "] for tpc " + tpc);
+         }
+
+         txStickyTargets.put(tpc, stickyTarget);
+         
+         /* Put it in invoker proxy txFailoverAuthorizations to avoid failover being
+          * allowed if the 1st EJB invocation within user trasnsaction fails with 
+          * GenericClusteringException.COMPLETED_NO */
+         InvokerProxyHA proxy = (InvokerProxyHA)invocation.getInvocationContext().getInvoker();
+         proxy.forbidTransactionFailover(tpc);
+      }
+   }   
+
+   @Override
+   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+   {
+      super.readExternal(in);
+      trace = log.isTraceEnabled();
+   }
+   
+   protected Object getTransactionPropagationContext()
+   {
+      TransactionPropagationContextFactory tpcFactory = TransactionPropagationContextUtil.getTPCFactoryClientSide();
+      if (trace)
+      {
+         log.trace("Using tpc factory " + tpcFactory);
+      }      
+      return (tpcFactory == null) ? null : tpcFactory.getTransactionPropagationContext();
+   }
+   
+   protected synchronized FamilyClusterInfo getFamilyClusterInfo(Invocation invocation) throws Exception
+   {
+      if (familyClusterInfo == null)
+      {
+         InvokerProxyHA proxy = (InvokerProxyHA)invocation.getInvocationContext().getInvoker();
+         familyClusterInfo = proxy.getFamilyClusterInfo();
+      }
+      
+      return familyClusterInfo;
+   }   
+}

Added: trunk/cluster/src/main/org/jboss/proxy/ClientUserTransactionStickyInterceptor.java
===================================================================
--- trunk/cluster/src/main/org/jboss/proxy/ClientUserTransactionStickyInterceptor.java	                        (rev 0)
+++ trunk/cluster/src/main/org/jboss/proxy/ClientUserTransactionStickyInterceptor.java	2008-11-14 08:55:44 UTC (rev 80991)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.proxy;
+
+import org.jboss.invocation.Invocation;
+
+/**
+ * The ClientUserTransactionStickyInterceptor should be used as an interceptor
+ * for the HA proxy in the ClientUserTransactionService. The aim of this 
+ * interceptor is twofold: First, when UserTransaction.begin() is called, the 
+ * result of the invocation, which is the transaction propagation context of 
+ * the transaction started, is stored together with the target server used, so 
+ * that future invocations can make use of the sticky target. Secondly, for the
+ * rest of UserTransaction invocations, i.e. commit(), getStatus()...etc, the 
+ * current tpc is retrieved and the sticky target is located and added to the 
+ * transient payload of the invocation.
+ * 
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+public class ClientUserTransactionStickyInterceptor extends AbstractTransactionStickyInterceptor
+{
+   @Override
+   public Object invoke(Invocation invocation) throws Throwable
+   {
+      putIfExistsTransactionTarget(invocation);
+      Object response = getNext().invoke(invocation); 
+      invocationHasReachedAServer(invocation, response);
+      return response;
+   }
+
+   public void invocationHasReachedAServer(Invocation invocation, Object response)
+   {
+      Object tpc = getTransactionPropagationContext();
+      if (tpc == null)
+      {
+         /* If tpc is null when invoking a UserTransaction operation, begin() 
+          * is being called, so we remember the target where the transaction 
+          * was started.
+          */
+         rememberTransactionTarget(invocation, response);
+      }
+   }
+}

Added: trunk/cluster/src/main/org/jboss/proxy/TransactionStickyInterceptor.java
===================================================================
--- trunk/cluster/src/main/org/jboss/proxy/TransactionStickyInterceptor.java	                        (rev 0)
+++ trunk/cluster/src/main/org/jboss/proxy/TransactionStickyInterceptor.java	2008-11-14 08:55:44 UTC (rev 80991)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.proxy;
+
+import org.jboss.invocation.Invocation;
+
+/**
+ * Transaction sticky interceptor targeted for Home and Bean invocations. This 
+ * interceptor will put, if exists, the transaction sticky target into the 
+ * transient payload in the invocation so that the transaction sticky load 
+ * balance policy can use it.  
+ * 
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+public class TransactionStickyInterceptor extends AbstractTransactionStickyInterceptor
+{
+   @Override
+   public Object invoke(Invocation invocation) throws Throwable
+   {
+      putIfExistsTransactionTarget(invocation);
+      return getNext().invoke(invocation); 
+   }
+}




More information about the jboss-cvs-commits mailing list