FileDocCategorySizeDatePackage
ATParticipant.javaAPI DocExample26569Tue May 29 16:57:16 BST 2007com.sun.xml.ws.tx.at

ATParticipant

public class ATParticipant extends com.sun.xml.ws.tx.coordinator.Registrant
This class encapsulates a WS-AT participant.

A participant represents one of the three ws-at protocols: completion, volatile 2PC or durable 2PC.

Participant lifecycle consist of generating a endpoint reference

Transaction timeout from Participants perspective. Coordination Context expires specifies the period, measured from the point in time at which the context was first created or received, after which a transaction MAY be terminated solely due to its length of operation. A 2PC participant MAY elect to abort its work in the transaction so long as it has not already decided to prepare.

author
Ryan.Shoemaker@Sun.COM
version
$Revision: 1.15.2.1 $
since
1.0

Fields Summary
public static final URI
LOCAL_PPS_URI
protected STATE
state
protected Xid
xid
private com.sun.xml.ws.api.tx.Participant
participant
private final boolean
remoteParticipant
private static com.sun.xml.ws.tx.common.TxLogger
logger
static final String
WSAT_COORDINATOR
private EndpointReference
localParticipantProtocolService
Constructors Summary
public ATParticipant(com.sun.xml.ws.tx.coordinator.Coordinator parent, com.sun.xml.ws.api.tx.Participant participant)
Register will figure out if participant will register with local or remote Coordination Protocol Service.

        super(parent, participant.getProtocol());
        this.participant = participant;
        this.remoteParticipant = false;

        if (logger.isLogging(Level.FINEST)) {
            logger.finest("ATParticipant", getCoordIdPartId());
        }
        // TODO: implement participant timeout from parent.getExpires().
    
public ATParticipant(com.sun.xml.ws.tx.coordinator.Coordinator parent, com.sun.xml.ws.tx.webservice.member.coord.RegisterType registerRequest)
Remote ATParticipant with a local Coordinator. ParticipantProtocolService received as part of registerRequest.

        super(parent, registerRequest);
        if (logger.isLogging(Level.FINEST)) {
            logger.finest("Remote ATParticipant", getCoordIdPartId());
        }
        participant = null;
        setCoordinatorProtocolService(exportCoordinatorProtocolServiceForATParticipant(parent));
        remoteParticipant = true;
        if (logger.isLogging(Level.FINEST)) {
            logger.finest("Remote ATParticipant:", getCoordIdPartId() + " CPS:" + getCoordinatorProtocolService());
        }
    
Methods Summary
public voidabort()

        if (logger.isLogging(Level.FINER)) {
            logger.entering("abort", getCoordIdPartId());
        }

        //TODO. put switch statement over all possible 2pc transaction state.
        //      invalid states require fault to be sent

        state = STATE.ABORTING;

        // local rollback
        if (participant != null) {
            participant.abort();
            participant = null;   // no need to contact participant anymore
        }
        // pass rollback to remote participant
        if (remoteParticipant) {
            remoteRollback();
        } else {
            localRollback();
        }

        if (logger.isLogging(Level.FINER)) {
            logger.exiting("abort", getCoordIdPartId());
        }
    
voidaborted()

        // TODO: verify state transition does not need to throw invalid state fault.
        state = STATE.ABORTED;
        if (logger.isLogging(Level.FINE)) {
            logger.fine("aborted", this.getCoordIdPartId() + " STATE=" + state.toString());
        }
    
public voidcommit()

        if (logger.isLogging(Level.FINER)) {
            logger.entering("commit" + getCoordIdPartId());
        }
        if (remoteParticipant) {
            remoteCommit();
        } else {
            localCommit();
        }
        if (logger.isLogging(Level.FINER)) {
            logger.entering("commit" + getCoordIdPartId());
        }
    
voidcommitted()

        // TODO: verify state transition does not need to throw invalid state fault.
        state = STATE.COMMITTED;
        if (logger.isLogging(Level.FINE)) {
            logger.fine("committed", this.getCoordIdPartId() + " STATE=" + state.toString());
        }
    
