FileDocCategorySizeDatePackage
RegistrationManager.javaAPI DocExample25587Tue May 29 16:57:18 BST 2007com.sun.xml.ws.tx.coordinator

RegistrationManager

public final class RegistrationManager extends Object
This singleton class handles the register and registerResponse operations for both local and remote (or external) clients. The exposed web service endpoints for register and registerResponse delegate to the methods in this class.
author
Ryan.Shoemaker@Sun.COM
version
$Revision: 1.15.2.1 $
since
1.0

Fields Summary
private static final RegistrationManager
instance
private static final URI
localRegistrationURI
private static final URI
localAsynchronousRegistrationURI
private static final URI
localRegistrationRequesterURI
private static com.sun.xml.ws.tx.common.TxLogger
logger
private static final CoordinationManager
coordinationManager
reference to the CoordinationManager
private static final com.sun.xml.ws.tx.webservice.member.coord.Coordinator
coordinatorService
Constructors Summary
private RegistrationManager()
Singleton constructor


           
      
    
Methods Summary
private com.sun.xml.ws.tx.webservice.member.coord.CoordinatorgetCoordinatorService()


    
       
        return coordinatorService;
    
public static com.sun.xml.ws.tx.coordinator.RegistrationManagergetInstance()
Get the singleton instance of the RegistrationManager

return
the RegistrationManager

        return instance;
    
public static java.net.URIgetLocalAsyncRegistrationURI()

        return localAsynchronousRegistrationURI;
    
public static java.net.URIgetLocalRegistrationRequesterURI()

        return localRegistrationRequesterURI;
    
public static java.net.URIgetLocalRegistrationURI()


//    public static EndpointReference newSynchronousRegistrationEPR(ActivityIdentifier activityId) {
//        EndpointReference registrationEPR =
//                WsaHelper.getAddressingBuilder().newEndpointReference(localRegistrationURI);
//        WsaHelper.addRefParam(registrationEPR, activityId.getSOAPElement());
//        return registrationEPR;
//    }

        
        return localRegistrationURI;
    
public static com.sun.xml.ws.developer.StatefulWebServiceManagergetRegistrationCoordinatorStatefulWebServiceManager()

        StatefulWebserviceFactory swf = StatefulWebserviceFactoryFactory.getInstance();
        return swf.getManager("Coordinator", "RegistrationCoordinator");
    
public static javax.xml.ws.EndpointReferencenewRegistrationEPR(com.sun.xml.ws.tx.common.ActivityIdentifier activityId)
Create a new EPR for our registration service.

Note: as a side-effect, this method creates a stateful instance of the registration service that will handle correlation when a client actually registers with us. Should we consider moving this code to point of use (ie during coordination context creation)?

param
activityId the coordination id for this activity, maintained as state in the registration service
return
an EPR containing the address of our registration service

        StatefulWebserviceFactory swf = StatefulWebserviceFactoryFactory.getInstance();
        return swf.createService("Coordinator", "RegistrationCoordinator",
                localAsynchronousRegistrationURI, AddressingVersion.MEMBER,
                activityId.getValue(), null);
    
public voidregister(Coordinator c, Registrant r)
This is the local entry point for register. Depending on the root registration service contained in the coordinator, this method will either invoke registerOperation on a remote registration service or simply register locally with our registration service.

