[jboss-svn-commits] JBL Code SVN: r31955 - in labs/jbosstm/trunk/txbridge: demo/dd and 5 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Mar 5 06:17:51 EST 2010
Author: jhalliday
Date: 2010-03-05 06:17:50 -0500 (Fri, 05 Mar 2010)
New Revision: 31955
Added:
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/BridgeDurableParticipant.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/BridgeVolatileParticipant.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridge.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridgeManager.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridgeRecoveryManager.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/JaxWSTxInboundBridgeHandler.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/BridgeSynchronization.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/BridgeXAResource.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/JaxWSTxOutboundBridgeHandler.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridge.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridgeManager.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridgeRecoveryManager.java
Removed:
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeXAResource.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxInboundBridgeHandler.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxOutboundBridgeHandler.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridge.java
labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java
Modified:
labs/jbosstm/trunk/txbridge/META-INF/jboss-beans.xml
labs/jbosstm/trunk/txbridge/demo/dd/jaxws-handlers-client.xml
labs/jbosstm/trunk/txbridge/demo/dd/jaxws-handlers-server.xml
labs/jbosstm/trunk/txbridge/docs/TransactionBridgingGuide.odt
labs/jbosstm/trunk/txbridge/docs/TransactionBridgingGuide.pdf
labs/jbosstm/trunk/txbridge/tests/dd/jaxws-handlers-client.xml
labs/jbosstm/trunk/txbridge/tests/dd/jaxws-handlers-server.xml
Log:
Refactor txbridge to divide inbound and outbound bridges. And initial structure for outbound bridge crash rec. JBTM-44
Modified: labs/jbosstm/trunk/txbridge/META-INF/jboss-beans.xml
===================================================================
--- labs/jbosstm/trunk/txbridge/META-INF/jboss-beans.xml 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/META-INF/jboss-beans.xml 2010-03-05 11:17:50 UTC (rev 31955)
@@ -23,7 +23,7 @@
<deployment xmlns="urn:jboss:bean-deployer:2.0">
- <bean name="TxBridge" class="org.jboss.jbossts.txbridge.BridgeRecoveryManager">
+ <bean name="TxBridgeInboundRecoveryManager" class="org.jboss.jbossts.txbridge.inbound.InboundBridgeRecoveryManager">
<demand state="PreInstall">jboss.xts:service=XTSService</demand>
@@ -33,5 +33,15 @@
</bean>
+ <bean name="TxBridgeOutboundRecoveryManager" class="org.jboss.jbossts.txbridge.outbound.OutboundBridgeRecoveryManager">
+
+ <demand state="PreInstall">jboss.xts:service=XTSService</demand>
+
+ <depends>jboss.xts:service=XTSService</depends>
+
+ <depends>jboss:service=TransactionManager</depends>
+
+ </bean>
+
</deployment>
Modified: labs/jbosstm/trunk/txbridge/demo/dd/jaxws-handlers-client.xml
===================================================================
--- labs/jbosstm/trunk/txbridge/demo/dd/jaxws-handlers-client.xml 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/demo/dd/jaxws-handlers-client.xml 2010-03-05 11:17:50 UTC (rev 31955)
@@ -37,7 +37,7 @@
<handler>
<handler-name>TransactionBridgeHandler</handler-name>
- <handler-class>org.jboss.jbossts.txbridge.JaxWSTxOutboundBridgeHandler</handler-class>
+ <handler-class>org.jboss.jbossts.txbridge.outbound.JaxWSTxOutboundBridgeHandler</handler-class>
</handler>
<handler>
Modified: labs/jbosstm/trunk/txbridge/demo/dd/jaxws-handlers-server.xml
===================================================================
--- labs/jbosstm/trunk/txbridge/demo/dd/jaxws-handlers-server.xml 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/demo/dd/jaxws-handlers-server.xml 2010-03-05 11:17:50 UTC (rev 31955)
@@ -37,7 +37,7 @@
<handler>
<handler-name>TransactionBridgeHandler</handler-name>
- <handler-class>org.jboss.jbossts.txbridge.JaxWSTxInboundBridgeHandler</handler-class>
+ <handler-class>org.jboss.jbossts.txbridge.inbound.JaxWSTxInboundBridgeHandler</handler-class>
</handler>
<handler>
Modified: labs/jbosstm/trunk/txbridge/docs/TransactionBridgingGuide.odt
===================================================================
(Binary files differ)
Modified: labs/jbosstm/trunk/txbridge/docs/TransactionBridgingGuide.pdf
===================================================================
(Binary files differ)
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,282 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2007, 2009 @author JBoss Inc
- */
-package org.jboss.jbossts.txbridge;
-
-import com.arjuna.wst.*;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
-import org.apache.log4j.Logger;
-
-import javax.transaction.xa.Xid;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-
-import javax.resource.spi.XATerminator;
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * Provides method call mapping between WS-AT Durable Participant interface
- * and an underlying JTA subtransaction coordinator.
- *
- * @author jonathan.halliday at redhat.com, 2007-04-30
- */
-public class BridgeDurableParticipant implements Durable2PCParticipant, Serializable
-{
- private static final Logger log = Logger.getLogger(BridgeDurableParticipant.class);
-
- /*
- * Uniq String used to prefix ids at participant registration,
- * so that the recovery module can identify relevant instances.
- */
- public static final String TYPE_IDENTIFIER = "BridgeDurableParticipant_";
-
- /*
- * Uniq (well, hopefully) formatId so we can distinguish our own Xids.
- */
- public static final int XARESOURCE_FORMAT_ID = 131080;
-
- private transient volatile XATerminator xaTerminator;
-
- private transient volatile String externalTxId;
-
- private transient volatile boolean isAwaitingRecovery = false;
-
- static final long serialVersionUID = -5739871936627778072L;
-
- // Xid not guaranteed Serializable by spec, but our XidImple happens to be
- private volatile Xid xid;
-
- // Id needed for recovery of the subordinate tx. Uids are likewise Serializable.
- private volatile Uid subordinateTransactionId;
-
- /**
- * Create a new WS-AT Durable Participant which wraps the subordinate XA tx terminator.
- *
- * @param externalTxId the WS-AT Tx identifier
- * @param xid the Xid to use when driving the subordinate XA transaction.
- */
- BridgeDurableParticipant(String externalTxId, Xid xid)
- {
- log.trace("BridgeDurableParticipant(TxId="+externalTxId+", Xid="+xid+")");
-
- this.xid = xid;
- this.externalTxId = externalTxId;
- xaTerminator = SubordinationManager.getXATerminator();
- }
-
- /**
- * Serialization hook. Gathers and writes information needed for transaction recovery.
- *
- * @param out the strean to which the object state is serialized.
- * @throws IOException if serialization fails.
- */
- private void writeObject(ObjectOutputStream out) throws IOException
- {
- log.trace("writeObject() for Xid="+xid);
-
- // we need to preserve the Uid of the underlying SubordinateTx, as it's required
- // to get a handle on it again during recovery, Using the xid wont work,
- // although we do need to serialize that too for use after recovery.
- try
- {
- subordinateTransactionId = SubordinationManager.getTransactionImporter().getImportedTransaction(xid).get_uid();
- }
- catch(XAException xaException)
- {
- log.error("Unable to get subordinate transaction id", xaException);
- IOException ioException = new IOException("Unable to serialize");
- ioException.initCause(xaException);
- throw ioException;
- }
-
- //out.defaultWriteObject();
- out.writeObject(xid);
- out.writeObject(subordinateTransactionId);
- }
-
- /**
- * Deserialization hook. Unpacks transaction recovery information and uses it to
- * recover the subordinate transaction.
- *
- * @param in the stream from which to unpack the object state.
- * @throws IOException if deserialzation and recovery fail.
- * @throws ClassNotFoundException if deserialzation fails.
- */
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
- {
- log.trace("readObject()");
-
- //in.defaultReadObject();
- xid = (Xid)in.readObject();
- subordinateTransactionId = (Uid)in.readObject();
-
- isAwaitingRecovery = true;
-
- xaTerminator = SubordinationManager.getXATerminator();
-
- try
- {
- SubordinationManager.getTransactionImporter().recoverTransaction(subordinateTransactionId);
- }
- catch(XAException xaException)
- {
- log.error("Unable to recover subordinate transaction id="+subordinateTransactionId, xaException);
- IOException ioException = new IOException("unable to deserialize");
- ioException.initCause(xaException);
- throw ioException;
- }
- }
-
- /**
- * Perform any work necessary to allow it to either commit or rollback
- * the work performed by the Web service under the scope of the
- * transaction. The implementation is free to do whatever it needs to in
- * order to fulfill the implicit contract between it and the coordinator.
- *
- * @return an indication of whether it can prepare or not.
- * @see com.arjuna.wst.Vote
- */
- public Vote prepare() throws WrongStateException, SystemException
- {
- log.trace("prepare(Xid="+xid+")");
-
- try
- {
- // XAResource.XA_OK, XAResource.XA_RDONLY or exception. if RDONLY, don't call commit
- int result = xaTerminator.prepare(xid);
- if(result == XAResource.XA_OK)
- {
- log.debug("prepare on Xid="+xid+" returning Prepared");
- return new Prepared();
- }
- else
- {
- cleanupRefs();
- log.debug("prepare on Xid="+xid+" returning ReadOnly");
- return new ReadOnly();
- }
-
- }
- catch(XAException e)
- {
- cleanupRefs();
- log.warn("prepare on Xid="+xid+" returning Aborted", e);
- return new Aborted();
- }
- }
-
- /**
- * The participant should make permanent the work that it controls.
- *
- * @throws WrongStateException
- * @throws SystemException
- */
- public void commit() throws WrongStateException, SystemException
- {
- log.trace("commit(Xid="+xid+")");
-
- try
- {
- xaTerminator.commit(xid, false);
- log.debug("commit on Xid="+xid+" OK");
- }
- catch (XAException e)
- {
- log.error("commit on Xid="+xid+" failed", e);
- }
- finally
- {
- cleanupRefs();
- }
- }
-
- /**
- * The participant should undo the work that it controls. The participant
- * will then return an indication of whether or not it succeeded..
- *
- * @throws WrongStateException
- * @throws SystemException
- */
- public void rollback() throws WrongStateException, SystemException
- {
- log.trace("rollback(Xid="+xid+")");
-
- try
- {
- xaTerminator.rollback(xid);
- log.debug("rollback on Xid="+xid+" OK");
- }
- catch (XAException e)
- {
- log.error("rollback on Xid="+xid+" failed", e);
- }
- finally
- {
- cleanupRefs();
- }
- }
-
- /**
- * During recovery the participant can enquire as to the status of the
- * transaction it was registered with. If that transaction is no longer
- * available (has rolled back) then this operation will be invoked by the
- * coordination service.
- */
- public void unknown() throws SystemException
- {
- log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
- }
-
- /**
- * During recovery the participant can enquire as to the status of the
- * transaction it was registered with. If an error occurs (e.g., the
- * transaction service is unavailable) then this operation will be invoked.
- */
- public void error() throws SystemException
- {
- log.trace("error(Xid="+xid+"): NOT IMPLEMENTED");
- }
-
- public boolean isAwaitingRecovery() {
- return isAwaitingRecovery;
- }
-
- public Xid getXid()
- {
- return xid;
- }
-
- private void cleanupRefs()
- {
- log.trace("cleanupRefs()");
-
- InboundBridgeManager.removeMapping(externalTxId);
- isAwaitingRecovery = false;
- }
-}
-
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,263 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2009 @author Red Hat Middleware LLC
- */
-package org.jboss.jbossts.txbridge;
-
-import com.arjuna.ats.arjuna.recovery.RecoveryManager;
-import com.arjuna.ats.arjuna.recovery.RecoveryModule;
-import com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
-import com.arjuna.ats.jta.recovery.XAResourceOrphanFilter;
-import org.apache.log4j.Logger;
-import org.jboss.jbossts.xts.recovery.participant.at.XTSATRecoveryModule;
-import org.jboss.jbossts.xts.recovery.participant.at.XTSATRecoveryManager;
-import com.arjuna.wst.Durable2PCParticipant;
-
-import javax.resource.spi.XATerminator;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-import java.io.ObjectInputStream;
-import java.util.*;
-
-/**
- * Integrates with JBossAS MC lifecycle and JBossTS recovery manager to provide recovery services.
- *
- * @author jonathan.halliday at redhat.com, 2009-02-10
- */
-public class BridgeRecoveryManager implements XTSATRecoveryModule, RecoveryModule, XAResourceOrphanFilter
-{
- private static final Logger log = Logger.getLogger(BridgeRecoveryManager.class);
-
- private final XTSATRecoveryManager xtsATRecoveryManager = XTSATRecoveryManager.getRecoveryManager();
- private final RecoveryManager acRecoveryManager = RecoveryManager.manager();
- private final XATerminator xaTerminator = SubordinationManager.getXATerminator();
-
- private final List<BridgeDurableParticipant> participantsAwaitingRecovery =
- Collections.synchronizedList(new LinkedList<BridgeDurableParticipant>());
- private volatile boolean orphanedXAResourcesAreIdentifiable = false;
-
- /**
- * MC lifecycle callback, used to register the recovery module with the transaction manager.
- */
- public void start()
- {
- log.info("BridgeRecoveryManager starting");
-
- xtsATRecoveryManager.registerRecoveryModule(this);
- acRecoveryManager.addModule(this);
-
- XARecoveryModule xaRecoveryModule = getXARecoveryModule();
- xaRecoveryModule.addXAResourceOrphanFilter(this);
- }
-
- private XARecoveryModule getXARecoveryModule()
- {
- XARecoveryModule xaRecoveryModule = null;
- for(RecoveryModule recoveryModule : ((Vector<RecoveryModule>)acRecoveryManager.getModules())) {
- if(recoveryModule instanceof XARecoveryModule) {
- xaRecoveryModule = (XARecoveryModule)recoveryModule;
- break;
- }
- }
-
- if(xaRecoveryModule == null) {
- throw new IllegalStateException("no XARecoveryModule found");
- }
- return xaRecoveryModule;
- }
-
- /**
- * MC lifecycle callback, used to unregister the recovery module from the transaction manager.
- */
- public void stop()
- {
- log.info("BridgeRecoveryManager stopping");
-
- xtsATRecoveryManager.unregisterRecoveryModule(this);
- acRecoveryManager.removeModule(this, false);
-
- XARecoveryModule xaRecoveryModule = getXARecoveryModule();
- xaRecoveryModule.removeXAResourceOrphanFilter(this);
- }
-
- /**
- * Called during recovery processing to allow an application to identify a participant id
- * belonging to one of its participants and recreate the participant by deserializing
- * it from the supplied object input stream. n.b. this is only appropriate in case the
- * participant was originally saved using serialization.
- *
- * @param id the id used when the participant was created
- * @param objectInputStream a stream from which the application should deserialize the participant
- * if it recognises that the id belongs to the module's application
- * @return the deserialized Participant object
- * @throws Exception if an error occurs deserializing the durable participant
- */
- @Override
- public Durable2PCParticipant deserialize(String id, ObjectInputStream objectInputStream) throws Exception
- {
- log.trace("deserialize(id="+id+")");
-
- if(id.startsWith(BridgeDurableParticipant.TYPE_IDENTIFIER))
- {
- Object participant = objectInputStream.readObject();
- BridgeDurableParticipant bridgeDurableParticipant = (BridgeDurableParticipant)participant;
- participantsAwaitingRecovery.add(bridgeDurableParticipant);
- return bridgeDurableParticipant;
- }
- else
- {
- return null;
- }
- }
-
- /**
- * Unused recovery callback. We use serialization instead, so this method will always throw an exception if called.
- */
- @Override
- public Durable2PCParticipant recreate(String s, byte[] bytes) throws Exception
- {
- throw new Exception("recreation not supported - should use deserialization instead.");
- }
-
- /**
- * Called by the RecoveryManager at start up, and then
- * PERIODIC_RECOVERY_PERIOD seconds after the completion, for all RecoveryModules,
- * of the second pass
- */
- @Override
- public void periodicWorkFirstPass()
- {
- log.trace("periodicWorkFirstPass()");
- }
-
- /**
- * Called by the RecoveryManager RECOVERY_BACKOFF_PERIOD seconds
- * after the completion of the first pass
- */
- @Override
- public void periodicWorkSecondPass()
- {
- log.trace("periodicWorkSecondPass()");
-
- cleanupRecoveredParticipants();
-
- // the XTS recovery module is registered and hence run before us. Therefore by the time we get here
- // we know deserialize has been called for any BridgeDurableParticipant for which a log exists.
- orphanedXAResourcesAreIdentifiable = true;
-
-
- List<Xid> indoubtSubordinates = getIndoubtSubordinates();
- for(Xid xid : indoubtSubordinates) {
- if(checkXid(xid) == XAResourceOrphanFilter.Vote.ROLLBACK) {
- log.trace("rolling back orphaned subordinate tx "+xid);
- try {
- xaTerminator.rollback(xid);
- } catch(XAException e) {
- log.error("problem rolling back orphaned subordinate tx "+xid, e);
- }
- }
- }
-
- }
-
- /**
- * Run a recovery scan to identify any in-doubt JTA subordinates.
- *
- * @return a possibly empty but non-null list of xids corresponding to outstanding
- * JTA subordinate transactions owned by the txbridge.
- */
- private List<Xid> getIndoubtSubordinates()
- {
- log.trace("getIndoubtSubordinates()");
-
- Xid[] allSubordinateXids = null;
- try {
- allSubordinateXids = xaTerminator.recover(XAResource.TMSTARTRSCAN);
- } catch(XAException e) {
- log.error("Problem whilst scanning for in-doubt subordinate transactions", e);
- } finally {
- try {
- xaTerminator.recover(XAResource.TMENDRSCAN);
- } catch(XAException e) {}
- }
-
- LinkedList<Xid> mySubordinateXids = new LinkedList<Xid>();
-
- if(allSubordinateXids == null) {
- return mySubordinateXids;
- }
-
- for(Xid xid : allSubordinateXids) {
- if(xid.getFormatId() == BridgeDurableParticipant.XARESOURCE_FORMAT_ID) {
- mySubordinateXids.add(xid);
- log.trace("in-doubt subordinate, xid: "+xid);
- }
- }
-
- return mySubordinateXids;
- }
-
- /**
- * Release any BridgeDurableParticipant instances that have been driven
- * through to completion by their parent XTS transaction.
- */
- private void cleanupRecoveredParticipants()
- {
- log.trace("cleanupRecoveredParticipants()");
-
- synchronized(participantsAwaitingRecovery) {
- Iterator<BridgeDurableParticipant> iter = participantsAwaitingRecovery.iterator();
- while(iter.hasNext()) {
- BridgeDurableParticipant participant = iter.next();
- if(!participant.isAwaitingRecovery()) {
- iter.remove();
- }
- }
- }
- }
-
- @Override
- public Vote checkXid(Xid xid)
- {
- log.trace("checkXid("+xid+")");
-
- if(xid.getFormatId() != BridgeDurableParticipant.XARESOURCE_FORMAT_ID) {
- return Vote.ABSTAIN;
- }
-
- if(!orphanedXAResourcesAreIdentifiable) {
- return Vote.LEAVE_ALONE;
- }
-
- synchronized(participantsAwaitingRecovery) {
- for(BridgeDurableParticipant participant : participantsAwaitingRecovery) {
- if(participant.getXid().equals(xid)) {
- return Vote.LEAVE_ALONE;
- }
- }
- }
-
- return Vote.ROLLBACK;
- }
-}
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,90 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2009 @author JBoss Inc
- */
-package org.jboss.jbossts.txbridge;
-
-import org.apache.log4j.Logger;
-import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
-
-import javax.transaction.Synchronization;
-import javax.transaction.Status;
-
-import com.arjuna.ats.jta.utils.JTAHelper;
-
-/**
- * Provides method call mapping between JTA parent coordinator and WS-AT subordinate transaction.
- *
- * @author jonathan.halliday at redhat.com, 2009-06-01
- */
-public class BridgeSynchronization implements Synchronization
-{
- private static final Logger log = Logger.getLogger(BridgeSynchronization.class);
-
- private final BridgeWrapper bridgeWrapper;
-
- public BridgeSynchronization(BridgeWrapper bridgeWrapper)
- {
- log.trace("BridgeSynchronization(BridgeWrapper="+bridgeWrapper+")");
-
- this.bridgeWrapper = bridgeWrapper;
- }
-
- /**
- * The beforeCompletion method is called by the transaction manager prior to the start of the two-phase transaction commit process.
- */
- public void beforeCompletion()
- {
- log.trace("beforeCompletion()");
-
- if(!bridgeWrapper.prepareVolatile())
- {
- // JTA does not explicitly provide for beforeCompletion signalling problems, but in
- // our impl the engine will set the tx rollbackOnly if beforeCompletion throw an exception
- // Note com.arjuna.ats.jta.TransactionManager.getTransaction().setRollbackOnly may also work.
- throw new RuntimeException("BridgeWrapper.prepareVolatile() returned false");
- }
- }
-
- /**
- * This method is called by the transaction manager after the transaction is committed or rolled back.
- *
- * @param status the javax.transaction.Status representing the tx outcome.
- */
- public void afterCompletion(int status)
- {
- log.trace("afterCompletion(status="+status+"/"+ JTAHelper.stringForm(status)+")");
-
- switch(status)
- {
- case Status.STATUS_COMMITTED:
- bridgeWrapper.commitVolatile();
- break;
- case Status.STATUS_ROLLEDBACK:
- bridgeWrapper.rollbackVolatile();
- break;
- default:
- log.warn("unexpected Status "+status+", treating as ROLLEDBACK");
- bridgeWrapper.rollbackVolatile();
- }
- }
-}
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,182 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2009 @author JBoss Inc
- */
-package org.jboss.jbossts.txbridge;
-
-import com.arjuna.wst.*;
-import com.arjuna.ats.internal.jta.resources.spi.XATerminatorExtensions;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
-import com.arjuna.ats.jta.utils.JTAHelper;
-import org.apache.log4j.Logger;
-
-import javax.transaction.xa.Xid;
-import javax.transaction.Status;
-
-/**
- * Provides method call mapping between WS-AT Volatile Participant interface
- * and an underlying JTA subtransaction coordinator.
- *
- * @author jonathan.halliday at redhat.com, 2009-06-01
- */
-public class BridgeVolatileParticipant implements Volatile2PCParticipant
-{
- private static final Logger log = Logger.getLogger(BridgeVolatileParticipant.class);
-
- // no standard interface for driving Synchronization phases separately
- // in JCA, so we have to use proprietary API.
- private final XATerminatorExtensions xaTerminatorExtensions;
-
- private final String externalTxId;
-
- private final Xid xid;
-
- /**
- * Create a new WS-AT Volatile Participant which wraps the subordinate XA tx terminator.
- *
- * @param externalTxId the WS-AT Tx identifier
- * @param xid the Xid to use when driving the subordinate XA transaction.
- */
- BridgeVolatileParticipant(String externalTxId, Xid xid)
- {
- log.trace("BridgeVolatileParticipant(TxId="+externalTxId+", Xid="+xid+")");
-
- this.xid = xid;
- this.externalTxId = externalTxId;
- this.xaTerminatorExtensions = (XATerminatorExtensions)SubordinationManager.getXATerminator();
- }
-
- /**
- * Perform beforeCompletion activities such as flushing cached state to stable store.
- *
- * @return an indication of whether it can prepare or not.
- * @see com.arjuna.wst.Vote
- */
- public Vote prepare() throws WrongStateException, SystemException
- {
- log.trace("prepare(Xid="+xid+")");
-
- // Usually a VolatileParticipant would return Aborted to stop the tx in error cases. However, that
- // would mean rollback() would not be called on the instance returning Aborted, which would make it
- // hard to invoke afterCompletion on the subordinate. So we cheat a bit by using setRollbackOnly instead.
- // A slightly more efficient but less clear impl would be to have the same object implement both the Volatile
- // and Durable Participants and keep count of the number of prepare/rollback invocations to know
- // if being invoked as Volatile or Durable.
-
-
- // TODO InboundBridgeManager.getInboundBridge() would be better,
- // but needs XTS to provide tx context on thread in (selected) Participant calls.
- InboundBridge inboundBridge = InboundBridgeManager.getInboundBridge(externalTxId);
-
- try
- {
- // TODO: check for rollbackOnly before bothering to invoke?
- // beforeCompletion should run in tx context.
- inboundBridge.start();
-
- if(!xaTerminatorExtensions.beforeCompletion(xid))
- {
- log.warn("prepare on Xid="+xid+" failed, setting RollbackOnly");
- inboundBridge.setRollbackOnly();
- }
-
- return new Prepared();
- }
- catch(Exception e)
- {
- log.warn("prepare on Xid="+xid+" failed, setting RollbackOnly", e);
- try
- {
- inboundBridge.setRollbackOnly();
- }
- catch(Exception e2)
- {
- log.warn("setRollbackOnly failed", e2);
- }
-
- return new Prepared();
- }
- finally
- {
- try
- {
- inboundBridge.stop();
- }
- catch(Exception e)
- {
- log.warn("stop failed for Xid="+xid, e);
- }
- }
- }
-
- /**
- * Perform afterCompletion cleanup activities such as releasing resources.
- *
- * Caution: may not be invoked in crash recovery situations.
- */
- public void commit() throws WrongStateException, SystemException
- {
- log.trace("commit(Xid="+xid+")");
-
- afterCompletion(Status.STATUS_COMMITTED);
- }
-
- /**
- * Perform afterCompletion cleanup activities such as releasing resources.
- *
- * Caution: may not be invoked in crash recovery situations.
- */
- public void rollback() throws WrongStateException, SystemException
- {
- log.trace("rollback(Xid="+xid+")");
-
- afterCompletion(Status.STATUS_ROLLEDBACK);
- }
-
- /**
- * Invoke afterCompletion on the subordinate JTA tx.
- *
- * @param status a javax.transaction.Status value, normally STATUS_COMMITTED or STATUS_ROLLEDBACK
- */
- private void afterCompletion(int status)
- {
- log.trace("afterCompletion(Xid="+xid+", status="+status+"/"+JTAHelper.stringForm(status)+")");
-
- // this is a null-op, the afterCompletion is done implicitly at the XAResource commit/rollback stage.
- }
-
- /**
- * Deprecated, should never be called.
- */
- public void unknown() throws SystemException
- {
- log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
- }
-
- /**
- * VolatileParticipants don't support recovery, so this should never be called.
- */
- public void error() throws SystemException
- {
- log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
- }
-}
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeXAResource.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeXAResource.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeXAResource.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,233 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2009 @author Red Hat Middleware LLC
- */
-package org.jboss.jbossts.txbridge;
-
-import org.apache.log4j.Logger;
-import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
-
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-import javax.transaction.xa.XAException;
-
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
-
-/**
- * Provides method call mapping between JTA parent coordinator and WS-AT subordinate transaction.
- *
- * @author jonathan.halliday at redhat.com, 2009-02-10
- */
-public class BridgeXAResource implements XAResource
-{
- // Design note: Given the way JBossTS is designed, we could subclass AbstractRecord rather than
- // implementing XAResource, but this design is more standards friendly and thus portable.
-
- private static final Logger log = Logger.getLogger(BridgeXAResource.class);
-
- private final transient BridgeWrapper bridgeWrapper;
-
- private final transient Uid externalTxId;
-
- /**
- * Create a new XAResource which wraps the subordinate WS-AT transaction.
- *
- * @param externalTxId the parent JTA transaction identifier.
- * @param bridgeWrapper the control for the subordinate WS-AT transaction.
- */
- public BridgeXAResource(Uid externalTxId, BridgeWrapper bridgeWrapper)
- {
- log.trace("BridgeXARresource(TxId="+externalTxId+", BridgeWrapper="+bridgeWrapper+")");
-
- this.externalTxId = externalTxId;
- this.bridgeWrapper = bridgeWrapper;
- }
-
- /**
- * Ask the resource manager to prepare for a transaction commit of the transaction specified in xid.
- *
- * @param xid A global transaction identifier
- * @return A value indicating the resource manager's vote on the outcome of the transaction
- * @throws XAException
- */
- public int prepare(Xid xid) throws XAException
- {
- log.trace("prepare(Xid="+xid+")");
-
- // TwoPhaseOutcome needs converting to XAResource rtn type.
- int twoPhaseOutcome = bridgeWrapper.prepare();
-
- log.trace("prepare TwoPhaseOutcome is "+twoPhaseOutcome+"/"+TwoPhaseOutcome.stringForm(twoPhaseOutcome));
-
- switch(twoPhaseOutcome)
- {
- case TwoPhaseOutcome.PREPARE_OK:
- log.trace("prepare returning XAResource.XA_OK");
- return XAResource.XA_OK;
- case TwoPhaseOutcome.PREPARE_READONLY:
- OutboundBridgeManager.removeMapping(externalTxId);
- log.trace("prepare returning XAResource.XA_RDONLY");
- return XAResource.XA_RDONLY;
- default:
- // TODO more find-grained error type handling
- log.trace("prepare TwoPhaseOutcome is "+twoPhaseOutcome+"/"+
- TwoPhaseOutcome.stringForm(twoPhaseOutcome)+", throwing XAException...");
- XAException xaException = new XAException("unexpected oucome: "+TwoPhaseOutcome.stringForm(twoPhaseOutcome));
- xaException.errorCode = XAException.XA_RBROLLBACK;
- throw xaException;
- }
- }
-
- /**
- * Informs the resource manager to roll back work done on behalf of a transaction branch.
- *
- * @param xid A global transaction identifier
- * @throws XAException
- */
- public void rollback(Xid xid) throws XAException
- {
- log.trace("rollback(Xid="+xid+")");
-
- try
- {
- bridgeWrapper.rollback();
- }
- finally
- {
- OutboundBridgeManager.removeMapping(externalTxId);
- }
- }
-
- /**
- * Commits the global transaction specified by xid.
- *
- * @param xid A global transaction identifier
- * @param onePhase
- * @throws XAException
- */
- public void commit(Xid xid, boolean onePhase) throws XAException
- {
- log.trace("commit(Xid="+xid+", onePhase="+onePhase+")");
-
- try
- {
- if(onePhase)
- {
- // no shortcuts, we have to do prepare anyhow
- if(prepare(xid) == XAResource.XA_RDONLY)
- {
- return;
- }
- }
-
- bridgeWrapper.commit();
- }
- finally
- {
- OutboundBridgeManager.removeMapping(externalTxId);
- }
- }
-
- /**
- * Starts work on behalf of a transaction branch specified in xid.
- *
- * @param xid A global transaction identifier
- * @param flags
- * @throws XAException
- */
- public void start(Xid xid, int flags) throws XAException
- {
- log.trace("start(Xid="+xid+", flags="+flags+")");
-
- // do nothing
- }
-
- /**
- * Ends the work performed on behalf of a transaction branch.
- *
- * @param xid A global transaction identifier
- * @param flags
- * @throws XAException
- */
- public void end(Xid xid, int flags) throws XAException
- {
- log.trace("end(Xid="+xid+", flags="+flags+")");
-
- // do nothing
- }
-
- public boolean isSameRM(XAResource xaResource) throws XAException
- {
- log.trace("isSameRM(XAResource="+xaResource+")");
-
- return false; // TODO
- }
-
- public void forget(Xid xid) throws XAException
- {
- log.trace("forget(Xid="+xid+")");
-
- // TODO
- }
-
- /**
- * Obtains a list of prepared transaction branches from a resource manager.
- *
- * @param flag
- * @return
- * @throws XAException
- */
- public Xid[] recover(int flag) throws XAException
- {
- log.trace("recover(flag="+flag+")");
-
- return new Xid[0]; // TODO
- }
-
- /**
- * Sets the current transaction timeout value for this XAResource instance.
- *
- * @param seconds - The transaction timeout value in seconds.
- * @return true if the transaction timeout value is set successfully; otherwise false.
- * @throws XAException
- */
- public boolean setTransactionTimeout(int seconds) throws XAException
- {
- log.trace("setTransactionTimeout(seconds="+seconds+")");
-
- return false; // TODO
- }
-
- /**
- * Obtains the current transaction timeout value set for this XAResource instance.
- *
- * @return the transaction timeout value in seconds.
- * @throws XAException
- */
- public int getTransactionTimeout() throws XAException
- {
- log.trace("getTransactionTimeout()");
-
- return 0; // TODO
- }
-}
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,132 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2007, 2009 @author JBoss Inc
- */
-package org.jboss.jbossts.txbridge;
-
-import com.arjuna.ats.jta.TransactionManager;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
-
-import javax.transaction.xa.Xid;
-import javax.transaction.xa.XAException;
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.Transaction;
-
-import org.apache.log4j.Logger;
-
-/**
- * Manages Thread association of the interposed coordinator.
- * Typically called from handlers in the WS stack.
- *
- * @author jonathan.halliday at redhat.com, 2007-04-30
- */
-public class InboundBridge
-{
- private static final Logger log = Logger.getLogger(InboundBridge.class);
-
- /**
- * Identifier for the subordinate transaction.
- */
- private final Xid xid;
-
- /**
- * Create a new InboundBridge to manage the given subordinate JTA transaction.
- *
- * @param xid the subordinate transaction id
- * @throws XAException
- * @throws SystemException
- */
- InboundBridge(Xid xid) throws XAException, SystemException
- {
- log.trace("InboundBridge(Xid="+xid+")");
-
- this.xid = xid;
-
- getTransaction(); // ensures transaction is initialized
- }
-
- /**
- * Associate the JTA transaction to the current Thread.
- * Typically used by a server side inbound handler.
- *
- * @throws XAException
- * @throws SystemException
- * @throws InvalidTransactionException
- */
- public void start() throws XAException, SystemException, InvalidTransactionException
- {
- log.trace("start(Xid="+xid+")");
-
- Transaction tx = getTransaction();
-
- TransactionManager.transactionManager().resume(tx);
- }
-
- /**
- * Disassociate the JTA transaction from the current Thread.
- * Typically used by a server side outbound handler.
- *
- * @throws XAException
- * @throws SystemException
- * @throws InvalidTransactionException
- */
- public void stop() throws XAException, SystemException, InvalidTransactionException
- {
- log.trace("stop("+xid+")");
-
- TransactionManager.transactionManager().suspend();
- }
-
- public void setRollbackOnly() throws XAException, SystemException
- {
- log.trace("setRollbackOnly("+xid+")");
-
- getTransaction().setRollbackOnly();
- }
-
- /**
- * Get the JTA Transaction which corresponds to the Xid of the instance.
- *
- * @return
- * @throws XAException
- * @throws SystemException
- */
- private Transaction getTransaction()
- throws XAException, SystemException
- {
- Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid);
-
- switch (tx.getStatus())
- {
- // TODO: other cases?
-
- case Status.STATUS_ACTIVE:
- case Status.STATUS_MARKED_ROLLBACK:
- break;
- default:
- throw new IllegalStateException("Transaction not in state ACTIVE");
- }
- return tx;
- }
-}
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,149 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2007, 2009 @author JBoss Inc
- */
-package org.jboss.jbossts.txbridge;
-
-import com.arjuna.ats.jta.xa.XATxConverter;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.mw.wst11.UserTransactionFactory;
-
-import com.arjuna.mw.wst11.TransactionManagerFactory;
-import com.arjuna.mw.wst11.TransactionManager;
-import com.arjuna.wst.WrongStateException;
-import com.arjuna.wst.UnknownTransactionException;
-import com.arjuna.wsc.AlreadyRegisteredException;
-
-import javax.transaction.xa.Xid;
-import javax.transaction.xa.XAException;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.log4j.Logger;
-
-/**
- * Maintains the mapping data that relates WS-AT transactions to JTA subordinate transactions and related objects.
- *
- * The mappings are scoped to the singleton instance of this class and its lifetime.
- * This poses problems where you have more than one instance (classloading, clusters)
- * or where you need crash recovery. It short, it's rather limited.
- *
- * @author jonathan.halliday at redhat.com, 2007-04-30
- */
-public class InboundBridgeManager
-{
- private static final Logger log = Logger.getLogger(InboundBridgeManager.class);
-
- // maps WS-AT Tx Id to InboundBridge instance.
- private static final ConcurrentMap<String, InboundBridge> inboundBridgeMappings = new ConcurrentHashMap<String, InboundBridge>();
-
- /**
- * Return an InboundBridge instance that maps the current Thread's WS transaction context
- * to a JTA context. Control of the latter is provided by the returned instance.
- *
- * @return an InboundBridge corresponding to the calling Thread's current WS-AT transaction context.
- * @throws WrongStateException
- * @throws UnknownTransactionException
- * @throws com.arjuna.wst.SystemException
- * @throws AlreadyRegisteredException
- */
- public static InboundBridge getInboundBridge()
- throws XAException, WrongStateException, UnknownTransactionException,
- com.arjuna.wst.SystemException, javax.transaction.SystemException, AlreadyRegisteredException
- {
- log.trace("getInboundBridge()");
-
- String externalTxId = UserTransactionFactory.userTransaction().toString();
-
- if(!inboundBridgeMappings.containsKey(externalTxId)) {
- createMapping(externalTxId);
- }
-
- return inboundBridgeMappings.get(externalTxId);
- }
-
- /**
- * Return an InboundBridge instance for the specified WS-AT transaction context.
- *
- * This method exists only to allow BridgeVolatileParticipant to get tx context and may go away
- * once its no longer needed for that purpose. Therefore it should probably not be relied upon.
- *
- * @deprecated
- * @param externalTxId The WS-AT tx identifier.
- * @return
- */
- static InboundBridge getInboundBridge(String externalTxId)
- {
- return inboundBridgeMappings.get(externalTxId);
- }
-
- /**
- * Remove the mapping for the given externalTxId. This should be called for gc when the tx is finished.
- *
- * @param externalTxId The WS-AT tx identifier.
- */
- public static synchronized void removeMapping(String externalTxId)
- {
- log.trace("removeMapping(externalTxId="+externalTxId+")");
-
- if(externalTxId != null) {
- inboundBridgeMappings.remove(externalTxId);
- }
- }
-
- /**
- * Create the JTA transaction mapping and support objects for a given WS transaction context.
- *
- * @param externalTxId The WS-AT tx identifier.
- * @throws WrongStateException
- * @throws UnknownTransactionException
- * @throws com.arjuna.wst.SystemException
- * @throws AlreadyRegisteredException
- */
- private static synchronized void createMapping(String externalTxId)
- throws XAException, WrongStateException, UnknownTransactionException,
- com.arjuna.wst.SystemException, javax.transaction.SystemException, AlreadyRegisteredException
- {
- log.trace("createMapping(externalTxId="+externalTxId+")");
-
- if(inboundBridgeMappings.containsKey(externalTxId)) {
- return;
- }
-
- TransactionManager transactionManager = TransactionManagerFactory.transactionManager();
-
- // Xid for driving the subordinate,
- // shared by the bridge (thread assoc) and Participant (termination via XATerminator)
- Xid xid = XATxConverter.getXid(new Uid(), false, BridgeDurableParticipant.XARESOURCE_FORMAT_ID);
-
- BridgeDurableParticipant bridgeDurableParticipant = new BridgeDurableParticipant(externalTxId, xid);
- // construct the participantId in such as way as we can recognise it at recovery time:
- String participantId = BridgeDurableParticipant.TYPE_IDENTIFIER+new Uid().toString();
- transactionManager.enlistForDurableTwoPhase(bridgeDurableParticipant, participantId);
-
- BridgeVolatileParticipant bridgeVolatileParticipant = new BridgeVolatileParticipant(externalTxId, xid);
- transactionManager.enlistForVolatileTwoPhase(bridgeVolatileParticipant, new Uid().toString());
-
- inboundBridgeMappings.put(externalTxId, new InboundBridge(xid));
- }
-}
\ No newline at end of file
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxInboundBridgeHandler.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxInboundBridgeHandler.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxInboundBridgeHandler.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,142 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2007, 2009 @author JBoss Inc
- */
-package org.jboss.jbossts.txbridge;
-
-import javax.xml.ws.handler.Handler;
-import javax.xml.ws.handler.MessageContext;
-
-import org.apache.log4j.Logger;
-
-/**
- * A handler that sits in the server side JAX-WS processing pipeline between the XTS header
- * context processor and the web service. Takes the WS transaction context provided by the
- * former and maps it to a JTA transaction context for use by the latter. Handles Thread
- * association of the JTA context.
- *
- * Note: we assume that there is a web services transaction context present and
- * that the service needs a JTA context. The handler should not be registered on
- * methods unless both these conditions hold.
- *
- * @author jonathan.halliday at redhat.com, 2007-04-30
- */
-public class JaxWSTxInboundBridgeHandler implements Handler
-{
- private static final Logger log = Logger.getLogger(JaxWSTxInboundBridgeHandler.class);
-
- /**
- * Process a message. Determines if it is inbound or outbound and dispatches accordingly.
- *
- * @param msgContext the context to process
- * @return true on success, false on error
- */
- public boolean handleMessage(MessageContext msgContext)
- {
- log.trace("handleMessage()");
-
- Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
- if (outbound == null)
- throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
-
- return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
- }
-
- /**
- * Tidy up the Transaction/Thread association before faults are thrown back to the client.
- *
- * @param messageContext unused
- * @return true on success, false on error
- */
- public boolean handleFault(MessageContext messageContext)
- {
- log.trace("handleFault()");
-
- return suspendTransaction();
- }
-
- public void close(MessageContext messageContext)
- {
- log.trace("close()");
- }
-
- /**
- * Process inbound messages by mapping the WS transaction context
- * to a JTA one and associating the latter to the current Thread.
- *
- * @param msgContext unused
- * @return true on success, false on error
- */
- protected boolean handleInbound(MessageContext msgContext)
- {
- log.trace("handleInbound()");
-
- try
- {
- InboundBridge inboundBridge = InboundBridgeManager.getInboundBridge();
- inboundBridge.start();
- }
- catch (Exception e)
- {
- log.error(e);
- return false;
- }
-
- return true;
- }
-
- /**
- * Tidy up the Transaction/Thread association before returning a message to the client.
- *
- * @param msgContext unused
- * @return true on success, false on error
- */
- protected boolean handleOutbound(MessageContext msgContext)
- {
- log.trace("handleOutbound()");
-
- return suspendTransaction();
- }
-
- /**
- * Break the association between the JTA transaction context and the calling Thread.
- *
- * @return true on success, false on error
- */
- private boolean suspendTransaction()
- {
- log.trace("suspendTransaction()");
-
- try
- {
- InboundBridge inboundBridge = InboundBridgeManager.getInboundBridge();
- inboundBridge.stop();
- }
- catch (Exception e)
- {
- log.error(e);
- return false;
- }
-
- return true;
- }
-}
\ No newline at end of file
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxOutboundBridgeHandler.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxOutboundBridgeHandler.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxOutboundBridgeHandler.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,142 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2009 @author Red Hat Middleware LLC
- */
-package org.jboss.jbossts.txbridge;
-
-import org.apache.log4j.Logger;
-
-import javax.xml.ws.handler.Handler;
-import javax.xml.ws.handler.MessageContext;
-
-/**
- * A handler that sits in the client side JAX-WS processing pipeline between the application
- * and the XTS header context processor. Takes the JTA transaction context provided by the
- * former and maps it to a WS-AT transaction context for use by the latter. Handles Thread
- * association of the WS-AT context.
- *
- * Note: we assume that there is a JTA transaction context present and
- * that the service needs a WS-AT context. The handler should not be registered on
- * methods unless both these conditions hold.
- *
- * @author jonathan.halliday at redhat.com, 2009-02-10
- */
-public class JaxWSTxOutboundBridgeHandler implements Handler
-{
- private static final Logger log = Logger.getLogger(JaxWSTxOutboundBridgeHandler.class);
-
- /**
- * Process a message. Determines if it is inbound or outbound and dispatches accordingly.
- *
- * @param msgContext the context to process
- * @return true on success, false on error
- */
- public boolean handleMessage(MessageContext msgContext)
- {
- log.trace("handleMessage()");
-
- Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
- if (outbound == null)
- throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
-
- return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
- }
-
- /**
- * Tidy up the Transaction/Thread association before faults are thrown back to the client.
- *
- * @param messageContext unused
- * @return true on success, false on error
- */
- public boolean handleFault(MessageContext messageContext)
- {
- log.trace("handleFault()");
-
- return suspendTransaction();
- }
-
- public void close(MessageContext messageContext)
- {
- log.trace("close()");
- }
-
- /**
- * Tidy up the Transaction/Thread association before returning a message to the client.
- *
- * @param msgContext unused
- * @return true on success, false on error
- */
- protected boolean handleInbound(MessageContext msgContext)
- {
- log.trace("handleInbound()");
-
- return suspendTransaction();
- }
-
- /**
- * Process outbound messages by mapping the JTA transaction context
- * to a WS-AT one and associating the latter to the current Thread.
- *
- * @param msgContext unused
- * @return true on success, false on error
- */
- protected boolean handleOutbound(MessageContext msgContext)
- {
- log.trace("handleOutbound()");
-
- try
- {
- OutboundBridge outboundBridge = OutboundBridgeManager.getOutboundBridge();
- outboundBridge.start();
- }
- catch (Exception e)
- {
- log.error(e);
- return false;
- }
-
- return true;
- }
-
- /**
- * Break the association between the WS-AT transaction context and the calling Thread.
- *
- * @return true on success, false on error
- */
- private boolean suspendTransaction()
- {
- log.trace("suspendTransaction()");
-
- try
- {
- OutboundBridge outboundBridge = OutboundBridgeManager.getOutboundBridge();
- outboundBridge.stop();
- }
- catch (Exception e)
- {
- log.error(e);
- return false;
- }
-
- return true;
- }
-}
\ No newline at end of file
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridge.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridge.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridge.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,88 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2009 @author Red Hat Middleware LLC
- */
-package org.jboss.jbossts.txbridge;
-
-import org.apache.log4j.Logger;
-import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
-import com.arjuna.mw.wst11.TransactionManagerFactory;
-import com.arjuna.mw.wst.TxContext;
-import com.arjuna.wst.SystemException;
-import com.arjuna.wst.UnknownTransactionException;
-
-/**
- * Manages Thread association of the interposed coordinator.
- * Typically called from handlers in the WS stack.
- *
- * @author jonathan.halliday at redhat.com, 2009-02-10
- */
-public class OutboundBridge
-{
- private static final Logger log = Logger.getLogger(OutboundBridge.class);
-
- /**
- * Management object for the subordinate transaction
- */
- private final BridgeWrapper bridgeWrapper;
-
- /**
- * Create a new OutboundBridge to manage the given subordinate WS-AT transaction.
- *
- * @param bridgeWrapper the subordinate transaction controller
- */
- public OutboundBridge(BridgeWrapper bridgeWrapper)
- {
- log.trace("OutboundBridge(BridgeWrapper="+bridgeWrapper+")");
-
- this.bridgeWrapper = bridgeWrapper;
- }
-
- /**
- * Associate the WS-AT transaction to the current Thread.
- * Typically used by the client side outbound handler.
- *
- * @throws UnknownTransactionException
- * @throws SystemException
- */
- public void start() throws UnknownTransactionException, SystemException
- {
- log.trace("start(BridgeWrapper="+bridgeWrapper+")");
-
- TxContext txContext = bridgeWrapper.getContext();
-
- TransactionManagerFactory.transactionManager().resume(txContext);
- }
-
- /**
- * Disassociate the WS-AT transaction from the current Thread.
- * Typically used by the client side inbound handler.
- *
- * @throws SystemException
- */
- public void stop() throws SystemException
- {
- log.trace("stop(BridgeWrapper="+bridgeWrapper+")");
-
- TransactionManagerFactory.transactionManager().suspend();
- }
-}
Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -1,136 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2009 @author Red Hat Middleware LLC
- */
-package org.jboss.jbossts.txbridge;
-
-import com.arjuna.ats.jta.TransactionManager;
-import com.arjuna.ats.jta.transaction.Transaction;
-import com.arjuna.ats.arjuna.common.Uid;
-
-import javax.transaction.SystemException;
-import javax.transaction.RollbackException;
-import javax.transaction.Synchronization;
-import javax.transaction.xa.XAResource;
-
-import org.apache.log4j.Logger;
-import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
-
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Maintains the mapping data that relates JTA transactions to WS-AT subordinate transactions and related objects.
- *
- * The mappings are scoped to the singleton instance of this class and its lifetime.
- * This poses problems where you have more than one instances (classloading, clusters)
- * or where you need crash recovery. It short, it's rather limited.
- *
- * @author jonathan.halliday at redhat.com, 2009-02-10
- */
-public class OutboundBridgeManager
-{
- private static final Logger log = Logger.getLogger(OutboundBridgeManager.class);
-
- // maps JTA Tx Id to OutboundBridge instance.
- private static final ConcurrentMap<Uid, OutboundBridge> outboundBridgeMappings = new ConcurrentHashMap<Uid, OutboundBridge>();
-
- /**
- * Return an OutboundBridge instance that maps the current Thread's JTA transaction context
- * to a WS-AT transaction context. Control of the latter is provided by the returned instance.
- *
- * @return as OutboundBridge corresponding to the calling Thread's current JTA transaction context.
- */
- public static OutboundBridge getOutboundBridge()
- {
- log.trace("getOutboundBridge()");
-
- try
- {
- Transaction transaction = (Transaction)TransactionManager.transactionManager().getTransaction();
-
- Uid externalTxId = transaction.get_uid();
-
- if(!outboundBridgeMappings.containsKey(externalTxId)) {
- createMapping(transaction, externalTxId);
- }
-
- return outboundBridgeMappings.get(externalTxId);
-
- }
- catch(SystemException e)
- {
- log.error("problem", e);
- }
-
- return null;
- }
-
- /**
- * Remove the mapping for the given externalTxId. This should be called for gc when the tx is finished.
- *
- * @param externalTxId The JTA transaction identifier.
- */
- public static synchronized void removeMapping(Uid externalTxId)
- {
- log.trace("removeMapping(externalTxId="+externalTxId+")");
-
- if(externalTxId != null) {
- outboundBridgeMappings.remove(externalTxId);
- }
- }
-
- /**
- * Create a WS-AT transaction mapping and support objects for a given JTA transaction context.
- *
- * @param externalTxId The JTA transaction identifier.
- * @throws SystemException
- */
- private static synchronized void createMapping(Transaction transaction, Uid externalTxId) throws SystemException
- {
- log.trace("createmapping(externalTxId="+externalTxId+")");
-
- if(outboundBridgeMappings.containsKey(externalTxId)) {
- return;
- }
-
- // TODO: allow params to be configurable, or at least pass timeout down.
- BridgeWrapper bridgeWrapper = BridgeWrapper.create(0, false);
-
- OutboundBridge outboundBridge = new OutboundBridge(bridgeWrapper);
- XAResource xaResource = new BridgeXAResource(externalTxId, bridgeWrapper);
- Synchronization synchronization = new BridgeSynchronization(bridgeWrapper);
-
- try
- {
- transaction.enlistResource(xaResource);
- transaction.registerSynchronization(synchronization);
- }
- catch(RollbackException e)
- {
- log.error("Unable to enlist BridgeXAResource or register BridgeSynchronization: ", e);
- throw new SystemException(e.toString());
- }
-
- outboundBridgeMappings.put(externalTxId, outboundBridge);
- }
-}
\ No newline at end of file
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/BridgeDurableParticipant.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/BridgeDurableParticipant.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/BridgeDurableParticipant.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,283 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2007, 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge.inbound;
+
+import com.arjuna.wst.*;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
+import org.apache.log4j.Logger;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+
+import javax.resource.spi.XATerminator;
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * Provides method call mapping between WS-AT Durable Participant interface
+ * and an underlying JTA subtransaction coordinator.
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class BridgeDurableParticipant implements Durable2PCParticipant, Serializable
+{
+ private static final Logger log = Logger.getLogger(BridgeDurableParticipant.class);
+
+ /*
+ * Uniq String used to prefix ids at participant registration,
+ * so that the recovery module can identify relevant instances.
+ */
+ public static final String TYPE_IDENTIFIER = "BridgeDurableParticipant_";
+
+ /*
+ * Uniq (well, hopefully) formatId so we can distinguish our own Xids.
+ */
+ public static final int XARESOURCE_FORMAT_ID = 131080;
+
+ private transient volatile XATerminator xaTerminator;
+
+ private transient volatile String externalTxId;
+
+ private transient volatile boolean isAwaitingRecovery = false;
+
+ static final long serialVersionUID = -5739871936627778072L;
+
+ // Xid not guaranteed Serializable by spec, but our XidImple happens to be
+ private volatile Xid xid;
+
+ // Id needed for recovery of the subordinate tx. Uids are likewise Serializable.
+ private volatile Uid subordinateTransactionId;
+
+ /**
+ * Create a new WS-AT Durable Participant which wraps the subordinate XA tx terminator.
+ *
+ * @param externalTxId the WS-AT Tx identifier
+ * @param xid the Xid to use when driving the subordinate XA transaction.
+ */
+ BridgeDurableParticipant(String externalTxId, Xid xid)
+ {
+ log.trace("BridgeDurableParticipant(TxId="+externalTxId+", Xid="+xid+")");
+
+ this.xid = xid;
+ this.externalTxId = externalTxId;
+ xaTerminator = SubordinationManager.getXATerminator();
+ }
+
+ /**
+ * Serialization hook. Gathers and writes information needed for transaction recovery.
+ *
+ * @param out the stream to which the object state is serialized.
+ * @throws IOException if serialization fails.
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException
+ {
+ log.trace("writeObject() for Xid="+xid);
+
+ // we need to preserve the Uid of the underlying SubordinateTx, as it's required
+ // to get a handle on it again during recovery, Using the xid wont work,
+ // although we do need to serialize that too for use after recovery.
+ try
+ {
+ subordinateTransactionId = SubordinationManager.getTransactionImporter().getImportedTransaction(xid).get_uid();
+ }
+ catch(XAException xaException)
+ {
+ log.error("Unable to get subordinate transaction id", xaException);
+ IOException ioException = new IOException("Unable to serialize");
+ ioException.initCause(xaException);
+ throw ioException;
+ }
+
+ //out.defaultWriteObject();
+ out.writeObject(xid);
+ out.writeObject(subordinateTransactionId);
+ }
+
+ /**
+ * Deserialization hook. Unpacks transaction recovery information and uses it to
+ * recover the subordinate transaction.
+ *
+ * @param in the stream from which to unpack the object state.
+ * @throws IOException if deserialzation and recovery fail.
+ * @throws ClassNotFoundException if deserialzation fails.
+ */
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+ {
+ log.trace("readObject()");
+
+ //in.defaultReadObject();
+ xid = (Xid)in.readObject();
+ subordinateTransactionId = (Uid)in.readObject();
+
+ // this readObject method executes only when a log is being read at recovery time:
+ isAwaitingRecovery = true;
+
+ xaTerminator = SubordinationManager.getXATerminator();
+
+ try
+ {
+ SubordinationManager.getTransactionImporter().recoverTransaction(subordinateTransactionId);
+ }
+ catch(XAException xaException)
+ {
+ log.error("Unable to recover subordinate transaction id="+subordinateTransactionId, xaException);
+ IOException ioException = new IOException("unable to deserialize");
+ ioException.initCause(xaException);
+ throw ioException;
+ }
+ }
+
+ /**
+ * Perform any work necessary to allow it to either commit or rollback
+ * the work performed by the Web service under the scope of the
+ * transaction. The implementation is free to do whatever it needs to in
+ * order to fulfill the implicit contract between it and the coordinator.
+ *
+ * @return an indication of whether it can prepare or not.
+ * @see com.arjuna.wst.Vote
+ */
+ public Vote prepare() throws WrongStateException, SystemException
+ {
+ log.trace("prepare(Xid="+xid+")");
+
+ try
+ {
+ // XAResource.XA_OK, XAResource.XA_RDONLY or exception. if RDONLY, don't call commit
+ int result = xaTerminator.prepare(xid);
+ if(result == XAResource.XA_OK)
+ {
+ log.debug("prepare on Xid="+xid+" returning Prepared");
+ return new Prepared();
+ }
+ else
+ {
+ cleanupRefs();
+ log.debug("prepare on Xid="+xid+" returning ReadOnly");
+ return new ReadOnly();
+ }
+
+ }
+ catch(XAException e)
+ {
+ cleanupRefs();
+ log.warn("prepare on Xid="+xid+" returning Aborted", e);
+ return new Aborted();
+ }
+ }
+
+ /**
+ * The participant should make permanent the work that it controls.
+ *
+ * @throws WrongStateException
+ * @throws SystemException
+ */
+ public void commit() throws WrongStateException, SystemException
+ {
+ log.trace("commit(Xid="+xid+")");
+
+ try
+ {
+ xaTerminator.commit(xid, false);
+ log.debug("commit on Xid="+xid+" OK");
+ }
+ catch (XAException e)
+ {
+ log.error("commit on Xid="+xid+" failed", e);
+ }
+ finally
+ {
+ cleanupRefs();
+ }
+ }
+
+ /**
+ * The participant should undo the work that it controls. The participant
+ * will then return an indication of whether or not it succeeded..
+ *
+ * @throws WrongStateException
+ * @throws SystemException
+ */
+ public void rollback() throws WrongStateException, SystemException
+ {
+ log.trace("rollback(Xid="+xid+")");
+
+ try
+ {
+ xaTerminator.rollback(xid);
+ log.debug("rollback on Xid="+xid+" OK");
+ }
+ catch (XAException e)
+ {
+ log.error("rollback on Xid="+xid+" failed", e);
+ }
+ finally
+ {
+ cleanupRefs();
+ }
+ }
+
+ /**
+ * During recovery the participant can enquire as to the status of the
+ * transaction it was registered with. If that transaction is no longer
+ * available (has rolled back) then this operation will be invoked by the
+ * coordination service.
+ */
+ public void unknown() throws SystemException
+ {
+ log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
+ }
+
+ /**
+ * During recovery the participant can enquire as to the status of the
+ * transaction it was registered with. If an error occurs (e.g., the
+ * transaction service is unavailable) then this operation will be invoked.
+ */
+ public void error() throws SystemException
+ {
+ log.trace("error(Xid="+xid+"): NOT IMPLEMENTED");
+ }
+
+ public boolean isAwaitingRecovery() {
+ return isAwaitingRecovery;
+ }
+
+ public Xid getXid()
+ {
+ return xid;
+ }
+
+ private void cleanupRefs()
+ {
+ log.trace("cleanupRefs()");
+
+ org.jboss.jbossts.txbridge.inbound.InboundBridgeManager.removeMapping(externalTxId);
+ isAwaitingRecovery = false;
+ }
+}
+
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/BridgeVolatileParticipant.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/BridgeVolatileParticipant.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/BridgeVolatileParticipant.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,179 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge.inbound;
+
+import com.arjuna.wst.*;
+import com.arjuna.ats.internal.jta.resources.spi.XATerminatorExtensions;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
+import com.arjuna.ats.jta.utils.JTAHelper;
+import org.apache.log4j.Logger;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.Status;
+
+/**
+ * Provides method call mapping between WS-AT Volatile Participant interface
+ * and an underlying JTA subtransaction coordinator.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-06-01
+ */
+public class BridgeVolatileParticipant implements Volatile2PCParticipant
+{
+ private static final Logger log = Logger.getLogger(BridgeVolatileParticipant.class);
+
+ // no standard interface for driving Synchronization phases separately
+ // in JCA, so we have to use proprietary API.
+ private final XATerminatorExtensions xaTerminatorExtensions;
+
+ private final String externalTxId;
+
+ private final Xid xid;
+
+ /**
+ * Create a new WS-AT Volatile Participant which wraps the subordinate XA tx terminator.
+ *
+ * @param externalTxId the WS-AT Tx identifier
+ * @param xid the Xid to use when driving the subordinate XA transaction.
+ */
+ BridgeVolatileParticipant(String externalTxId, Xid xid)
+ {
+ log.trace("BridgeVolatileParticipant(TxId="+externalTxId+", Xid="+xid+")");
+
+ this.xid = xid;
+ this.externalTxId = externalTxId;
+ this.xaTerminatorExtensions = (XATerminatorExtensions)SubordinationManager.getXATerminator();
+ }
+
+ /**
+ * Perform beforeCompletion activities such as flushing cached state to stable store.
+ *
+ * @return an indication of whether it can prepare or not.
+ * @see com.arjuna.wst.Vote
+ */
+ public Vote prepare() throws WrongStateException, SystemException
+ {
+ log.trace("prepare(Xid="+xid+")");
+
+ // Usually a VolatileParticipant would return Aborted to stop the tx in error cases. However, that
+ // would mean rollback() would not be called on the instance returning Aborted, which would make it
+ // hard to invoke afterCompletion on the subordinate. So we cheat a bit by using setRollbackOnly instead.
+ // A slightly more efficient but less clear impl would be to have the same object implement both the Volatile
+ // and Durable Participants and keep count of the number of prepare/rollback invocations to know
+ // if being invoked as Volatile or Durable.
+
+ InboundBridge inboundBridge = InboundBridgeManager.getInboundBridge(externalTxId);
+
+ try
+ {
+ // TODO: check for rollbackOnly before bothering to invoke?
+ // beforeCompletion should run in tx context.
+ inboundBridge.start();
+
+ if(!xaTerminatorExtensions.beforeCompletion(xid))
+ {
+ log.warn("prepare on Xid="+xid+" failed, setting RollbackOnly");
+ inboundBridge.setRollbackOnly();
+ }
+
+ return new Prepared();
+ }
+ catch(Exception e)
+ {
+ log.warn("prepare on Xid="+xid+" failed, setting RollbackOnly", e);
+ try
+ {
+ inboundBridge.setRollbackOnly();
+ }
+ catch(Exception e2)
+ {
+ log.warn("setRollbackOnly failed", e2);
+ }
+
+ return new Prepared();
+ }
+ finally
+ {
+ try
+ {
+ inboundBridge.stop();
+ }
+ catch(Exception e)
+ {
+ log.warn("stop failed for Xid="+xid, e);
+ }
+ }
+ }
+
+ /**
+ * Perform afterCompletion cleanup activities such as releasing resources.
+ *
+ * Caution: may not be invoked in crash recovery situations.
+ */
+ public void commit() throws WrongStateException, SystemException
+ {
+ log.trace("commit(Xid="+xid+")");
+
+ afterCompletion(Status.STATUS_COMMITTED);
+ }
+
+ /**
+ * Perform afterCompletion cleanup activities such as releasing resources.
+ *
+ * Caution: may not be invoked in crash recovery situations.
+ */
+ public void rollback() throws WrongStateException, SystemException
+ {
+ log.trace("rollback(Xid="+xid+")");
+
+ afterCompletion(Status.STATUS_ROLLEDBACK);
+ }
+
+ /**
+ * Invoke afterCompletion on the subordinate JTA tx.
+ *
+ * @param status a javax.transaction.Status value, normally STATUS_COMMITTED or STATUS_ROLLEDBACK
+ */
+ private void afterCompletion(int status)
+ {
+ log.trace("afterCompletion(Xid="+xid+", status="+status+"/"+JTAHelper.stringForm(status)+")");
+
+ // this is a null-op, the afterCompletion is done implicitly at the XAResource commit/rollback stage.
+ }
+
+ /**
+ * Deprecated, should never be called.
+ */
+ public void unknown() throws SystemException
+ {
+ log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
+ }
+
+ /**
+ * VolatileParticipants don't support recovery, so this should never be called.
+ */
+ public void error() throws SystemException
+ {
+ log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
+ }
+}
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridge.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridge.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridge.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2007, 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge.inbound;
+
+import com.arjuna.ats.jta.TransactionManager;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.Transaction;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Manages Thread association of the interposed coordinator.
+ * Typically called from handlers in the WS stack.
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class InboundBridge
+{
+ private static final Logger log = Logger.getLogger(InboundBridge.class);
+
+ /**
+ * Identifier for the subordinate transaction.
+ */
+ private final Xid xid;
+
+ /**
+ * Create a new InboundBridge to manage the given subordinate JTA transaction.
+ *
+ * @param xid the subordinate transaction id
+ * @throws XAException
+ * @throws SystemException
+ */
+ InboundBridge(Xid xid) throws XAException, SystemException
+ {
+ log.trace("InboundBridge(Xid="+xid+")");
+
+ this.xid = xid;
+
+ getTransaction(); // ensures transaction is initialized
+ }
+
+ /**
+ * Associate the JTA transaction to the current Thread.
+ * Typically used by a server side inbound handler.
+ *
+ * @throws XAException
+ * @throws SystemException
+ * @throws InvalidTransactionException
+ */
+ public void start() throws XAException, SystemException, InvalidTransactionException
+ {
+ log.trace("start(Xid="+xid+")");
+
+ Transaction tx = getTransaction();
+
+ TransactionManager.transactionManager().resume(tx);
+ }
+
+ /**
+ * Disassociate the JTA transaction from the current Thread.
+ * Typically used by a server side outbound handler.
+ *
+ * @throws XAException
+ * @throws SystemException
+ * @throws InvalidTransactionException
+ */
+ public void stop() throws XAException, SystemException, InvalidTransactionException
+ {
+ log.trace("stop("+xid+")");
+
+ TransactionManager.transactionManager().suspend();
+ }
+
+ public void setRollbackOnly() throws XAException, SystemException
+ {
+ log.trace("setRollbackOnly("+xid+")");
+
+ getTransaction().setRollbackOnly();
+ }
+
+ /**
+ * Get the JTA Transaction which corresponds to the Xid of the instance.
+ *
+ * @return
+ * @throws XAException
+ * @throws SystemException
+ */
+ private Transaction getTransaction()
+ throws XAException, SystemException
+ {
+ Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid);
+
+ switch (tx.getStatus())
+ {
+ // TODO: other cases?
+
+ case Status.STATUS_ACTIVE:
+ case Status.STATUS_MARKED_ROLLBACK:
+ break;
+ default:
+ throw new IllegalStateException("Transaction not in state ACTIVE");
+ }
+ return tx;
+ }
+}
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridgeManager.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridgeManager.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridgeManager.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,149 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2007, 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge.inbound;
+
+import com.arjuna.ats.jta.xa.XATxConverter;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst11.UserTransactionFactory;
+
+import com.arjuna.mw.wst11.TransactionManagerFactory;
+import com.arjuna.mw.wst11.TransactionManager;
+import com.arjuna.wst.WrongStateException;
+import com.arjuna.wst.UnknownTransactionException;
+import com.arjuna.wsc.AlreadyRegisteredException;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Maintains the mapping data that relates WS-AT transactions to JTA subordinate transactions and related objects.
+ *
+ * The mappings are scoped to the singleton instance of this class and its lifetime.
+ * This poses problems where you have more than one instance (classloading, clusters)
+ * or where you need crash recovery. It short, it's rather limited.
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class InboundBridgeManager
+{
+ private static final Logger log = Logger.getLogger(InboundBridgeManager.class);
+
+ // maps WS-AT Tx Id to InboundBridge instance.
+ private static final ConcurrentMap<String, InboundBridge> inboundBridgeMappings = new ConcurrentHashMap<String, org.jboss.jbossts.txbridge.inbound.InboundBridge>();
+
+ /**
+ * Return an InboundBridge instance that maps the current Thread's WS transaction context
+ * to a JTA context. Control of the latter is provided by the returned instance.
+ *
+ * @return an InboundBridge corresponding to the calling Thread's current WS-AT transaction context.
+ * @throws WrongStateException
+ * @throws UnknownTransactionException
+ * @throws com.arjuna.wst.SystemException
+ * @throws AlreadyRegisteredException
+ */
+ public static InboundBridge getInboundBridge()
+ throws XAException, WrongStateException, UnknownTransactionException,
+ com.arjuna.wst.SystemException, javax.transaction.SystemException, AlreadyRegisteredException
+ {
+ log.trace("getInboundBridge()");
+
+ String externalTxId = UserTransactionFactory.userTransaction().toString();
+
+ if(!inboundBridgeMappings.containsKey(externalTxId)) {
+ createMapping(externalTxId);
+ }
+
+ return inboundBridgeMappings.get(externalTxId);
+ }
+
+ /**
+ * Return an InboundBridge instance for the specified WS-AT transaction context.
+ *
+ * This method exists only to allow BridgeVolatileParticipant to get tx context and may go away
+ * once its no longer needed for that purpose. Therefore it should probably not be relied upon.
+ *
+ * @deprecated
+ * @param externalTxId The WS-AT tx identifier.
+ * @return
+ */
+ static InboundBridge getInboundBridge(String externalTxId)
+ {
+ return inboundBridgeMappings.get(externalTxId);
+ }
+
+ /**
+ * Remove the mapping for the given externalTxId. This should be called for gc when the tx is finished.
+ *
+ * @param externalTxId The WS-AT tx identifier.
+ */
+ public static synchronized void removeMapping(String externalTxId)
+ {
+ log.trace("removeMapping(externalTxId="+externalTxId+")");
+
+ if(externalTxId != null) {
+ inboundBridgeMappings.remove(externalTxId);
+ }
+ }
+
+ /**
+ * Create the JTA transaction mapping and support objects for a given WS transaction context.
+ *
+ * @param externalTxId The WS-AT tx identifier.
+ * @throws WrongStateException
+ * @throws UnknownTransactionException
+ * @throws com.arjuna.wst.SystemException
+ * @throws AlreadyRegisteredException
+ */
+ private static synchronized void createMapping(String externalTxId)
+ throws XAException, WrongStateException, UnknownTransactionException,
+ com.arjuna.wst.SystemException, javax.transaction.SystemException, AlreadyRegisteredException
+ {
+ log.trace("createMapping(externalTxId="+externalTxId+")");
+
+ if(inboundBridgeMappings.containsKey(externalTxId)) {
+ return;
+ }
+
+ TransactionManager transactionManager = TransactionManagerFactory.transactionManager();
+
+ // Xid for driving the subordinate,
+ // shared by the bridge (thread assoc) and Participant (termination via XATerminator)
+ Xid xid = XATxConverter.getXid(new Uid(), false, BridgeDurableParticipant.XARESOURCE_FORMAT_ID);
+
+ BridgeDurableParticipant bridgeDurableParticipant = new BridgeDurableParticipant(externalTxId, xid);
+ // construct the participantId in such as way as we can recognise it at recovery time:
+ String participantId = org.jboss.jbossts.txbridge.inbound.BridgeDurableParticipant.TYPE_IDENTIFIER+new Uid().toString();
+ transactionManager.enlistForDurableTwoPhase(bridgeDurableParticipant, participantId);
+
+ BridgeVolatileParticipant bridgeVolatileParticipant = new BridgeVolatileParticipant(externalTxId, xid);
+ transactionManager.enlistForVolatileTwoPhase(bridgeVolatileParticipant, new Uid().toString());
+
+ inboundBridgeMappings.put(externalTxId, new InboundBridge(xid));
+ }
+}
\ No newline at end of file
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridgeRecoveryManager.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridgeRecoveryManager.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/InboundBridgeRecoveryManager.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,289 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author Red Hat Middleware LLC
+ */
+package org.jboss.jbossts.txbridge.inbound;
+
+import com.arjuna.ats.arjuna.recovery.RecoveryManager;
+import com.arjuna.ats.arjuna.recovery.RecoveryModule;
+import com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
+import com.arjuna.ats.jta.recovery.XAResourceOrphanFilter;
+import org.apache.log4j.Logger;
+import org.jboss.jbossts.xts.recovery.participant.at.XTSATRecoveryModule;
+import org.jboss.jbossts.xts.recovery.participant.at.XTSATRecoveryManager;
+import com.arjuna.wst.Durable2PCParticipant;
+
+import javax.resource.spi.XATerminator;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import java.io.ObjectInputStream;
+import java.util.*;
+
+/**
+ * Integrates with JBossAS MC lifecycle and JBossTS recovery manager to provide
+ * recovery services for inbound bridged transactions.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-02-10
+ */
+public class InboundBridgeRecoveryManager implements XTSATRecoveryModule, RecoveryModule, XAResourceOrphanFilter
+{
+ private static final Logger log = Logger.getLogger(InboundBridgeRecoveryManager.class);
+
+ private final XTSATRecoveryManager xtsATRecoveryManager = XTSATRecoveryManager.getRecoveryManager();
+ private final RecoveryManager acRecoveryManager = RecoveryManager.manager();
+ private final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+
+ private final List<BridgeDurableParticipant> participantsAwaitingRecovery =
+ Collections.synchronizedList(new LinkedList<BridgeDurableParticipant>());
+ private volatile boolean orphanedXAResourcesAreIdentifiable = false;
+
+ /**
+ * MC lifecycle callback, used to register components with the recovery manager.
+ */
+ public void start()
+ {
+ log.info("InboundBridgeRecoveryManager starting");
+
+ xtsATRecoveryManager.registerRecoveryModule(this);
+ acRecoveryManager.addModule(this);
+
+ XARecoveryModule xaRecoveryModule = getXARecoveryModule();
+ xaRecoveryModule.addXAResourceOrphanFilter(this);
+ }
+
+ /**
+ * MC lifecycle callback, used to unregister components from the recovery manager.
+ */
+ public void stop()
+ {
+ log.info("InboundBridgeRecoveryManager stopping");
+
+ xtsATRecoveryManager.unregisterRecoveryModule(this);
+ acRecoveryManager.removeModule(this, false);
+
+ XARecoveryModule xaRecoveryModule = getXARecoveryModule();
+ xaRecoveryModule.removeXAResourceOrphanFilter(this);
+ }
+
+ /**
+ * Lookup the XARecoveryModule, required for (de-)registration of XAResourceOrphanFilter.
+ * @return the RecoveryManager's XARecoveryModule instance.
+ */
+ private XARecoveryModule getXARecoveryModule()
+ {
+ // at some stage we should probably consider extending atsintegration's
+ // RecoveryManagerService (and maybe the app server's tm integration spi) to
+ // expose orphan filters directly, as with e.g. [add|remove]XAResourceRecovery.
+
+ XARecoveryModule xaRecoveryModule = null;
+ for(RecoveryModule recoveryModule : ((Vector<RecoveryModule>)acRecoveryManager.getModules())) {
+ if(recoveryModule instanceof XARecoveryModule) {
+ xaRecoveryModule = (XARecoveryModule)recoveryModule;
+ break;
+ }
+ }
+
+ if(xaRecoveryModule == null) {
+ throw new IllegalStateException("no XARecoveryModule found");
+ }
+ return xaRecoveryModule;
+ }
+
+ /**
+ * Called during recovery processing to allow an application to identify a participant id
+ * belonging to one of its participants and recreate the participant by deserializing
+ * it from the supplied object input stream. n.b. this is only appropriate in case the
+ * participant was originally saved using serialization.
+ *
+ * @param id the id used when the participant was created
+ * @param objectInputStream a stream from which the application should deserialize the participant
+ * if it recognises that the id belongs to the module's application
+ * @return the deserialized Participant object
+ * @throws Exception if an error occurs deserializing the durable participant
+ */
+ @Override
+ public Durable2PCParticipant deserialize(String id, ObjectInputStream objectInputStream) throws Exception
+ {
+ log.trace("deserialize(id="+id+")");
+
+ // Inbound bridge transactions don't have an independent log - their state is inlined into the
+ // XTS Participant log and this callback is used to recover that state.
+ // We keep a handle on it for later use, as we have no other means of determining which Xids
+ // represent uncompleted transactions.
+ if(id.startsWith(BridgeDurableParticipant.TYPE_IDENTIFIER))
+ {
+ Object participant = objectInputStream.readObject();
+ BridgeDurableParticipant bridgeDurableParticipant = (BridgeDurableParticipant)participant;
+ participantsAwaitingRecovery.add(bridgeDurableParticipant);
+ return bridgeDurableParticipant;
+ }
+ else
+ {
+ return null; // it belongs to some other XTS app, ignore it.
+ }
+ }
+
+ /**
+ * Unused recovery callback. We use serialization instead, so this method will always throw an exception if called.
+ */
+ @Override
+ public Durable2PCParticipant recreate(String s, byte[] bytes) throws Exception
+ {
+ throw new Exception("recreation not supported - should use deserialization instead.");
+ }
+
+ /**
+ * Called by the RecoveryManager at start up, and then
+ * PERIODIC_RECOVERY_PERIOD seconds after the completion, for all RecoveryModules,
+ * of the second pass
+ */
+ @Override
+ public void periodicWorkFirstPass()
+ {
+ log.trace("periodicWorkFirstPass()");
+ }
+
+ /**
+ * Called by the RecoveryManager RECOVERY_BACKOFF_PERIOD seconds
+ * after the completion of the first pass
+ */
+ @Override
+ public void periodicWorkSecondPass()
+ {
+ log.trace("periodicWorkSecondPass()");
+
+ cleanupRecoveredParticipants();
+
+ // the XTS recovery module is registered and hence run before us. Therefore by the time we get here
+ // we know deserialize has been called for any BridgeDurableParticipant for which a log exists.
+ // thus if it's not in our participantsAwaitingRecovery list by now, it's presumed rollback.
+ orphanedXAResourcesAreIdentifiable = true;
+
+ // Inbound tx may have a JCA tx log but no corresponding XTS Participant (i.e. BridgeDurableParticipant) log.
+ // these can now be identified and rolled back.
+ List<Xid> indoubtSubordinates = getIndoubtSubordinates();
+ for(Xid xid : indoubtSubordinates) {
+ if(checkXid(xid) == XAResourceOrphanFilter.Vote.ROLLBACK) {
+ log.trace("rolling back orphaned subordinate tx "+xid);
+ try {
+ xaTerminator.rollback(xid);
+ } catch(XAException e) {
+ log.error("problem rolling back orphaned subordinate tx "+xid, e);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Run a recovery scan to identify any in-doubt JTA subordinates.
+ *
+ * @return a possibly empty but non-null list of xids corresponding to outstanding
+ * JTA subordinate transactions owned by the txbridge.
+ */
+ private List<Xid> getIndoubtSubordinates()
+ {
+ log.trace("getIndoubtSubordinates()");
+
+ Xid[] allSubordinateXids = null;
+ try {
+ allSubordinateXids = xaTerminator.recover(XAResource.TMSTARTRSCAN);
+ } catch(XAException e) {
+ log.error("Problem whilst scanning for in-doubt subordinate transactions", e);
+ } finally {
+ try {
+ xaTerminator.recover(XAResource.TMENDRSCAN);
+ } catch(XAException e) {}
+ }
+
+ LinkedList<Xid> mySubordinateXids = new LinkedList<Xid>();
+
+ if(allSubordinateXids == null) {
+ return mySubordinateXids;
+ }
+
+ for(Xid xid : allSubordinateXids) {
+ if(xid.getFormatId() == BridgeDurableParticipant.XARESOURCE_FORMAT_ID) {
+ mySubordinateXids.add(xid);
+ log.trace("in-doubt subordinate, xid: "+xid);
+ }
+ }
+
+ return mySubordinateXids;
+ }
+
+ /**
+ * Release any BridgeDurableParticipant instances that have been driven
+ * through to completion by their parent XTS transaction.
+ */
+ private void cleanupRecoveredParticipants()
+ {
+ log.trace("cleanupRecoveredParticipants()");
+
+ synchronized(participantsAwaitingRecovery) {
+ Iterator<org.jboss.jbossts.txbridge.inbound.BridgeDurableParticipant> iter = participantsAwaitingRecovery.iterator();
+ while(iter.hasNext()) {
+ BridgeDurableParticipant participant = iter.next();
+ if(!participant.isAwaitingRecovery()) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ /**
+ * Used to identify inbound bridged Xids in either the RM log (when called by XARecoveryModule) or
+ * the JCA subordinate tx log (when called internally from this class) which have or have not got a
+ * remaining transaction that may still drive them to completion.
+ *
+ * @param xid The in-doubt xid.
+ * @return a Vote on the handling of the xid (to roll it back or not).
+ */
+ @Override
+ public Vote checkXid(Xid xid)
+ {
+ log.trace("checkXid("+xid+")");
+
+ if(xid.getFormatId() != BridgeDurableParticipant.XARESOURCE_FORMAT_ID) {
+ return Vote.ABSTAIN; // it's not one of ours, ignore it.
+ }
+
+ if(!orphanedXAResourcesAreIdentifiable) {
+ // recovery system not in stable state yet - we don't yet know if it's orphaned or not.
+ return Vote.LEAVE_ALONE;
+ }
+
+ // check if it's owned by a recovered tx that may still commit.
+ synchronized(participantsAwaitingRecovery) {
+ for(BridgeDurableParticipant participant : participantsAwaitingRecovery) {
+ if(participant.getXid().equals(xid)) {
+ return Vote.LEAVE_ALONE;
+ }
+ }
+ }
+
+ // presumed abort:
+ return Vote.ROLLBACK;
+ }
+}
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/JaxWSTxInboundBridgeHandler.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxInboundBridgeHandler.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/JaxWSTxInboundBridgeHandler.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/inbound/JaxWSTxInboundBridgeHandler.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,142 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2007, 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge.inbound;
+
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+
+import org.apache.log4j.Logger;
+
+/**
+ * A handler that sits in the server side JAX-WS processing pipeline between the XTS header
+ * context processor and the web service. Takes the WS transaction context provided by the
+ * former and maps it to a JTA transaction context for use by the latter. Handles Thread
+ * association of the JTA context.
+ *
+ * Note: we assume that there is a web services transaction context present and
+ * that the service needs a JTA context. The handler should not be registered on
+ * methods unless both these conditions hold.
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class JaxWSTxInboundBridgeHandler implements Handler
+{
+ private static final Logger log = Logger.getLogger(JaxWSTxInboundBridgeHandler.class);
+
+ /**
+ * Process a message. Determines if it is inbound or outbound and dispatches accordingly.
+ *
+ * @param msgContext the context to process
+ * @return true on success, false on error
+ */
+ public boolean handleMessage(MessageContext msgContext)
+ {
+ log.trace("handleMessage()");
+
+ Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ if (outbound == null)
+ throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+
+ return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
+ }
+
+ /**
+ * Tidy up the Transaction/Thread association before faults are thrown back to the client.
+ *
+ * @param messageContext unused
+ * @return true on success, false on error
+ */
+ public boolean handleFault(MessageContext messageContext)
+ {
+ log.trace("handleFault()");
+
+ return suspendTransaction();
+ }
+
+ public void close(MessageContext messageContext)
+ {
+ log.trace("close()");
+ }
+
+ /**
+ * Process inbound messages by mapping the WS transaction context
+ * to a JTA one and associating the latter to the current Thread.
+ *
+ * @param msgContext unused
+ * @return true on success, false on error
+ */
+ protected boolean handleInbound(MessageContext msgContext)
+ {
+ log.trace("handleInbound()");
+
+ try
+ {
+ InboundBridge inboundBridge = org.jboss.jbossts.txbridge.inbound.InboundBridgeManager.getInboundBridge();
+ inboundBridge.start();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Tidy up the Transaction/Thread association before returning a message to the client.
+ *
+ * @param msgContext unused
+ * @return true on success, false on error
+ */
+ protected boolean handleOutbound(MessageContext msgContext)
+ {
+ log.trace("handleOutbound()");
+
+ return suspendTransaction();
+ }
+
+ /**
+ * Break the association between the JTA transaction context and the calling Thread.
+ *
+ * @return true on success, false on error
+ */
+ private boolean suspendTransaction()
+ {
+ log.trace("suspendTransaction()");
+
+ try
+ {
+ org.jboss.jbossts.txbridge.inbound.InboundBridge inboundBridge = InboundBridgeManager.getInboundBridge();
+ inboundBridge.stop();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ return false;
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/BridgeSynchronization.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/BridgeSynchronization.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/BridgeSynchronization.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge.outbound;
+
+import org.apache.log4j.Logger;
+import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
+
+import javax.transaction.Synchronization;
+import javax.transaction.Status;
+
+import com.arjuna.ats.jta.utils.JTAHelper;
+
+/**
+ * Provides method call mapping between JTA parent coordinator and WS-AT subordinate transaction.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-06-01
+ */
+public class BridgeSynchronization implements Synchronization
+{
+ private static final Logger log = Logger.getLogger(BridgeSynchronization.class);
+
+ private final BridgeWrapper bridgeWrapper;
+
+ public BridgeSynchronization(BridgeWrapper bridgeWrapper)
+ {
+ log.trace("BridgeSynchronization(BridgeWrapper="+bridgeWrapper+")");
+
+ this.bridgeWrapper = bridgeWrapper;
+ }
+
+ /**
+ * The beforeCompletion method is called by the transaction manager prior to the start of the two-phase transaction commit process.
+ */
+ public void beforeCompletion()
+ {
+ log.trace("beforeCompletion()");
+
+ if(!bridgeWrapper.prepareVolatile())
+ {
+ // JTA does not explicitly provide for beforeCompletion signalling problems, but in
+ // our impl the engine will set the tx rollbackOnly if beforeCompletion throw an exception
+ // Note com.arjuna.ats.jta.TransactionManager.getTransaction().setRollbackOnly may also work.
+ throw new RuntimeException("BridgeWrapper.prepareVolatile() returned false");
+ }
+ }
+
+ /**
+ * This method is called by the transaction manager after the transaction is committed or rolled back.
+ *
+ * @param status the javax.transaction.Status representing the tx outcome.
+ */
+ public void afterCompletion(int status)
+ {
+ log.trace("afterCompletion(status="+status+"/"+ JTAHelper.stringForm(status)+")");
+
+ switch(status)
+ {
+ case Status.STATUS_COMMITTED:
+ bridgeWrapper.commitVolatile();
+ break;
+ case Status.STATUS_ROLLEDBACK:
+ bridgeWrapper.rollbackVolatile();
+ break;
+ default:
+ log.warn("unexpected Status "+status+", treating as ROLLEDBACK");
+ bridgeWrapper.rollbackVolatile();
+ }
+ }
+}
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/BridgeXAResource.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeXAResource.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/BridgeXAResource.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/BridgeXAResource.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,287 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author Red Hat Middleware LLC
+ */
+package org.jboss.jbossts.txbridge.outbound;
+
+import com.arjuna.wst.UnknownTransactionException;
+import org.apache.log4j.Logger;
+import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
+
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * Provides method call mapping between JTA parent coordinator and WS-AT subordinate transaction.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-02-10
+ */
+public class BridgeXAResource implements XAResource, Serializable
+{
+ // Design note: Given the way JBossTS is designed, we could subclass AbstractRecord rather than
+ // implementing XAResource, but this design is more standards friendly and thus portable.
+
+ private static final Logger log = Logger.getLogger(BridgeXAResource.class);
+
+ private transient volatile BridgeWrapper bridgeWrapper;
+
+ private volatile Uid externalTxId; // JTA i.e. parent id
+
+ private volatile String bridgeWrapperId; // XTS i.e. subordinate.
+
+ /**
+ * Create a new XAResource which wraps the subordinate WS-AT transaction.
+ *
+ * @param externalTxId the parent JTA transaction identifier.
+ * @param bridgeWrapper the control for the subordinate WS-AT transaction.
+ */
+ public BridgeXAResource(Uid externalTxId, BridgeWrapper bridgeWrapper)
+ {
+ log.trace("BridgeXARresource(TxId="+externalTxId+", BridgeWrapper="+bridgeWrapper+")");
+
+ this.externalTxId = externalTxId;
+ this.bridgeWrapper = bridgeWrapper;
+ bridgeWrapperId = bridgeWrapper.getIdentifier();
+ }
+
+ /**
+ * Serialization hook. Gathers and writes information needed for transaction recovery.
+ *
+ * @param out the stream to which the object state is serialized.
+ * @throws java.io.IOException if serialization fails.
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException
+ {
+ log.trace("writeObject() for tx id="+externalTxId);
+
+ //out.defaultWriteObject();
+ out.writeObject(externalTxId);
+ out.writeObject(bridgeWrapperId);
+ }
+
+ /**
+ * Deserialization hook. Unpacks transaction recovery information and uses it to
+ * recover the subordinate transaction.
+ *
+ * @param in the stream from which to unpack the object state.
+ * @throws IOException if deserialzation and recovery fail.
+ * @throws ClassNotFoundException if deserialzation fails.
+ */
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+ {
+ log.trace("readObject()");
+
+ //in.defaultReadObject();
+ externalTxId = (Uid)in.readObject();
+ bridgeWrapperId = (String)in.readObject();
+
+ try
+ {
+ bridgeWrapper = BridgeWrapper.recover(bridgeWrapperId);
+ // TODO: check for null!
+ }
+ catch(UnknownTransactionException unknownTransactionException)
+ {
+ log.error("Unable to recover subordinate transaction id="+bridgeWrapperId, unknownTransactionException);
+ IOException ioException = new IOException("unable to deserialize");
+ ioException.initCause(unknownTransactionException);
+ throw ioException;
+ }
+ }
+
+ /**
+ * Ask the resource manager to prepare for a transaction commit of the transaction specified in xid.
+ *
+ * @param xid A global transaction identifier
+ * @return A value indicating the resource manager's vote on the outcome of the transaction
+ * @throws XAException
+ */
+ public int prepare(Xid xid) throws XAException
+ {
+ log.trace("prepare(Xid="+xid+")");
+
+ // TwoPhaseOutcome needs converting to XAResource rtn type.
+ int twoPhaseOutcome = bridgeWrapper.prepare();
+
+ log.trace("prepare TwoPhaseOutcome is "+twoPhaseOutcome+"/"+TwoPhaseOutcome.stringForm(twoPhaseOutcome));
+
+ switch(twoPhaseOutcome)
+ {
+ case TwoPhaseOutcome.PREPARE_OK:
+ log.trace("prepare returning XAResource.XA_OK");
+ return XAResource.XA_OK;
+ case TwoPhaseOutcome.PREPARE_READONLY:
+ OutboundBridgeManager.removeMapping(externalTxId);
+ log.trace("prepare returning XAResource.XA_RDONLY");
+ return XAResource.XA_RDONLY;
+ default:
+ // TODO more find-grained error type handling
+ log.trace("prepare TwoPhaseOutcome is "+twoPhaseOutcome+"/"+
+ TwoPhaseOutcome.stringForm(twoPhaseOutcome)+", throwing XAException...");
+ XAException xaException = new XAException("unexpected oucome: "+TwoPhaseOutcome.stringForm(twoPhaseOutcome));
+ xaException.errorCode = XAException.XA_RBROLLBACK;
+ throw xaException;
+ }
+ }
+
+ /**
+ * Informs the resource manager to roll back work done on behalf of a transaction branch.
+ *
+ * @param xid A global transaction identifier
+ * @throws XAException
+ */
+ public void rollback(Xid xid) throws XAException
+ {
+ log.trace("rollback(Xid="+xid+")");
+
+ try
+ {
+ bridgeWrapper.rollback();
+ }
+ finally
+ {
+ OutboundBridgeManager.removeMapping(externalTxId);
+ }
+ }
+
+ /**
+ * Commits the global transaction specified by xid.
+ *
+ * @param xid A global transaction identifier
+ * @param onePhase
+ * @throws XAException
+ */
+ public void commit(Xid xid, boolean onePhase) throws XAException
+ {
+ log.trace("commit(Xid="+xid+", onePhase="+onePhase+")");
+
+ try
+ {
+ if(onePhase)
+ {
+ // no shortcuts, we have to do prepare anyhow
+ if(prepare(xid) == XAResource.XA_RDONLY)
+ {
+ return;
+ }
+ }
+
+ bridgeWrapper.commit();
+ }
+ finally
+ {
+ OutboundBridgeManager.removeMapping(externalTxId);
+ }
+ }
+
+ /**
+ * Starts work on behalf of a transaction branch specified in xid.
+ *
+ * @param xid A global transaction identifier
+ * @param flags
+ * @throws XAException
+ */
+ public void start(Xid xid, int flags) throws XAException
+ {
+ log.trace("start(Xid="+xid+", flags="+flags+")");
+
+ // do nothing
+ }
+
+ /**
+ * Ends the work performed on behalf of a transaction branch.
+ *
+ * @param xid A global transaction identifier
+ * @param flags
+ * @throws XAException
+ */
+ public void end(Xid xid, int flags) throws XAException
+ {
+ log.trace("end(Xid="+xid+", flags="+flags+")");
+
+ // do nothing
+ }
+
+ public boolean isSameRM(XAResource xaResource) throws XAException
+ {
+ log.trace("isSameRM(XAResource="+xaResource+")");
+
+ return false; // TODO
+ }
+
+ public void forget(Xid xid) throws XAException
+ {
+ log.trace("forget(Xid="+xid+")");
+
+ // TODO
+ }
+
+ /**
+ * Obtains a list of prepared transaction branches from a resource manager.
+ *
+ * @param flag
+ * @return
+ * @throws XAException
+ */
+ public Xid[] recover(int flag) throws XAException
+ {
+ log.trace("recover(flag="+flag+")");
+
+ return new Xid[0]; // TODO
+ }
+
+ /**
+ * Sets the current transaction timeout value for this XAResource instance.
+ *
+ * @param seconds - The transaction timeout value in seconds.
+ * @return true if the transaction timeout value is set successfully; otherwise false.
+ * @throws XAException
+ */
+ public boolean setTransactionTimeout(int seconds) throws XAException
+ {
+ log.trace("setTransactionTimeout(seconds="+seconds+")");
+
+ return false; // TODO
+ }
+
+ /**
+ * Obtains the current transaction timeout value set for this XAResource instance.
+ *
+ * @return the transaction timeout value in seconds.
+ * @throws XAException
+ */
+ public int getTransactionTimeout() throws XAException
+ {
+ log.trace("getTransactionTimeout()");
+
+ return 0; // TODO
+ }
+}
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/JaxWSTxOutboundBridgeHandler.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/JaxWSTxOutboundBridgeHandler.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/JaxWSTxOutboundBridgeHandler.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/JaxWSTxOutboundBridgeHandler.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,142 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author Red Hat Middleware LLC
+ */
+package org.jboss.jbossts.txbridge.outbound;
+
+import org.apache.log4j.Logger;
+
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+
+/**
+ * A handler that sits in the client side JAX-WS processing pipeline between the application
+ * and the XTS header context processor. Takes the JTA transaction context provided by the
+ * former and maps it to a WS-AT transaction context for use by the latter. Handles Thread
+ * association of the WS-AT context.
+ *
+ * Note: we assume that there is a JTA transaction context present and
+ * that the service needs a WS-AT context. The handler should not be registered on
+ * methods unless both these conditions hold.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-02-10
+ */
+public class JaxWSTxOutboundBridgeHandler implements Handler
+{
+ private static final Logger log = Logger.getLogger(JaxWSTxOutboundBridgeHandler.class);
+
+ /**
+ * Process a message. Determines if it is inbound or outbound and dispatches accordingly.
+ *
+ * @param msgContext the context to process
+ * @return true on success, false on error
+ */
+ public boolean handleMessage(MessageContext msgContext)
+ {
+ log.trace("handleMessage()");
+
+ Boolean outbound = (Boolean)msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+ if (outbound == null)
+ throw new IllegalStateException("Cannot obtain required property: " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+
+ return outbound ? handleOutbound(msgContext) : handleInbound(msgContext);
+ }
+
+ /**
+ * Tidy up the Transaction/Thread association before faults are thrown back to the client.
+ *
+ * @param messageContext unused
+ * @return true on success, false on error
+ */
+ public boolean handleFault(MessageContext messageContext)
+ {
+ log.trace("handleFault()");
+
+ return suspendTransaction();
+ }
+
+ public void close(MessageContext messageContext)
+ {
+ log.trace("close()");
+ }
+
+ /**
+ * Tidy up the Transaction/Thread association before returning a message to the client.
+ *
+ * @param msgContext unused
+ * @return true on success, false on error
+ */
+ protected boolean handleInbound(MessageContext msgContext)
+ {
+ log.trace("handleInbound()");
+
+ return suspendTransaction();
+ }
+
+ /**
+ * Process outbound messages by mapping the JTA transaction context
+ * to a WS-AT one and associating the latter to the current Thread.
+ *
+ * @param msgContext unused
+ * @return true on success, false on error
+ */
+ protected boolean handleOutbound(MessageContext msgContext)
+ {
+ log.trace("handleOutbound()");
+
+ try
+ {
+ OutboundBridge outboundBridge = OutboundBridgeManager.getOutboundBridge();
+ outboundBridge.start();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Break the association between the WS-AT transaction context and the calling Thread.
+ *
+ * @return true on success, false on error
+ */
+ private boolean suspendTransaction()
+ {
+ log.trace("suspendTransaction()");
+
+ try
+ {
+ OutboundBridge outboundBridge = OutboundBridgeManager.getOutboundBridge();
+ outboundBridge.stop();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ return false;
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridge.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridge.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridge.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridge.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author Red Hat Middleware LLC
+ */
+package org.jboss.jbossts.txbridge.outbound;
+
+import org.apache.log4j.Logger;
+import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
+import com.arjuna.mw.wst11.TransactionManagerFactory;
+import com.arjuna.mw.wst.TxContext;
+import com.arjuna.wst.SystemException;
+import com.arjuna.wst.UnknownTransactionException;
+
+/**
+ * Manages Thread association of the interposed coordinator.
+ * Typically called from handlers in the WS stack.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-02-10
+ */
+public class OutboundBridge
+{
+ private static final Logger log = Logger.getLogger(OutboundBridge.class);
+
+ /**
+ * Management object for the subordinate transaction
+ */
+ private final BridgeWrapper bridgeWrapper;
+
+ /**
+ * Create a new OutboundBridge to manage the given subordinate WS-AT transaction.
+ *
+ * @param bridgeWrapper the subordinate transaction controller
+ */
+ public OutboundBridge(BridgeWrapper bridgeWrapper)
+ {
+ log.trace("OutboundBridge(BridgeWrapper="+bridgeWrapper+")");
+
+ this.bridgeWrapper = bridgeWrapper;
+ }
+
+ /**
+ * Associate the WS-AT transaction to the current Thread.
+ * Typically used by the client side outbound handler.
+ *
+ * @throws UnknownTransactionException
+ * @throws SystemException
+ */
+ public void start() throws UnknownTransactionException, SystemException
+ {
+ log.trace("start(BridgeWrapper="+bridgeWrapper+")");
+
+ TxContext txContext = bridgeWrapper.getContext();
+
+ TransactionManagerFactory.transactionManager().resume(txContext);
+ }
+
+ /**
+ * Disassociate the WS-AT transaction from the current Thread.
+ * Typically used by the client side inbound handler.
+ *
+ * @throws SystemException
+ */
+ public void stop() throws SystemException
+ {
+ log.trace("stop(BridgeWrapper="+bridgeWrapper+")");
+
+ TransactionManagerFactory.transactionManager().suspend();
+ }
+}
Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridgeManager.java (from rev 31937, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridgeManager.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridgeManager.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,136 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author Red Hat Middleware LLC
+ */
+package org.jboss.jbossts.txbridge.outbound;
+
+import com.arjuna.ats.jta.TransactionManager;
+import com.arjuna.ats.jta.transaction.Transaction;
+import com.arjuna.ats.arjuna.common.Uid;
+
+import javax.transaction.SystemException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.xa.XAResource;
+
+import org.apache.log4j.Logger;
+import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Maintains the mapping data that relates JTA transactions to WS-AT subordinate transactions and related objects.
+ *
+ * The mappings are scoped to the singleton instance of this class and its lifetime.
+ * This poses problems where you have more than one instance (classloading, clusters)
+ * or where you need crash recovery. It short, it's rather limited.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-02-10
+ */
+public class OutboundBridgeManager
+{
+ private static final Logger log = Logger.getLogger(OutboundBridgeManager.class);
+
+ // maps JTA Tx Id to OutboundBridge instance.
+ private static final ConcurrentMap<Uid, org.jboss.jbossts.txbridge.outbound.OutboundBridge> outboundBridgeMappings = new ConcurrentHashMap<Uid, org.jboss.jbossts.txbridge.outbound.OutboundBridge>();
+
+ /**
+ * Return an OutboundBridge instance that maps the current Thread's JTA transaction context
+ * to a WS-AT transaction context. Control of the latter is provided by the returned instance.
+ *
+ * @return as OutboundBridge corresponding to the calling Thread's current JTA transaction context.
+ */
+ public static org.jboss.jbossts.txbridge.outbound.OutboundBridge getOutboundBridge()
+ {
+ log.trace("getOutboundBridge()");
+
+ try
+ {
+ Transaction transaction = (Transaction)TransactionManager.transactionManager().getTransaction();
+
+ Uid externalTxId = transaction.get_uid();
+
+ if(!outboundBridgeMappings.containsKey(externalTxId)) {
+ createMapping(transaction, externalTxId);
+ }
+
+ return outboundBridgeMappings.get(externalTxId);
+
+ }
+ catch(SystemException e)
+ {
+ log.error("problem", e);
+ }
+
+ return null;
+ }
+
+ /**
+ * Remove the mapping for the given externalTxId. This should be called for gc when the tx is finished.
+ *
+ * @param externalTxId The JTA transaction identifier.
+ */
+ public static synchronized void removeMapping(Uid externalTxId)
+ {
+ log.trace("removeMapping(externalTxId="+externalTxId+")");
+
+ if(externalTxId != null) {
+ outboundBridgeMappings.remove(externalTxId);
+ }
+ }
+
+ /**
+ * Create a WS-AT transaction mapping and support objects for a given JTA transaction context.
+ *
+ * @param externalTxId The JTA transaction identifier.
+ * @throws SystemException
+ */
+ private static synchronized void createMapping(Transaction transaction, Uid externalTxId) throws SystemException
+ {
+ log.trace("createmapping(externalTxId="+externalTxId+")");
+
+ if(outboundBridgeMappings.containsKey(externalTxId)) {
+ return;
+ }
+
+ // TODO: allow params to be configurable, or at least pass timeout down.
+ BridgeWrapper bridgeWrapper = BridgeWrapper.create(0, false);
+
+ org.jboss.jbossts.txbridge.outbound.OutboundBridge outboundBridge = new org.jboss.jbossts.txbridge.outbound.OutboundBridge(bridgeWrapper);
+ XAResource xaResource = new org.jboss.jbossts.txbridge.outbound.BridgeXAResource(externalTxId, bridgeWrapper);
+ Synchronization synchronization = new org.jboss.jbossts.txbridge.outbound.BridgeSynchronization(bridgeWrapper);
+
+ try
+ {
+ transaction.enlistResource(xaResource);
+ transaction.registerSynchronization(synchronization);
+ }
+ catch(RollbackException e)
+ {
+ log.error("Unable to enlist BridgeXAResource or register BridgeSynchronization: ", e);
+ throw new SystemException(e.toString());
+ }
+
+ outboundBridgeMappings.put(externalTxId, outboundBridge);
+ }
+}
\ No newline at end of file
Added: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridgeRecoveryManager.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridgeRecoveryManager.java (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/outbound/OutboundBridgeRecoveryManager.java 2010-03-05 11:17:50 UTC (rev 31955)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates,
+ * and individual contributors as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss, by Red Hat.
+ */
+package org.jboss.jbossts.txbridge.outbound;
+
+import com.arjuna.ats.arjuna.recovery.RecoveryManager;
+import com.arjuna.ats.arjuna.recovery.RecoveryModule;
+import org.apache.log4j.Logger;
+
+/**
+ * Integrates with JBossAS MC lifecycle and JBossTS recovery manager to provide
+ * recovery services for outbound bridged transactions.
+ *
+ * @author jonathan.halliday at redhat.com, 2010-03-05
+ */
+public class OutboundBridgeRecoveryManager implements RecoveryModule
+{
+ private static final Logger log = Logger.getLogger(OutboundBridgeRecoveryManager.class);
+
+ private final RecoveryManager acRecoveryManager = RecoveryManager.manager();
+
+ /**
+ * MC lifecycle callback, used to register components with the recovery manager.
+ */
+ public void start()
+ {
+ log.info("OutboundBridgeRecoveryManager starting");
+
+ acRecoveryManager.addModule(this);
+ }
+
+ /**
+ * MC lifecycle callback, used to unregister components from the recovery manager.
+ */
+ public void stop()
+ {
+ log.info("OutboundBridgeRecoveryManager stopping");
+
+ acRecoveryManager.removeModule(this, false);
+ }
+
+ /**
+ * Called by the RecoveryManager at start up, and then
+ * PERIODIC_RECOVERY_PERIOD seconds after the completion, for all RecoveryModules,
+ * of the second pass
+ */
+ @Override
+ public void periodicWorkFirstPass()
+ {
+ log.trace("periodicWorkFirstPass()");
+ }
+
+ /**
+ * Called by the RecoveryManager RECOVERY_BACKOFF_PERIOD seconds
+ * after the completion of the first pass
+ */
+ @Override
+ public void periodicWorkSecondPass()
+ {
+ log.trace("periodicWorkSecondPass()");
+
+ // TODO BridgeWrapper recovery scan for orphans - pending JBTM-725 work.
+ }
+}
Modified: labs/jbosstm/trunk/txbridge/tests/dd/jaxws-handlers-client.xml
===================================================================
--- labs/jbosstm/trunk/txbridge/tests/dd/jaxws-handlers-client.xml 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/tests/dd/jaxws-handlers-client.xml 2010-03-05 11:17:50 UTC (rev 31955)
@@ -37,7 +37,7 @@
<handler>
<handler-name>TransactionBridgeHandler</handler-name>
- <handler-class>org.jboss.jbossts.txbridge.JaxWSTxOutboundBridgeHandler</handler-class>
+ <handler-class>org.jboss.jbossts.txbridge.outbound.JaxWSTxOutboundBridgeHandler</handler-class>
</handler>
<handler>
Modified: labs/jbosstm/trunk/txbridge/tests/dd/jaxws-handlers-server.xml
===================================================================
--- labs/jbosstm/trunk/txbridge/tests/dd/jaxws-handlers-server.xml 2010-03-05 05:45:20 UTC (rev 31954)
+++ labs/jbosstm/trunk/txbridge/tests/dd/jaxws-handlers-server.xml 2010-03-05 11:17:50 UTC (rev 31955)
@@ -37,7 +37,7 @@
<handler>
<handler-name>TransactionBridgeHandler</handler-name>
- <handler-class>org.jboss.jbossts.txbridge.JaxWSTxInboundBridgeHandler</handler-class>
+ <handler-class>org.jboss.jbossts.txbridge.inbound.JaxWSTxInboundBridgeHandler</handler-class>
</handler>
<handler>
More information about the jboss-svn-commits
mailing list