javax.xml.soap.SOAPFaultcreateSOAPFault(java.lang.String message)

see
com.sun.xml.ws.tx.common.WsaHelper
deprecated
since now

        try {
            final SOAPFault fault = SOAPVersion.SOAP_11.saajSoapFactory.createFault();
            fault.setFaultString(message);
            // TODO: fix deprecated constant reference
            // fault.setFaultCode(JAXWSAConstants.SOAP11_SENDER_QNAME);
            fault.appendFaultSubcode(new QName(WSAT_SOAP_NSURI, "InconsistentInternalState"));
            fault.setFaultRole("A global consistent failure has occurred. This is an unrecoverable condition.");
            return fault;
        } catch (SOAPException ex) {
            throw new WebServiceException(ex);
        }
    
private javax.xml.ws.EndpointReferenceexportCoordinatorProtocolServiceForATParticipant(com.sun.xml.ws.tx.coordinator.Coordinator coord)

    
         
        return StatefulWebserviceFactoryFactory.getInstance().createService(WSAT_COORDINATOR, "Coordinator",
                ATCoordinator.localCoordinationProtocolServiceURI, AddressingVersion.MEMBER,
                coord.getIdValue(), this.getIdValue());
    
public voidforget()
A participant is forgotten after it has sent committed or aborted to coordinator.

        if (isRemoteCPS() && localParticipantProtocolService != null) {
            final ParticipantPortTypeImpl ppti = 
                    ParticipantPortTypeImpl.getManager().resolve(localParticipantProtocolService);
            
            // could resolve to null if stateful webservice timeout already unexported automatically.
            if (ppti != null) {
                ParticipantPortTypeImpl.getManager().unexport(ppti);
            } 
        }
        localParticipantProtocolService = null;
        if (remoteParticipant) {
            final CoordinatorPortTypeImpl cpti = CoordinatorPortTypeImpl.getManager().resolve(getCoordinatorProtocolService());
            if (cpti != null) {
                CoordinatorPortTypeImpl.getManager().unexport(cpti);
            }
        }
        
        getATCoordinator().forget(this);
    
public ATCoordinatorgetATCoordinator()

        return (ATCoordinator) getCoordinator();
    
private com.sun.xml.ws.tx.webservice.member.at.CoordinatorPortTypegetATCoordinatorWS(boolean nonterminalNotify)

        if (getCoordinatorProtocolService() == null && !isRegistrationCompleted()) {
            logger.warning("getATCoordinatorWS",
                    LocalizationMessages.NO_REG_RESP_0014(
                            getATCoordinator().getContext().getRootRegistrationService().toString(),
                            getCoordIdPartId()));
        }

        return getATCoordinatorWS(getCoordinatorProtocolService(),
                getParticipantProtocolService(), nonterminalNotify);
    
public static com.sun.xml.ws.tx.webservice.member.at.CoordinatorPortTypegetATCoordinatorWS(javax.xml.ws.EndpointReference toCPS, javax.xml.ws.EndpointReference replyToPPS, boolean nonterminalNotify)

        final OneWayFeature owf = new OneWayFeature();
        WSEndpointReference wsepr = null;
        if (nonterminalNotify && replyToPPS != null) {
            try {
                wsepr = new WSEndpointReference(replyToPPS);
            } catch (Exception xse) {
                logger.severe("getATCoordinatorWS", LocalizationMessages.REPLYTOPPS_EPR_EXCEPTION_0015(replyToPPS.toString(), xse.getLocalizedMessage()));
            }
            if (wsepr != null) {
                owf.setReplyTo(wsepr);
            } else {
                logger.warning("getATCoordinatorWS", LocalizationMessages.NULL_PPS_EPR_WARNING_0016());
            }
        }
        assert toCPS != null;
        return ATCoordinator.getWSATCoordinatorService().getCoordinator(toCPS, owf);
    
private com.sun.xml.ws.tx.webservice.member.at.ParticipantPortTypegetATParticipantWS(boolean nonterminalNotification)

        return this.getATParticipantWS(this.getParticipantProtocolService(),
                this.getCoordinatorProtocolService(), nonterminalNotification);
    
public static com.sun.xml.ws.tx.webservice.member.at.ParticipantPortTypegetATParticipantWS(javax.xml.ws.EndpointReference toPPS, javax.xml.ws.EndpointReference replyToCPS, boolean nonterminalNotification)

        final OneWayFeature owf = new OneWayFeature();
        WSEndpointReference wsepr = null;
        if (nonterminalNotification && replyToCPS != null) {
            try {
                wsepr = new WSEndpointReference(replyToCPS);
            } catch (Exception xse) {
                logger.severe("getATCoordinatorWS", LocalizationMessages.REPLYTOPPS_EPR_EXCEPTION_0015(replyToCPS.toString(), xse.getLocalizedMessage()));
            }
            if (wsepr != null) {
                owf.setReplyTo(wsepr);
            } else {
                logger.warning("getATParticipantWS", LocalizationMessages.NULL_CPS_EPR_WARNING_0018());
            }
            
        }
        assert toPPS != null;
        return ATCoordinator.getWSATCoordinatorService().getParticipant(toPPS, owf);
    
private java.lang.StringgetCoordIdPartId()

        return " coordId=" + getCoordinator().getIdValue() + " partId=" + getIdValue() + " ";
    
public javax.xml.ws.EndpointReferencegetLocalParticipantProtocolService()
No need to export an external stateful web service for this usage case.


                      
       
        if (localParticipantProtocolService == null) {
            if (isRemoteCPS()) {
                final StatefulWebserviceFactory swf = StatefulWebserviceFactoryFactory.getInstance();
                localParticipantProtocolService =
                        swf.createService(WSAT_COORDINATOR, "Participant",
                                LOCAL_PPS_URI, AddressingVersion.MEMBER,
                                getATCoordinator().getIdValue(), this.getId().getValue());
            } else {
                localParticipantProtocolService = getLocalParticipantProtocolServiceEPR();
            }
        }
        return localParticipantProtocolService;
    
public static javax.xml.ws.EndpointReferencegetLocalParticipantProtocolServiceEPR()

         final MemberSubmissionEndpointReference epr = new MemberSubmissionEndpointReference();
         epr.addr = new MemberSubmissionEndpointReference.Address();
         epr.addr.uri = LOCAL_PPS_URI.toString();
         return epr;
    
public com.sun.xml.ws.tx.webservice.member.at.ParticipantPortTypegetParticipantPort(javax.xml.ws.EndpointReference epr)

        return ATCoordinator.getWSATCoordinatorService().getParticipant(epr);
    
public com.sun.xml.ws.tx.at.ATParticipant$STATEgetState()
Return participant's state for Atomic Transaction 2PC Protocol.

        return state;
    
protected javax.transaction.xa.XidgetXid()

        return xid;
    
private voidinternalPrepare()

        if (remoteParticipant) {
            remotePrepare();
        } else {
            localPrepare();
        }
    
public booleanisDurable()

        return getProtocol() == Protocol.DURABLE;
    
public booleanisVolatile()

        return getProtocol() == Protocol.VOLATILE;
    
private voidlocalCommit()

        final String METHOD_NAME = "localCommit";
        switch (getState()) {
            case NONE:

                // TODO send committed using wsa:replyTo EPR.
                // this case
                break;
            case ABORTING:
                logger.warning(METHOD_NAME, LocalizationMessages.INCONSISTENT_STATE_0020(getState(), getCoordIdPartId())); 
                //fault wsat:InconsistentInternalState
                abort();

                break;
            case ACTIVE:
            case PREPARING:
            case PREPARED:
                logger.warning(METHOD_NAME, LocalizationMessages.INCONSISTENT_STATE_0020(getState(), getCoordIdPartId()));
                // TODO throw fault coor:InvalidState
                abort();
                break;

            case PREPARED_SUCCESS:
                state = STATE.COMMITTING;
                participant.commit();
                participant = null;   // no longer need to contact participant.
                if (logger.isLogging(Level.FINE)) {
                    logger.fine(METHOD_NAME, "committed " + getCoordIdPartId());
                }
                if (isRemoteCPS()) {
                    try {
                        getATCoordinatorWS(false).committedOperation(null);
                    } catch (WebServiceException wse) {
                        logger.warning(METHOD_NAME, LocalizationMessages.COMMITTED_FAILED_0021(wse.getLocalizedMessage()));
                        throw wse;
                    }
                } else {
                    getATCoordinator().committed(getIdValue());
                }
                forget();
                break;

            case COMMITTING:
                if (isRemoteCPS()) {
                    getATCoordinatorWS(false).committedOperation(null);
                } else {
                    getATCoordinator().committed(getIdValue());
                }
                forget();

                break;
        }
    
private voidlocalPrepare()

        final String METHOD_NAME = "localPrepare";
        if (logger.isLogging(Level.FINER)) {
            logger.entering(METHOD_NAME, getCoordIdPartId());
        }
        Participant.STATE result = null;
        state = STATE.PREPARING;
        try {
            result = participant.prepare();
        } catch (TXException e) {
            // failure during prepare, just abort

            // set participant to null. don't want to call its abort(), it already knows its aborted
            participant = null;
            abort();
            throw new TXException("Rollback");
        } catch (Exception e) {
            participant = null;
            abort();
            throw new TXException("Rollback");
        }
        switch (result) {
            case P_OK:
                state = STATE.PREPARED;
                if (isRemoteCPS()) {
                    if (logger.isLogging(Level.FINEST)) {
                        logger.finest(METHOD_NAME, "send prepared to remote coordinator"
                                + getIdValue());
                    }
                    try {
                        getATCoordinatorWS(true).preparedOperation(null);
                    } catch (WebServiceException wse) {
                        logger.warning(METHOD_NAME, LocalizationMessages.PREPARE_FAILED_0010(wse.getLocalizedMessage()));
                        throw wse;
                    }
                } else {
                    if (logger.isLogging(Level.FINEST)) {
                        logger.finest(METHOD_NAME, "send prepared to local coordinator"
                                + getIdValue());
                    }
                    getATCoordinator().prepared(this.getIdValue());
                }
                state = STATE.PREPARED_SUCCESS;
                break;

            case P_READONLY:
                state = STATE.READONLY;
                if (isRemoteCPS()) {
                    if (logger.isLogging(Level.FINEST)) {
                        logger.finest(METHOD_NAME, "send readonly to remote coordinator for participant id"
                                + getIdValue());
                    }
                    try {
                        getATCoordinatorWS(false).readOnlyOperation(null);
                    } catch (WebServiceException wse) {
                         logger.warning(METHOD_NAME, "readonly to web service failed. "
                                        + wse.getLocalizedMessage());
                         throw wse;
                    }
                } else {
                    if (logger.isLogging(Level.FINEST)) {
                        logger.finest(METHOD_NAME, "send readonly to remote coordinator for participant id" +
                                getIdValue());
                    }
                    getATCoordinator().readonly(getIdValue());
                }
                if (logger.isLogging(Level.FINE)) {
                    logger.fine(METHOD_NAME, "readonly " + getCoordIdPartId());
                }
                forget();
                break;
        }
        if (logger.isLogging(Level.FINER)) {
            logger.exiting("ATParticipant.localPrepare");
        }
    
private voidlocalRollback()

        if (isRemoteCPS()) {
            try {
                getATCoordinatorWS(false).abortedOperation(null);
            } catch (WebServiceException wse) {
                logger.warning("localRollback", LocalizationMessages.PREPARED_FAILED_0019(wse.getLocalizedMessage()));
                throw wse;
            }
        } else {
            getATCoordinator().aborted(getIdValue());
        }

        if (logger.isLogging(Level.FINE)) {
            logger.fine("abort", getCoordIdPartId());
        }
        forget();
    
public voidprepare()
Returns participant state. or (something for abort).

        final String METHOD_NAME = "prepare";
        
        if (logger.isLogging(Level.FINER)) {
            logger.entering(METHOD_NAME, "coordId=" + getCoordinator().getIdValue() + " partId=" + getIdValue());
        }
        switch (getState()) {
            case NONE:
            case ABORTING:
                abort();
                throw new TXException("Rollback");

            case ACTIVE:
                internalPrepare();
                break;

            case PREPARED_SUCCESS:
                // just resend
                if (isRemoteCPS()) {
                    try {
                        getATCoordinatorWS(true).preparedOperation(null);
                    } catch (WebServiceException wse) {
                        logger.warning(METHOD_NAME, LocalizationMessages.PREPARE_FAILED_0010(wse.getLocalizedMessage()));
                       
                        throw wse;
                    } catch (Exception e) {
                        logger.severe(METHOD_NAME, LocalizationMessages.PREPARE_FAILED_0010(e.getLocalizedMessage()));
                    }
                } else {
                    getATCoordinator().prepared(getIdValue());
                }
                break;
                
            case PREPARING:
            case PREPARED:
            case COMMITTING:
                // ignore PREPARE in these states
                break;
        }
        if (logger.isLogging(Level.FINER)) {
            logger.exiting(METHOD_NAME, "coordId=" + getCoordinator().getIdValue() + " partId=" + getIdValue());
        }
    
voidprepared()

        // TODO:  given current state, check if it is valid to set to this state.
        state = STATE.PREPARED_SUCCESS;
         if (logger.isLogging(Level.FINE)) {
            logger.fine("prepared", this.getCoordIdPartId() + " STATE=" + state.toString());
        }
    
voidreadonly()

        // TODO: verify state transition does not need to throw invalid state fault.
        state = STATE.READONLY;
        if (logger.isLogging(Level.FINE)) {
            logger.fine("readonly", this.getCoordIdPartId() + " STATE=" + state.toString());
        }
    
private voidremoteCommit()
Send Terminal notification

        // TODO: resend if don't receive committed notification from coordinator in some communication timeout amount of time

        if (logger.isLogging(Level.FINER)) {
            logger.entering("remoteCommit()", getIdValue());
        }
        this.getATParticipantWS(true).commitOperation(null);
        if (logger.isLogging(Level.FINER)) {
            logger.exiting("remoteCommit");
        }
    
private voidremotePrepare()

        state = STATE.PREPARING;
        // TODO: resend if don't receive prepared notfication from coordinator in some communication timeout amount of time
        try {
            getATParticipantWS(true).prepareOperation(null);
        } catch (WebServiceException wse) {
            logger.warning("remotePrepare", LocalizationMessages.PREPARE_FAILED_0010(wse.getLocalizedMessage()));
            throw wse;
        } catch (Exception e) {
            logger.severe("remotePrepare", LocalizationMessages.PREPARE_FAILED_0010(e.getLocalizedMessage()));
        }
    
private voidremoteRollback()
Send terminal notification

        // TODO: resend if don't receive aborted notification from coordinator in some communication timeout amount of time

        if (logger.isLogging(Level.FINER)) {
            logger.entering("remoteRollack", getCoordIdPartId());
        }
        getATParticipantWS(true).rollbackOperation(null);
        if (logger.isLogging(Level.FINER)) {
            logger.exiting("remoteRollback", getCoordIdPartId());
        }
    
public voidsetCoordinatorProtocolService(javax.xml.ws.EndpointReference cps)

        super.setCoordinatorProtocolService(cps);

        if (cps != null) {
            // wscoor:registerResponse successfully communicated CPS, change participant's state
            state = STATE.ACTIVE;
        }