param
c Coordinator
param
r registrant

        if (logger.isLogging(Level.FINER)) {
            logger.entering("RegistrationManager.register(Coordinator, Registrant)");
        }

        EndpointReference registrationEPR;
        if (c.registerWithRootRegistrationService(r)) {
            if (logger.isLogging(Level.FINE)) {
                logger.fine("RegistrationManager.register", "register with remote coordinator");
            }
            // if subordinate, send <register> message to root, wait for <registerResponse>, then return
            registrationEPR = c.getContext().getRootRegistrationService();
            r.setRemoteCPS(true);
            assert (registrationEPR != null);

            // Send register to remote registration coordinator to get Coordinator Protocol Service
            assert r.getCoordinatorProtocolService() == null;

            // Set register parameter. Same for both synchronous and asynchronous.
            RegisterType registerParam = new RegisterType();
            registerParam.setProtocolIdentifier(r.getProtocol().getUri());
            MemberSubmissionEndpointReference ppsEpr =
                    (MemberSubmissionEndpointReference) r.getLocalParticipantProtocolService();
            registerParam.setParticipantProtocolService(ppsEpr);
            if (logger.isLogging(Level.FINE)) {
                logger.fine("register", "participant protocol service" + ppsEpr.toString());
            }

            // try synchronous register first and fallback to async if it fails
            // if (synchronousRegister(registrationEPR, c, registerParam, r)) return;

            // Asynchronous register/wait for asynchronous registerReply

            // setup stateful ws instance for registerResponse from remote registration coordinator
            StatefulWebserviceFactory swf = StatefulWebserviceFactoryFactory.getInstance();
            EndpointReference registrationRequesterEPR =
                    swf.createService("Coordinator", "RegistrationRequester",
                            localRegistrationRequesterURI, AddressingVersion.MEMBER,
                            r.getCoordinator().getIdValue(), r.getIdValue());

            // set replyTo for outgoing register message
            OneWayFeature owf = new OneWayFeature();
            owf.setReplyTo((new WSEndpointReference(registrationRequesterEPR)));
            RegistrationCoordinatorPortType registerCoordinator =
                    getCoordinatorService().getRegistrationCoordinator(registrationEPR, (WebServiceFeature) owf);

            if (logger.isLogging(Level.FINEST)) {
                logger.finest("RegistrationManager.register", "send wscoor:register to epr:" + registrationEPR
                        + " replyTo EPR: " + owf.getReplyTo());
            }

            boolean timedOut;
            r.setRegistrationCompleted(false);
            try {
                // prefer to try synchronouos register/register response than busy wait.
                registerCoordinator.registerOperation(registerParam);

                // next line is necessary. race condition that register did not complete before
                // tranaction initiator committed/rolled back tranaction.
                // This is why synchronous register preferable to asynchronous register.
                timedOut = r.waitForRegistrationResponse();
                if(logger.isLogging(Level.FINEST)) {
                    logger.finest("register(Coordinator, Registrant)", "timedOut = " + timedOut);
                }
            } catch (WebServiceException wse) {
                logger.warning("register",
                        LocalizationMessages.REGISTER_FAILED_3006(
                                registrationEPR, c.getIdValue(), wse.getLocalizedMessage()));
                throw wse;
            }

            if (r.isRegistrationCompleted()) {
                if (logger.isLogging(Level.FINE)) {
                    logger.fine("register", "asynch registration succeeded. Coordinator Protocol Service is " +
                            r.getCoordinatorProtocolService());
                }
            }

            if(timedOut) {
                // send fault S4.4 wscoor:No Activity
                WsaHelper.sendFault(
                        null,
                        registrationEPR,
                        SOAPVersion.SOAP_11,
                        TxFault.NoActivity,
                        "registration timed out for activity id: " + c.getIdValue(),  // no I18N - spec requires xml:lang="en"
                        null /* TODO: what is RelatesTo in this case? */ );
                logger.warning("register", LocalizationMessages.REGISTRATION_TIMEOUT_3007(c.getIdValue(), registrationEPR));
            }

            // reply processed in #registerResponse(WebServiceContext, RegisterResponseType) gets CPS for registrant.
        } else {
            if (logger.isLogging(Level.FINE)) {
                logger.fine("RegistrationManager.register", "register with local coordinator");
            }
            // else root coordinator, simply register and return
            r.setCoordinatorProtocolService(c.getCoordinatorProtocolServiceForRegistrant(r));
            c.addRegistrant(r, null);
        }

        if (logger.isLogging(Level.FINER)) {
            logger.exiting("RegistrationManager.register(Coordinator, Registrant)");
        }
    
public voidregister(javax.xml.ws.WebServiceContext wsContext, java.lang.String activityId, com.sun.xml.ws.tx.webservice.member.coord.RegisterType registerRequest)
Handle an incoming web service request from an external Participant and send a back.

