org.jboss.jbossts.xts.bridge.at.BridgeWrapper Maven / Gradle / Ivy
package org.jboss.jbossts.xts.bridge.at;
import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator;
import com.arjuna.mwlabs.wst11.at.ContextFactoryImple;
import com.arjuna.mwlabs.wst11.at.context.TxContextImple;
import com.arjuna.mw.wst.TxContext;
import com.arjuna.wst.UnknownTransactionException;
import com.arjuna.wsc11.ContextFactoryMapper;
import com.arjuna.webservices11.wsat.AtomicTransactionConstants;
import com.arjuna.wst.SystemException;
import org.jboss.jbossts.xts.recovery.participant.at.XTSATRecoveryManager;
/**
* An API class for use by the JTA ==> AT bridge manager providing a wrapper around a subordinate transaction.
* Static methods are provided to create and register a WS-AT subordinate transaction or to locate a recovered
* transaction. The returned wrapper allows a client to drive the coordinator through prepare, (phase 2) commit
* and/or rollback, to access the transaction id under which the coordinator is registered and, if the transaction
* has not been recovered, to obtain a resumable tx context for the transaction.
*
* n.b. this class only supports bridging to WS-AT 1.1 transactions.
*/
public class BridgeWrapper
{
/**
* cached reference to the WS-AT 1.1. context factory - we only support bridging to WS-AT 1.1 subordinate
* transactions
*/
private static ContextFactoryImple contextFactory =
(ContextFactoryImple)ContextFactoryMapper.getMapper().getContextFactory(AtomicTransactionConstants.WSAT_PROTOCOL);
/**
* this class handles all creation of bridged transactions
*/
private BridgeWrapper()
{
}
/**
* the standard type string used to identify AT AT subordinate transactions. bridge clients
* must ensure that they do not employ this type for their subordinates.
*/
public static final String SUBORDINATE_TX_TYPE_AT_AT = SubordinateATCoordinator.SUBORDINATE_TX_TYPE_AT_AT;
/**
* create an AT 1.1 subordinate transaction, associate it with the AT 1.1. registry then return a
* BridgedTransaction wrapper allowing the transaction to be driven through prepare, commit
* and/or rollback and providing access to the transaction id and a context which can be used to
* resume the transaction.
* @param subordinateType a unique string which groups subordinates for the benefit of their parent
* tx/app and allows them to be identified and retrieved as a group during recovery. this must differ
* from the string {@link SUBORDINATE_TX_TYPE_AT_AT}
* @param expires the timeout for the bridged-to transaction or 0 if no timeout is required
* @param isSecure true if AT 1.1. protocol messages for the bridged-to transaction should employ
* secure communications, otherwise false
* @return a wrapper for the bridged-to transaction
* @throws SystemException
*/
public static BridgeWrapper create(String subordinateType, long expires, boolean isSecure)
{
// the AT 1.1 context factory provides us with a means to create the required data.
ContextFactoryImple.BridgeTxData bridgeTxData = contextFactory.createBridgedTransaction(subordinateType, expires, isSecure);
if (bridgeTxData != null) {
BridgeWrapper bridgeWrapper = new BridgeWrapper();
bridgeWrapper.context = new TxContextImple(bridgeTxData.context);
bridgeWrapper.coordinator = bridgeTxData.coordinator;
bridgeWrapper.id = bridgeTxData.identifier;
bridgeWrapper.subordinateType = subordinateType;
return bridgeWrapper;
} else {
return null;
}
}
/**
* recreate a wrapper for a bridged-to WS-AT 1.1 transaction recovered from the log
* @param identifier the identifier of a previously created bridged-to transaction
* @return a wrapper for the bridged-to transaction or null if it may still be awaiting recovery
* @throws UnknownTransactionException if recovery has been performed and no transaction with the
* given identifier has been found in the log
*/
public static BridgeWrapper recover(String identifier) throws UnknownTransactionException
{
SubordinateATCoordinator coordinator = SubordinateATCoordinator.getRecoveredCoordinator(identifier);
if (coordinator != null) {
BridgeWrapper bridgeWrapper = new BridgeWrapper();
bridgeWrapper.context = null;
bridgeWrapper.coordinator =coordinator;
bridgeWrapper.id = identifier;
bridgeWrapper.subordinateType = coordinator.getSubordinateType();
return bridgeWrapper;
} else {
XTSATRecoveryManager recoveryManager = XTSATRecoveryManager.getRecoveryManager();
if (recoveryManager != null && recoveryManager.isCoordinatorRecoveryStarted()) {
throw new UnknownTransactionException();
} else {
return null;
}
}
}
/**
* return a list of bridge wrappers for all recovered subordinate transactions with a given
* subordinate type
* @param subordinateType the subordinate type supplied in the original bridge wrapper create call
* which created the subordinate transaction.
* @return a possibly zero-length array of bridge wrappers for all recovered subordinate AT transactions
* with the given subordinate type or null if a subordinate coordinator recovery scan has not yet occurred
*/
public static BridgeWrapper[] scan(String subordinateType)
{
// return null if not yet ready
XTSATRecoveryManager recoveryManager = XTSATRecoveryManager.getRecoveryManager();
if (!recoveryManager.isCoordinatorRecoveryStarted()) {
return null;
}
// refuse to expose the internal AT - AT subordinates
if (subordinateType == null || subordinateType.equals(SUBORDINATE_TX_TYPE_AT_AT)) {
return EMPTY_SCAN;
}
SubordinateATCoordinator[] coordinators = SubordinateATCoordinator.listRecoveredCoordinators();
int count = 0;
for (int i = 0; i < coordinators.length; i++) {
if (coordinators[i].getSubordinateType().equals(subordinateType)) {
count++;
}
}
if (count == 0) {
return EMPTY_SCAN;
}
BridgeWrapper[] result = new BridgeWrapper[count];
count = 0;
for (int i = 0; i < coordinators.length; i++) {
SubordinateATCoordinator coordinator = coordinators[i];
if (coordinator.getSubordinateType().equals(subordinateType)) {
BridgeWrapper bridgeWrapper = new BridgeWrapper();
bridgeWrapper.context = null;
bridgeWrapper.coordinator = coordinator;
bridgeWrapper.id = coordinator.get_uid().stringForm();
bridgeWrapper.subordinateType = coordinator.getSubordinateType();
result[count++] = bridgeWrapper;
}
}
return result;
}
/**
* obtain the identifier for the bridged-to transaction
* @return the identifier for the bridged-to transaction
*/
public String getIdentifier()
{
return id;
}
/**
* obtain a resumable transaction context for the bridged-to transaction
* @return a resumable transaction context
* @throws UnknownTransactionException if this transaction has been recovered from the log and hence
* has no associated transaction context.
*/
public TxContext getContext() throws UnknownTransactionException
{
if (context != null) {
return context;
} else {
throw new UnknownTransactionException();
}
}
/**
* obtain the subordinate type for the bridged-to transaction
* @return the subordinate type for the bridged-to transaction
*/
public String getSubordinateType()
{
return subordinateType;
}
/**
* initiate synchronization beforeCompletion processing for the bridged-to transaction
*
* @return true if the beforeCompletion succeeds otherwise false.
*/
public boolean prepareVolatile()
{
return coordinator.prepareVolatile();
}
/**
* prepare the bridged-to transaction
* @return the result of preparing the transaction
*/
public int prepare ()
{
return coordinator.prepare();
}
/**
* initiate synchronization afterCompletion processing for the bridged-to transaction following a
* successful commit
*/
public void commitVolatile()
{
coordinator.commitVolatile();
}
/**
* perform a phase 2 commit for the bridged-to transaction
*/
public void commit ()
{
coordinator.commit();
}
/**
* initiate synchronization afterCompletion processing for the bridged-to transaction following a
* rollback
*/
public void rollbackVolatile()
{
coordinator.rollbackVolatile();
}
/**
* rollback the bridged-to transaction
*/
public void rollback ()
{
coordinator.rollback();
}
private SubordinateATCoordinator coordinator;
private TxContext context;
private String id;
private String subordinateType;
private final static BridgeWrapper[] EMPTY_SCAN = new BridgeWrapper[0];
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy