[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