param
wsContext webservice context
param
registerRequest the incoming request
param
activityId activity id

        if (logger.isLogging(Level.FINER)) {
            logger.entering("RegistrationManager.register(WebserviceContext, RegisterType)");
        }

        // request message must have wsa:MessageId and wsa:ReplyTo, cache them
        String msgID = WsaHelper.getMsgID(wsContext);
        EndpointReference registrationRequesterEPR = WsaHelper.getReplyTo(wsContext);
        WSEndpointReference faultTo = WsaHelper.getFaultTo(wsContext);
        if (logger.isLogging(Level.FINEST)) {
            logger.finest("register", "activityId:" + activityId + " register request msg id: " +
                    msgID + " replyTo: " + registrationRequesterEPR);
        }
        if (registrationRequesterEPR == null) {
            if (faultTo != null) {
                // send fault S4.3 wscoor:Invalid Parameters
                WsaHelper.sendFault(
                        faultTo,
                        null,
                        SOAPVersion.SOAP_11,
                        TxFault.InvalidParameters,
                        "register wsa:replyTo must be set for activityId " + activityId + " and msgId: " + msgID,  // no I18N - spec requires xml:lang="en"
                        msgID);
            }
            throw new WebServiceException(LocalizationMessages.REGISTER_REPLYTO_NOT_SET_3003(activityId, msgID));
        }

        Coordinator c = coordinationManager.getCoordinator(activityId);
        if (c == null) {
            // send fault S4.1 wscoor:Invalid State
            WsaHelper.sendFault(
                    faultTo,
                    null,
                    SOAPVersion.SOAP_11,
                    TxFault.InvalidState,
                    "attempting to register for an unknown activity Id: " + activityId + " and msgId: " + msgID,  // no I18N - spec requires xml:lang="en"
                    msgID);
            logger.warning("register", LocalizationMessages.REGISTER_FOR_UNKNOWN_ACTIVITY_3004(activityId, msgID));
        }

        Registrant r = null;
        Protocol requestProtocol = Protocol.getProtocol(registerRequest.getProtocolIdentifier());
        switch (requestProtocol) {
            case DURABLE:
            case VOLATILE:
            case COMPLETION:
                r = new ATParticipant(c, registerRequest);
                c.addRegistrant(r, wsContext);
                break;

            case WSAT2004:
            case UNKNOWN:
                // send fault S4.2 wscoor:Invalid Protocol
                WsaHelper.sendFault(
                        faultTo,
                        null,
                        SOAPVersion.SOAP_11,
                        TxFault.InvalidState,
                        registerRequest.getProtocolIdentifier() + " is not a recognized coordination type: activityId " +  // no I18N - spec requires xml:lang="en"
                                activityId + " and msgId " + msgID,
                        msgID);
                throw new UnsupportedOperationException(
                        LocalizationMessages.UNRECOGNIZED_COORDINATION_TYPE_3011(
                                registerRequest.getProtocolIdentifier(), activityId, msgID));
        }

        /* send <registerResponse> to RegistrationRequesterEPR */

        // setup relatesTo and get the remote port EPR
        OneWayFeature owf = new OneWayFeature();
        owf.setRelatesToID(msgID);
        RegistrationRequesterPortType registrationRequester =
                getCoordinatorService().getRegistrationRequester(registrationRequesterEPR, owf);

        // build the registerResponse message
        RegisterResponseType registerResponse = new RegisterResponseType();
        registerResponse.setCoordinatorProtocolService(
                (MemberSubmissionEndpointReference) r.getCoordinatorProtocolService());

        // send the message
        try {
            registrationRequester.registerResponseOperation(registerResponse);
        } catch (WebServiceException wse) {
            logger.warning("register",
                    LocalizationMessages.REGISTERRESPONSE_FAILED_3005(
                            registrationRequesterEPR,
                            activityId,
                            msgID,
                            wse.getLocalizedMessage()));
            throw wse;
        } catch (Exception e) {
            logger.severe("register",
                    LocalizationMessages.REGISTERRESPONSE_FAILED_3005(
                            registrationRequesterEPR,
                            activityId,
                            msgID,
                            e.getLocalizedMessage()));
            throw new WebServiceException(e);
        }

        if (logger.isLogging(Level.FINER)) {
            logger.exiting("RegistrationManager.register(WebserviceContext, RegisterType)");
        }
    
public voidregisterResponse(javax.xml.ws.WebServiceContext wsContext, java.lang.String activityId, java.lang.String registrantId, com.sun.xml.ws.tx.webservice.member.coord.RegisterResponseType registerResponse)
Process an incoming message.

param
activityId activity id
param
registrantId registrant id
param
registerResponse message
param
wsContext context of the inbound web service invocation

        if (logger.isLogging(Level.FINER)) {
            logger.entering("RegistrationManager.registerResponse");
        }

         // look up the registrant and remove it from outstanding Registrants
        Registrant r = Registrant.getOutstandingRegistrant(registrantId);
        if (r == null) {
            // send fault S4.1 wscoor:Invalid State
            WsaHelper.sendFault(
                    wsContext,
                    SOAPVersion.SOAP_11,
                    TxFault.InvalidState,
                    "received registerResponse for non-existent registrant : " +  // no I18N - spec requires xml:lang="en"
                            registrantId + " for activityId:" + activityId);
            logger.warning("registerResponse",
                    LocalizationMessages.NONEXISTENT_REGISTRANT_3008(registrantId, activityId));
        } else {
            // set coordinator protocol service on registrant
            r.setCoordinatorProtocolService(registerResponse.getCoordinatorProtocolService());
            r.setRemoteCPS(true);
            r.getCoordinator().addRegistrant(r, wsContext);
            Registrant.removeOutstandingRegistrant(registrantId);
            if (logger.isLogging(Level.FINEST)) {
                logger.finest("registerResponse", "Completed registration for CoordId:" + activityId +
                        "registrantId:" + registrantId);
            }
        }

        if (logger.isLogging(Level.FINER)) {
            logger.exiting("RegistrationManager.registerResponse");
        }
    
private booleansynchronousRegister(javax.xml.ws.EndpointReference registrationEPR, Coordinator c, com.sun.xml.ws.tx.webservice.member.coord.RegisterType registerParam, Registrant r)
Synchronously register with remote coordinator. Not all providers will support the synchronous register/registerReply since it is optional in the 2004 OASIS version of WS-COOR.

param
registrationEPR epr of remote registration service
param
c coordinator
param
registerParam message
param
r registrant
return
true if registration suceeded, false otherwise

//        RegistrationPortTypeRPC registerRPC = getCoordinatorService().getRegistration();
//        WsaHelper.initializeAsDestination((BindingProvider) registerRPC, registrationEPR);
//        ap = WsaHelper.getAddressingProperties((BindingProvider) registerRPC,
//                WsaHelper.BindingProviderContextType.REQUEST_CONTEXT);
//        ap.setReplyTo(newSynchronousRegistrationEPR((ActivityIdentifier)c.getId()));
//        try {
//            RegisterResponseType response = registerRPC.registerOperation(registerParam);
//            if (response == null) {
//                logger.warning("register", "synchronousRegisterRPC failed to get a non-null response.");
//            } else {
//                registerResponse(c.getIdValue(), r.getIdValue(), response);
//                logger.exiting("register", "synchronous register succeeded. Coordination Protocol Service:" +
//                    r.getCoordinatorProtocolService());
//                return true;
//            }
//        } catch (WebServiceException wse) {
//            // very likely that some WS-AT implementations might not implement this optional
//            // binding.  be prepared to use async version of register/register response.
//            logger.warning("register", "synchronous register failed, trying required registration protocol");
//            wse.printStackTrace();
//        }
//        logger.warning("register", "synchronous register failed, trying required registration protocol");
        return false;
    
public static com.sun.xml.ws.tx.webservice.member.coord.RegisterResponseTypesynchronousRegister(javax.xml.ws.WebServiceContext wsContext, java.lang.String activityId, com.sun.xml.ws.tx.webservice.member.coord.RegisterType registerRequest)
Handling incoming synchronous and return .

param
activityId activity id
param
registerRequest request
return
a new
param
wsContext context for incoming web service invocation

        Protocol requestProtocol = Protocol.getProtocol(registerRequest.getProtocolIdentifier());
        if (logger.isLogging(Level.FINER)) {
            logger.entering("synchronousRegister", "protocol=" + requestProtocol +
                    " coordId=" + activityId);
        }

        Coordinator c = coordinationManager.getCoordinator(activityId);
        if (c == null) {
            // send fault S4.3 wscoor:Invalid Parameters
            WsaHelper.sendFault(
                    wsContext,
                    SOAPVersion.SOAP_11,
                    TxFault.InvalidParameters,
                    "Received RegisterResponse for unknown activity id: " + activityId );  // no I18N - spec requires xml:lang="en"
            logger.warning("synchronousRegister", LocalizationMessages.NONEXISTENT_ACTIVITY_3010(activityId));
        }

        Registrant r = null;
        switch (requestProtocol) {
            case DURABLE:
            case VOLATILE:
            case COMPLETION:
                r = new ATParticipant(c, registerRequest);
                c.addRegistrant(r, wsContext);
                break;

            case WSAT2004:
            case UNKNOWN:
                // send fault S4.3 wscoor:Invalid Parameters
                WsaHelper.sendFault(
                        wsContext,
                        SOAPVersion.SOAP_11,
                        TxFault.InvalidParameters,
                        requestProtocol.getUri() + " is not a recognized coordination type" );  // no I18N - spec requires xml:lang="en"
                throw new UnsupportedOperationException(
                        LocalizationMessages.UNRECOGNIZED_COORDINATION_TYPE_3011(
                                requestProtocol, activityId, WsaHelper.getMsgID(wsContext)));
        }

        // build the registerResponse message
        RegisterResponseType registerResponse = new RegisterResponseType();
        registerResponse.setCoordinatorProtocolService((MemberSubmissionEndpointReference) r.getCoordinatorProtocolService());
        if (logger.isLogging(Level.FINER)) {
            logger.exiting("synchronousRegister", r.getCoordinatorProtocolService());
        }

        return registerResponse;