0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common Development
0008: * and Distribution License("CDDL") (collectively, the "License"). You
0009: * may not use this file except in compliance with the License. You can obtain
0010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
0011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
0012: * language governing permissions and limitations under the License.
0013: *
0014: * When distributing the software, include this License Header Notice in each
0015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
0016: * Sun designates this particular file as subject to the "Classpath" exception
0017: * as provided by Sun in the GPL Version 2 section of the License file that
0018: * accompanied this code. If applicable, add the following below the License
0019: * Header, with the fields enclosed by brackets [] replaced by your own
0020: * identifying information: "Portions Copyrighted [year]
0021: * [name of copyright owner]"
0022: *
0023: * Contributor(s):
0024: *
0025: * If you wish your version of this file to be governed by only the CDDL or
0026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
0027: * elects to include this software in this distribution under the [CDDL or GPL
0028: * Version 2] license." If you don't indicate a single choice of license, a
0029: * recipient has the option to distribute your version of this file under
0030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
0031: * its licensees as provided above. However, if you add GPL Version 2 code
0032: * and therefore, elected the GPL Version 2 license, then the option applies
0033: * only if the new code is made subject to such option by the copyright
0034: * holder.
0035: */
0036:
0037: /*
0038: * RMServerTube.java
0039: *
0040: * @author Mike Grogan
0041: * @author Bhakti Mehta
0042: * Created on August 25, 2007, 8:10 AM
0043: *
0044: */
0045:
0046: package com.sun.xml.ws.rm.jaxws.runtime.server;
0047:
0048: import com.sun.xml.ws.api.BindingID;
0049: import com.sun.xml.ws.api.SOAPVersion;
0050: import com.sun.xml.ws.api.WSBinding;
0051: import com.sun.xml.ws.api.addressing.AddressingVersion;
0052: import com.sun.xml.ws.api.addressing.WSEndpointReference;
0053: import com.sun.xml.ws.api.message.Header;
0054: import com.sun.xml.ws.api.message.*;
0055: import com.sun.xml.ws.api.message.Message;
0056: import com.sun.xml.ws.api.model.wsdl.WSDLPort;
0057: import com.sun.xml.ws.api.pipe.NextAction;
0058: import com.sun.xml.ws.api.pipe.Tube;
0059: import com.sun.xml.ws.api.pipe.TubeCloner;
0060: import com.sun.xml.ws.api.server.WSEndpoint;
0061: import com.sun.xml.ws.rm.*;
0062: import com.sun.xml.ws.rm.jaxws.runtime.InboundSequence;
0063: import com.sun.xml.ws.rm.jaxws.runtime.OutboundSequence;
0064: import com.sun.xml.ws.rm.jaxws.runtime.SequenceConfig;
0065: import com.sun.xml.ws.rm.jaxws.runtime.TubeBase;
0066: import com.sun.xml.ws.rm.jaxws.util.LoggingHelper;
0067: import com.sun.xml.ws.rm.protocol.*;
0068: import com.sun.xml.ws.rm.v200502.*;
0069: import com.sun.xml.ws.rm.v200702.MakeConnectionElement;
0070: import com.sun.xml.ws.rm.v200702.CloseSequenceElement;
0071: import com.sun.xml.ws.rm.v200702.CloseSequenceResponseElement;
0072: import com.sun.xml.ws.rm.v200702.TerminateSequenceResponseElement;
0073: import com.sun.xml.ws.runtime.util.Session;
0074: import com.sun.xml.ws.runtime.util.SessionManager;
0075: import com.sun.xml.ws.security.SecurityContextToken;
0076: import com.sun.xml.ws.security.trust.WSTrustElementFactory;
0077: import com.sun.xml.ws.security.trust.elements.str.DirectReference;
0078: import com.sun.xml.ws.security.trust.elements.str.SecurityTokenReference;
0079: import com.sun.xml.wss.impl.MessageConstants;
0080:
0081: import javax.xml.bind.JAXBElement;
0082: import javax.xml.bind.JAXBException;
0083: import javax.xml.namespace.QName;
0084: import javax.xml.soap.SOAPException;
0085: import javax.xml.soap.SOAPFactory;
0086: import javax.xml.soap.SOAPFault;
0087: import javax.xml.ws.WebServiceException;
0088: import javax.xml.ws.soap.SOAPBinding;
0089: import javax.xml.ws.wsaddressing.W3CEndpointReference;
0090: import java.net.URI;
0091: import java.util.HashMap;
0092: import java.util.logging.Level;
0093: import java.util.logging.Logger;
0094:
0095: /**
0096: * Server-side RM Tube implementation
0097: */
0098: public class RMServerTube
0099: extends
0100: TubeBase<RMDestination, ServerOutboundSequence, ServerInboundSequence> {
0101:
0102: public static final Logger logger = Logger.getLogger(LoggingHelper
0103: .getLoggerName(RMServerTube.class), Messages.class
0104: .getName());
0105:
0106: public static final LoggingHelper loggingHelper = new LoggingHelper(
0107: logger);
0108:
0109: private static HashMap<String, ActionHandler> actionMap = new HashMap<String, ActionHandler>();
0110:
0111: private RMConstants constants;
0112:
0113: protected WSDLPort wsdlModel;
0114:
0115: protected WSEndpoint owner;
0116:
0117: protected SequenceConfig config;
0118:
0119: private boolean secureReliableMessaging = false;
0120:
0121: protected WSBinding binding;
0122:
0123: private com.sun.xml.ws.rm.Message currentRequestMessage;
0124:
0125: private SessionManager sessionManager = SessionManager
0126: .getSessionManager();
0127:
0128: /**
0129: * Constructor is passed everything available in PipelineAssembler.
0130: *
0131: * @param wsdlModel The WSDLPort
0132: * @param owner The WSEndpoint.
0133: * @param nextTube The next Tube in the pipeline.
0134: *
0135: */
0136: public RMServerTube(WSDLPort wsdlModel, WSEndpoint owner,
0137: Tube nextTube) {
0138:
0139: super (RMDestination.getRMDestination(), nextTube);
0140: this .wsdlModel = wsdlModel;
0141: this .owner = owner;
0142:
0143: this .binding = this .owner.getBinding();
0144:
0145: this .config = getSequenceConfig();
0146: this .version = config.rmVersion;
0147: this .constants = config.getRMConstants();
0148: this .unmarshaller = config.getRMVersion().createUnmarshaller();
0149: this .marshaller = config.getRMVersion().createMarshaller();
0150: initActionMap();
0151:
0152: }
0153:
0154: /**
0155: * Copy constructor used by <code>copy</code> method.
0156: *
0157: * @param toCopy to be copied.
0158: * @param cloner passed as an argument to copy.
0159: */
0160: private RMServerTube(RMServerTube toCopy, TubeCloner cloner) {
0161:
0162: super (RMDestination.getRMDestination(), toCopy, cloner);
0163:
0164: this .wsdlModel = toCopy.wsdlModel;
0165: this .owner = toCopy.owner;
0166: this .config = toCopy.config;
0167: this .binding = owner.getBinding();
0168: this .version = toCopy.version;
0169: this .constants = RMConstants.getRMConstants(binding
0170: .getAddressingVersion());
0171: this .unmarshaller = config.getRMVersion().createUnmarshaller();
0172: this .marshaller = config.getRMVersion().createMarshaller();
0173: initActionMap();
0174:
0175: }
0176:
0177: @Override
0178: public NextAction processRequest(Packet packet) {
0179:
0180: SOAPFault soapFault = null;
0181: com.sun.xml.ws.rm.Message message = null;
0182:
0183: try {
0184:
0185: //handle special protocol messages
0186: Packet ret = null;
0187: try {
0188: ret = handleProtocolMessage(packet);
0189: } catch (CreateSequenceException e) {
0190: soapFault = newCreateSequenceRefusedFault(e);
0191: } catch (TerminateSequenceException e) {
0192: soapFault = newSequenceTerminatedFault(e);
0193: } catch (InvalidSequenceException e) {
0194: soapFault = newUnknownSequenceFault(e);
0195: }
0196:
0197: if (ret != null) {
0198: //the contract of handleProtocolMessage is to return null if messager is non-protocol
0199: //message or protocol message is piggybacked on an application message.
0200: return doReturnWith(ret);
0201: }
0202:
0203: //If we got here, this is an application message
0204: //do inbound bookkeeping
0205: try {
0206: message = handleInboundMessage(packet);
0207: } catch (MessageNumberRolloverException e) {
0208: soapFault = newMessageNumberRolloverFault(e);
0209: } catch (InvalidSequenceException e) {
0210: soapFault = newUnknownSequenceFault(e);
0211: } catch (CloseSequenceException e) {
0212: soapFault = newClosedSequenceFault(e);
0213: }
0214:
0215: Packet retPacket = null;
0216: if (soapFault != null) {
0217: Message m = com.sun.xml.ws.api.message.Messages
0218: .create(soapFault);
0219:
0220: //SequenceFault is to be added for only SOAP 1.1
0221: if (binding.getSOAPVersion() == SOAPVersion.SOAP_11) {
0222: //FIXME - need JAXBRIContext that can marshall SequenceFaultElement
0223: Header header = Headers.create(config
0224: .getRMVersion().getJAXBContext(),
0225: new SequenceFaultElement());
0226: m.getHeaders().add(header);
0227: }
0228:
0229: retPacket = packet
0230: .createServerResponse(m, constants
0231: .getAddressingVersion(), binding
0232: .getSOAPVersion(), constants
0233: .getAddressingVersion()
0234: .getDefaultFaultAction());
0235: retPacket.setMessage(m);
0236: doReturnWith(retPacket);
0237: }
0238:
0239: //allow diagnostic access to message if ProcessingFilter has been specified
0240: if (filter != null) {
0241: filter.handleEndpointRequestMessage(message);
0242: }
0243:
0244: //If Message is a duplicate, handleInboundMessage threw a DuplicateMessageException,
0245: //Therefore, this is the first time processing this message.
0246:
0247: //use sequence id to initialize inboundSequence and outboundSequence
0248: //local variables by doing a lookup in RMDestination
0249: ServerInboundSequence inboundSequence = (ServerInboundSequence) message
0250: .getSequence();
0251:
0252: if (inboundSequence == null) {
0253: logger
0254: .log(
0255: Level.SEVERE,
0256: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.NOT_RELIABLE_SEQ_OR_PROTOCOL_MESSAGE
0257: .format());
0258: throw new RMException(
0259: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.NOT_RELIABLE_SEQ_OR_PROTOCOL_MESSAGE
0260: .format());
0261:
0262: }
0263: //reset inactivity timer
0264: inboundSequence.resetLastActivityTime();
0265:
0266: ServerOutboundSequence outboundSequence = (ServerOutboundSequence) inboundSequence
0267: .getOutboundSequence();
0268:
0269: //determine whether the correct STR has been used to sign message
0270: if (secureReliableMessaging)
0271: checkSTR(packet, inboundSequence);
0272:
0273: //set com.sun.xml.ws.session and com.sun.xml.ws.sessionid
0274: //invocationProperties if they have not already been set
0275: //by SC pipe.
0276: setSessionData(packet, inboundSequence);
0277:
0278: //clear packet.transporBackChannel so downstream pipes do not prevent
0279: //empty one-way response bodies to be sent back when we need to use the
0280: //bodies for RM SequenceAcknowledgemnts.
0281: packet.transportBackChannel = null;
0282:
0283: //make these available in an injected WebServiceContext
0284: packet.invocationProperties.put(Constants.sequenceProperty,
0285: inboundSequence);
0286: packet.invocationProperties.put(
0287: Constants.messageNumberProperty, message
0288: .getMessageNumber());
0289:
0290: //If ordered deliver is configured,
0291: //Block here if InboundSequence reports gaps before this message.
0292: //inboundSequence.holdIfUndeliverable(message);
0293:
0294: //send the message down the Tubeline
0295: this .currentRequestMessage = message;
0296:
0297: if (!inboundSequence.isOrdered()) {
0298: return doInvoke(next, packet);
0299: } else {
0300: MessageSender sender = new TubelineSender(this , packet,
0301: config.getSoapVersion(), constants
0302: .getAddressingVersion());
0303:
0304: message.setMessageSender(sender);
0305:
0306: //send message down tubeline if predecesor has arrived. Otherwise.
0307: //it will have to wait until releaseNextMessage is called during the
0308: //processing of the predecessor in processResponse.
0309: if (inboundSequence.isDeliverable(message)) {
0310: sender.send();
0311: }
0312:
0313: return doSuspend();
0314:
0315: }
0316: } catch (BufferFullException e) {
0317:
0318: //need to return message with empty body and SequenceAcknowledgement
0319: //header for inboundSequence. This is similar to handleAckRequestedAction, which
0320: //should do much the same thing. The only difference is that handleAckRequestedAction
0321: //must also have logic to get the inboundSequence from the AckRequested header in the
0322: //packet
0323: if (packet.getMessage().isOneWay(wsdlModel)) {
0324: //refuse to process the request. Client will retry
0325: Packet ret = new Packet();
0326: ret.invocationProperties
0327: .putAll(packet.invocationProperties);
0328: return doReturnWith(ret);
0329: }
0330:
0331: //handleInboundMessage shouldn't let inboundSequence be null.
0332: try {
0333: ServerInboundSequence seq = (ServerInboundSequence) e
0334: .getSequence();
0335: if (seq != null) {
0336: Packet ret = generateAckMessage(packet, seq, config
0337: .getRMVersion()
0338: .getSequenceAcknowledgementAction());
0339: return doReturnWith(ret);
0340: } else {
0341: //unreachable
0342: return null;
0343: }
0344: } catch (RMException ee) {
0345: logger
0346: .severe(Messages.ACKNOWLEDGEMENT_MESSAGE_EXCEPTION
0347: .format()
0348: + e);
0349: return doThrow(new WebServiceException(
0350: Messages.ACKNOWLEDGEMENT_MESSAGE_EXCEPTION
0351: .format()
0352: + e));
0353: }
0354:
0355: } catch (DuplicateMessageException e) {
0356:
0357: // 1. If one-way return empty message without invoking process on next pipe
0358: // 2. If two-way, formulate response according to secret Microsoft protocol.
0359: // a. If original was processed and response is still available in OutboundSequence,
0360: // return it again.
0361: // b. Otherwise (original not yet processed or response already discarded, return
0362: // ack message.
0363:
0364: if (packet.getMessage().isOneWay(wsdlModel)) {
0365: //ignore the message.
0366: Packet ret = new Packet();
0367: ret.invocationProperties
0368: .putAll(packet.invocationProperties);
0369: return doReturnWith(ret);
0370:
0371: } else {
0372: //check whether original response is available.
0373: com.sun.xml.ws.api.message.Message response;
0374: com.sun.xml.ws.rm.Message original = e.getRMMessage();
0375: com.sun.xml.ws.rm.Message origresp = original
0376: .getRelatedMessage();
0377:
0378: if (origresp != null) {
0379: response = origresp.getCopy();
0380: if (response != null) {
0381: //original response is available, resend it.
0382: Packet ret = new Packet(response);
0383: ret.invocationProperties
0384: .putAll(packet.invocationProperties);
0385: return doReturnWith(ret);
0386: }
0387: }
0388:
0389: //either the original request is waiting to be processing, or the response has been
0390: //acked and thrown away. All we can do is return a SequenceAcknowledgement.
0391: try {
0392:
0393: ServerInboundSequence seq = (ServerInboundSequence) original
0394: .getSequence();
0395: Packet ret = generateAckMessage(packet, seq, config
0396: .getRMVersion()
0397: .getSequenceAcknowledgementAction());
0398: return doReturnWith(ret);
0399:
0400: } catch (RMException ee) {
0401: return doThrow(new WebServiceException(ee));
0402: }
0403: }
0404: } catch (RMException e) {
0405:
0406: //see if a RM Fault type has been assigned to this exception type. If so, let
0407: //the exception generate a fault message. Otherwise, wrap as WebServiceException and
0408: //rethrow.
0409: Message m = e.getFaultMessage();
0410: if (m != null) {
0411: return doReturnWith(new Packet(m));
0412: } else {
0413: return doThrow(new WebServiceException(e));
0414: }
0415:
0416: } catch (RuntimeException e) {
0417: return doThrow(new WebServiceException(e));
0418: }
0419: }
0420:
0421: /**
0422: *
0423: */
0424: @Override
0425: public NextAction processResponse(Packet packet) {
0426:
0427: //on the non-ordered code path, we need to do post-processing. On
0428: //the ordered path, this has been one
0429: ServerInboundSequence inboundSequence = (ServerInboundSequence) currentRequestMessage
0430: .getSequence();
0431: if (!inboundSequence.isOrdered()) {
0432:
0433: postProcess(packet);
0434: }
0435:
0436: return doReturnWith(packet);
0437: }
0438:
0439: @Override
0440: public NextAction processException(Throwable t) {
0441: return doThrow(t);
0442: }
0443:
0444: public void postProcess(Packet packet) {
0445:
0446: ServerInboundSequence inboundSequence = (ServerInboundSequence) currentRequestMessage
0447: .getSequence();
0448: ServerOutboundSequence outboundSequence = (ServerOutboundSequence) inboundSequence
0449: .getOutboundSequence();
0450: try {
0451:
0452: // This shouldn't be necessary, but having messageNumberProperty
0453: // set has side-effects here due to the fact that RMClientPipe
0454: // and RMServerPipe share an implementation of handleOutboundMessage
0455: packet.invocationProperties.put(Constants.sequenceProperty,
0456: null);
0457: packet.invocationProperties.put(
0458: Constants.messageNumberProperty, null);
0459:
0460: Message responseMessage = packet.getMessage();
0461: Message emptyMessage;
0462:
0463: if (responseMessage == null) {
0464:
0465: //This a one-way response. handleOutboundMessage
0466: //might need a message to write sequenceAcknowledgent headers to.
0467: //Give it one.
0468: emptyMessage = com.sun.xml.ws.api.message.Messages
0469: .createEmpty(config.getSoapVersion());
0470: packet.setMessage(emptyMessage);
0471:
0472: //propogate this information so handleOutboundMessage will not
0473: //add this to the outbound sequence, if any.
0474: packet.invocationProperties.put("onewayresponse", true);
0475: }
0476:
0477: //If ordered delivery is configured, unblock the next message in the sequence
0478: //if it is waiting for this one to be delivered.
0479: inboundSequence.releaseNextMessage(currentRequestMessage);
0480:
0481: //Let Outbound sequence do its bookkeeping work, which consists of writing
0482: //outbound RM headers.
0483:
0484: //need to handle any error caused by
0485: //handleOutboundMessage.. Request has already been processed
0486: //by the endpoint.
0487: com.sun.xml.ws.rm.Message om = handleOutboundMessage(
0488: outboundSequence, packet);
0489:
0490: //allow diagnostic access to outbound message if ProcessingFilter is
0491: //specified
0492: if (filter != null) {
0493: filter.handleEndpointResponseMessage(om);
0494: }
0495:
0496: //If we populated
0497: //ret with an empty message to be used by RM protocol, and it
0498: //was not used, get rid of the empty message.
0499: if (responseMessage == null && packet.getMessage() != null
0500: && !packet.getMessage().hasHeaders()) {
0501: packet.setMessage(null);
0502:
0503: } else {
0504:
0505: //Fill in relatedMessage field in request message for use in case request is resent.
0506: //the com.sun.xml.ws.api.message.Message referenced will be a copy of the one
0507: //contained in the returned packet. See implementation of message.setRelatedMessage.
0508: currentRequestMessage.setRelatedMessage(om);
0509:
0510: // MS client expects SequenceAcknowledgement action incase of oneway messages
0511: if (responseMessage == null
0512: && packet.getMessage() != null) {
0513:
0514: HeaderList headerList = packet.getMessage()
0515: .getHeaders();
0516:
0517: headerList.add(Headers.create(constants
0518: .getAddressingVersion().actionTag, config
0519: .getRMVersion()
0520: .getSequenceAcknowledgementAction()));
0521:
0522: }
0523: }
0524:
0525: } catch (RMException e) {
0526:
0527: //see if a RM Fault type has been assigned to this exception type. If so, let
0528: //the exception generate a fault message. Otherwise, wrap as WebServiceException and
0529: //rethrow.
0530: Message m = e.getFaultMessage();
0531: if (m != null) {
0532: doReturnWith(new Packet(m));
0533: } else {
0534: doThrow(new WebServiceException(e));
0535: }
0536:
0537: } catch (RuntimeException e) {
0538: doThrow(new WebServiceException(e));
0539: }
0540: }
0541:
0542: public void preDestroy() {
0543:
0544: //nothing to do here so far
0545: next.preDestroy();
0546: }
0547:
0548: public RMServerTube copy(TubeCloner cloner) {
0549: return new RMServerTube(this , cloner);
0550:
0551: }
0552:
0553: public Tube nextTube() {
0554: return next;
0555: }
0556:
0557: /**
0558: * Handle a non-Application message. Look at the wsa:Action header and if it is
0559: * one mapped to a handler in our actionHandlers dispatch table, invoke the handler.
0560: *
0561: * @param packet The Packet containing the incoming message
0562: * @return The Packet returned by invocation of the handler
0563: * null if no handler is registered
0564: * @throws RMException - if any thrown by the handler.
0565: */
0566: public Packet handleProtocolMessage(Packet packet)
0567: throws RMException {
0568:
0569: ActionHandler handler;
0570: String actionValue;
0571: actionValue = packet.getMessage().getHeaders().getAction(
0572: constants.getAddressingVersion(),
0573: config.getSoapVersion());
0574: if (actionValue == null || actionValue.equals("")) {
0575: logger
0576: .severe(com.sun.xml.ws.rm.jaxws.runtime.server.Messages.NON_RM_REQUEST_OR_MISSING_WSA_ACTION_HEADER
0577: .format());
0578: throw new RMException(
0579: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.NON_RM_REQUEST_OR_MISSING_WSA_ACTION_HEADER
0580: .format());
0581: }
0582:
0583: handler = actionMap.get(actionValue);
0584: if (handler != null) {
0585: return handler.process(this , packet);
0586: } else {
0587: return null;
0588: }
0589:
0590: }
0591:
0592: /**********************************/
0593: /* Handlers for wsa:Action values */
0594: /**********************************/
0595:
0596: public Packet handleCreateSequenceAction(Packet packet)
0597: throws RMException {
0598:
0599: AbstractCreateSequence csrElement;
0600:
0601: String offeredId = null;
0602: Message message = packet.getMessage();
0603:
0604: try {
0605: csrElement = message.readPayloadAsJAXB(unmarshaller);
0606: } catch (JAXBException e) {
0607: logger
0608: .severe(com.sun.xml.ws.rm.jaxws.runtime.server.Messages.CREATESEQUENCE_HEADER_PROBLEM
0609: .format()
0610: + e);
0611: throw new RMException(
0612: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.CREATESEQUENCE_HEADER_PROBLEM
0613: .format()
0614: + e);
0615: }
0616:
0617: /**ADDRESSING_FIXME
0618: * Assume for now that AcksTo is anonymous.
0619: */
0620: URI acksTo = constants.getAnonymousURI();
0621: /*String acksToString = acksTo.toString();*/
0622: /*String replyToString = acksToString;*/
0623: /*
0624: EndpointReference replyTo = inboundAddressingProperties.getReplyTo();
0625: if (replyTo == null) {
0626: replyTo = addressingBuilder.newEndpointReference( ac.getAnonymousURI());
0627: inboundAddressingProperties.setReplyTo(replyTo);
0628: }
0629:
0630: EndpointReference acksTo = csrElement.getAcksTo();
0631: String ackstoUri = acksTo.getAddress().getURI().toString();
0632: String replytoUri = replyTo.getAddress().getURI().toString();
0633:
0634:
0635: if (!ackstoUri.equals(replytoUri)){
0636: throw new CreateSequenceException(Messages.ACKSTO_NOT_EQUAL_REPLYTO.format(ackstoUri,replytoUri) );
0637: }
0638: */
0639:
0640: com.sun.xml.ws.security.secext10.SecurityTokenReferenceType strType = null;
0641: if (csrElement instanceof com.sun.xml.ws.rm.v200502.CreateSequenceElement) {
0642: com.sun.xml.ws.rm.v200502.OfferType offer = ((com.sun.xml.ws.rm.v200502.CreateSequenceElement) csrElement)
0643: .getOffer();
0644: if (offer != null) {
0645: com.sun.xml.ws.rm.v200502.Identifier id = offer
0646: .getIdentifier();
0647: if (id != null) {
0648: offeredId = id.getValue();
0649: }
0650: }
0651: // Read STR element in csrElement if any
0652: strType = ((com.sun.xml.ws.rm.v200502.CreateSequenceElement) csrElement)
0653: .getSecurityTokenReference();
0654: this .secureReliableMessaging = strType != null ? true
0655: : false;
0656: } else {
0657: com.sun.xml.ws.rm.v200702.OfferType offer = ((com.sun.xml.ws.rm.v200702.CreateSequenceElement) csrElement)
0658: .getOffer();
0659: if (offer != null) {
0660: com.sun.xml.ws.rm.v200702.Identifier id = offer
0661: .getIdentifier();
0662: if (id != null) {
0663: offeredId = id.getValue();
0664: }
0665: }
0666: // Read STR element in csrElement if any
0667: strType = ((com.sun.xml.ws.rm.v200702.CreateSequenceElement) csrElement)
0668: .getSecurityTokenReference();
0669: this .secureReliableMessaging = strType != null ? true
0670: : false;
0671:
0672: }
0673: //create server-side data structures.
0674: ServerInboundSequence inboundSequence = provider
0675: .createSequence(acksTo, null, //assign random id
0676: offeredId, config);
0677:
0678: //start the inactivity timer
0679: inboundSequence.resetLastActivityTime();
0680:
0681: //TODO.. Read STR element in csrElement if any
0682: if (this .secureReliableMessaging) {
0683:
0684: SecurityContextToken sct = (SecurityContextToken) packet.invocationProperties
0685: .get(MessageConstants.INCOMING_SCT);
0686: if (sct != null) {
0687: String strId = sct.getIdentifier().toString();
0688: WSTrustElementFactory wsTrustElemFactory = WSTrustElementFactory
0689: .newInstance();
0690: JAXBElement jaxbElem = new com.sun.xml.ws.security.secext10.ObjectFactory()
0691: .createSecurityTokenReference(strType);
0692: SecurityTokenReference str = wsTrustElemFactory
0693: .createSecurityTokenReference(jaxbElem);
0694:
0695: com.sun.xml.ws.security.trust.elements.str.Reference ref = str
0696: .getReference();
0697: if (ref instanceof com.sun.xml.ws.security.trust.elements.str.DirectReference) {
0698: DirectReference directRef = (DirectReference) ref;
0699: String gotId = directRef.getURIAttr().toString();
0700: if (gotId.equals(strId)) {
0701: inboundSequence.setStrId(strId);
0702: } else {
0703: throw new RMSecurityException(
0704: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.SECURITY_TOKEN_AUTHORIZATION_ERROR
0705: .format(gotId, strId));
0706: }
0707: } else
0708: throw new RMSecurityException(
0709: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.SECURITY_REFERENCE_ERROR
0710: .format(ref.getClass().getName()));
0711:
0712: } else
0713: throw new RMSecurityException(
0714: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.NULL_SECURITY_TOKEN
0715: .format());
0716: }
0717:
0718: startSession(inboundSequence);
0719:
0720: if (offeredId == null) {
0721: inboundSequence.getOutboundSequence().saveMessages = false;
0722: }
0723:
0724: //initialize CreateSequenceResponseElement
0725: AbstractAcceptType accept = null;
0726: AbstractCreateSequenceResponse crsElement = null;
0727: if (config.getRMVersion() == RMVersion.WSRM10) {
0728: crsElement = new com.sun.xml.ws.rm.v200502.CreateSequenceResponseElement();
0729:
0730: com.sun.xml.ws.rm.v200502.Identifier id2 = new com.sun.xml.ws.rm.v200502.Identifier();
0731: id2.setValue(inboundSequence.getId());
0732: ((com.sun.xml.ws.rm.v200502.CreateSequenceResponseElement) crsElement)
0733: .setIdentifier(id2);
0734: accept = new com.sun.xml.ws.rm.v200502.AcceptType();
0735: } else {
0736: crsElement = new com.sun.xml.ws.rm.v200702.CreateSequenceResponseElement();
0737:
0738: com.sun.xml.ws.rm.v200702.Identifier id2 = new com.sun.xml.ws.rm.v200702.Identifier();
0739: id2.setValue(inboundSequence.getId());
0740: ((com.sun.xml.ws.rm.v200702.CreateSequenceResponseElement) crsElement)
0741: .setIdentifier(id2);
0742: accept = new com.sun.xml.ws.rm.v200702.AcceptType();
0743:
0744: }
0745:
0746: URI dest;
0747: if (offeredId != null) {
0748:
0749: String destString = message.getHeaders().getTo(
0750: constants.getAddressingVersion(),
0751: config.getSoapVersion());
0752: try {
0753: dest = new URI(destString);
0754: } catch (Exception e) {
0755: logger
0756: .severe(com.sun.xml.ws.rm.jaxws.runtime.server.Messages.INVALID_OR_MISSING_TO_ON_CS_MESSAGE
0757: .format());
0758: throw new RMException(
0759: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.INVALID_OR_MISSING_TO_ON_CS_MESSAGE
0760: .format());
0761: }
0762:
0763: W3CEndpointReference endpointReference;
0764: WSEndpointReference wsepr = new WSEndpointReference(dest,
0765: constants.getAddressingVersion());
0766: if (constants.getAddressingVersion() == AddressingVersion.W3C) {
0767: endpointReference = (W3CEndpointReference) wsepr
0768: .toSpec();
0769: accept.setAcksTo(endpointReference);
0770: } /*else {
0771: //TODO support MemberSubmissionEndpointReference when issue 131 of JAXB is resolved
0772: //endpointReference = (MemberSubmissionEndpointReference)wsepr.toSpec() ;
0773: }*/
0774: crsElement.setAccept(accept);
0775: }
0776:
0777: Message response = com.sun.xml.ws.api.message.Messages.create(
0778: config.getRMVersion().getJAXBContext(), crsElement,
0779: config.getSoapVersion());
0780:
0781: message.assertOneWay(false);
0782:
0783: /*ADDRESSING_FIXME
0784: * This will probably be broken with MS client if they still send CS with
0785: * missing reply-to.
0786: */
0787:
0788: Packet ret = packet
0789: .createServerResponse(response, constants
0790: .getAddressingVersion(), config
0791: .getSoapVersion(), config.getRMVersion()
0792: .getCreateSequenceResponseAction());
0793: /*
0794: ret.setEndPointAddressString(acksToString);
0795: ret.proxy = packet.proxy;
0796:
0797: //there are some invocation properties. Outgoing addressing headers at least
0798: ret.invocationProperties.putAll(packet.invocationProperties);
0799:
0800: //Set addressing headers
0801: AddressingProperties outboundAddressingProperties =
0802: addressingBuilder.newAddressingProperties();
0803: //outboundAddressingProperties.initializeAsReply(inboundAddressingProperties, false);
0804: outboundAddressingProperties.initializeAsReply(inboundAddressingProperties);
0805:
0806:
0807: //AddressingProperties.initializeAsResponse does not know how to set outbound Action
0808: //property.
0809: outboundAddressingProperties.setAction(addressingBuilder.newURI(
0810: constants.getCreateSequenceResponseAction()));
0811:
0812:
0813:
0814: ret.invocationProperties.put(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND,
0815: outboundAddressingProperties);
0816: */
0817: return ret;
0818: }
0819:
0820: public Packet handleTerminateSequenceAction(Packet packet)
0821: throws RMException {
0822:
0823: AbstractTerminateSequence tsElement;
0824: Message message = packet.getMessage();
0825:
0826: try {
0827: tsElement = message.readPayloadAsJAXB(unmarshaller);
0828: } catch (JAXBException e) {
0829: logger
0830: .severe(com.sun.xml.ws.rm.jaxws.runtime.server.Messages.TERMINATE_SEQUENCE_EXCEPTION
0831: .format()
0832: + e);
0833: throw new TerminateSequenceException(
0834: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.TERMINATE_SEQUENCE_EXCEPTION
0835: .format()
0836: + e);
0837: }
0838: String id;
0839: if (tsElement instanceof com.sun.xml.ws.rm.v200502.TerminateSequenceElement) {
0840: id = ((com.sun.xml.ws.rm.v200502.TerminateSequenceElement) tsElement)
0841: .getIdentifier().getValue();
0842: } else {
0843: id = ((com.sun.xml.ws.rm.v200702.TerminateSequenceElement) tsElement)
0844: .getIdentifier().getValue();
0845: }
0846:
0847: ServerInboundSequence seq = provider.getInboundSequence(id);
0848: if (seq == null) {
0849: logger.severe(String.format(Constants.UNKNOWN_SEQUENCE_TEXT
0850: + id));
0851: throw new InvalidSequenceException(String.format(
0852: Constants.UNKNOWN_SEQUENCE_TEXT, id), id);
0853: }
0854:
0855: //end the session if we own its lifetime..i.e. SC is not
0856: //present
0857: endSession(seq);
0858:
0859: provider.terminateSequence(id);
0860:
0861: //formulate response if required
0862: Packet ret = null;
0863: OutboundSequence outboundSequence = seq.getOutboundSequence();
0864:
0865: Message response = null;
0866: String tsAction = null;
0867: //If there is an "real" outbound sequence, client expects us to terminate it.
0868: switch (config.getRMVersion()) {
0869: case WSRM10: {
0870:
0871: tsAction = RMVersion.WSRM10.getTerminateSequenceAction();
0872: if (outboundSequence.saveMessages) {
0873: TerminateSequenceElement terminateSeqResponse = new TerminateSequenceElement();
0874: Identifier id2 = new Identifier();
0875: id2.setValue(outboundSequence.getId());
0876:
0877: terminateSeqResponse.setIdentifier(id2);
0878: response = com.sun.xml.ws.api.message.Messages.create(
0879: config.getRMVersion().getJAXBContext(),
0880: terminateSeqResponse, config.getSoapVersion());
0881: ret = packet.createServerResponse(response, constants
0882: .getAddressingVersion(), config
0883: .getSoapVersion(), tsAction);
0884:
0885: AbstractSequenceAcknowledgement element = seq
0886: .generateSequenceAcknowledgement(null,
0887: marshaller, false);
0888:
0889: Header header = createHeader(element);
0890: response.getHeaders().add(header);
0891:
0892: } else {
0893:
0894: packet.transportBackChannel.close();
0895: ret = new Packet(null);
0896: }
0897: break;
0898: }
0899: case WSRM11: {
0900: tsAction = RMVersion.WSRM11
0901: .getTerminateSequenceResponseAction();
0902: TerminateSequenceResponseElement terminateSeqResponse = new TerminateSequenceResponseElement();
0903: com.sun.xml.ws.rm.v200702.Identifier id2 = new com.sun.xml.ws.rm.v200702.Identifier();
0904: id2.setValue(outboundSequence.getId());
0905:
0906: terminateSeqResponse.setIdentifier(id2);
0907: response = com.sun.xml.ws.api.message.Messages.create(
0908: config.getRMVersion().getJAXBContext(),
0909: terminateSeqResponse, config.getSoapVersion());
0910: response.assertOneWay(false);
0911: ret = packet.createServerResponse(response, constants
0912: .getAddressingVersion(), config.getSoapVersion(),
0913: tsAction);
0914:
0915: AbstractSequenceAcknowledgement element = seq
0916: .generateSequenceAcknowledgement(null, marshaller,
0917: false);
0918:
0919: Header header = createHeader(element);
0920: response.getHeaders().add(header);
0921: break;
0922: }
0923:
0924: }
0925:
0926: return ret;
0927:
0928: }
0929:
0930: public Packet handleLastMessageAction(Packet inbound)
0931: throws RMException {
0932:
0933: try {
0934: Message message = inbound.getMessage();
0935: Header header = message.getHeaders().get(
0936: config.getRMVersion().getSequenceQName(), true);
0937: if (header == null) {
0938: logger.severe(Messages.INVALID_LAST_MESSAGE.format());
0939: throw new RMException(Messages.INVALID_LAST_MESSAGE
0940: .format());
0941: }
0942:
0943: SequenceElement el = (SequenceElement) header
0944: .readAsJAXB(unmarshaller);
0945: String id = el.getId();
0946:
0947: ServerInboundSequence seq = provider.getInboundSequence(id);
0948: if (seq == null) {
0949: logger.severe(String.format(
0950: Constants.UNKNOWN_SEQUENCE_TEXT, id + id));
0951: throw new InvalidSequenceException(String.format(
0952: Constants.UNKNOWN_SEQUENCE_TEXT, id), id);
0953: }
0954:
0955: //add message to ClientInboundSequence so that this message
0956: //number appears in sequence acknowledgement
0957: int messageNumber = el.getNumber();
0958: seq.set(messageNumber, new com.sun.xml.ws.rm.Message(
0959: message, version));
0960:
0961: return generateAckMessage(inbound, seq, config
0962: .getRMVersion().getLastAction());
0963:
0964: } catch (JAXBException e) {
0965: logger.severe(Messages.LAST_MESSAGE_EXCEPTION.format() + e);
0966: throw new RMException(Messages.LAST_MESSAGE_EXCEPTION
0967: .format()
0968: + e);
0969: }
0970: }
0971:
0972: public Packet handleCloseSequenceAction(Packet inbound)
0973: throws RMException {
0974:
0975: CloseSequenceElement csElement;
0976:
0977: String id = null;
0978: Message message = inbound.getMessage();
0979:
0980: try {
0981: csElement = message.readPayloadAsJAXB(unmarshaller);
0982: } catch (JAXBException e) {
0983:
0984: throw new RMException(
0985: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.CLOSESEQUENCE_HEADER_PROBLEM
0986: .format()
0987: + e);
0988: }
0989: id = csElement.getIdentifier().getValue();
0990: ServerInboundSequence seq = provider.getInboundSequence(id);
0991: if (seq == null) {
0992: logger.severe(String.format(
0993: Constants.UNKNOWN_SEQUENCE_TEXT, id + id));
0994: throw new InvalidSequenceException(String.format(
0995: Constants.UNKNOWN_SEQUENCE_TEXT, id), id);
0996: }
0997:
0998: int lastMessageNumber = csElement.getLastMsgNumber();
0999:
1000: CloseSequenceResponseElement csrElement = new com.sun.xml.ws.rm.v200702.CloseSequenceResponseElement();
1001: com.sun.xml.ws.rm.v200702.Identifier identifier = new com.sun.xml.ws.rm.v200702.Identifier();
1002: identifier.setValue(seq.getId());
1003: csrElement.setIdentifier(identifier);
1004:
1005: Message response = com.sun.xml.ws.api.message.Messages.create(
1006: config.getRMVersion().getJAXBContext(), csrElement,
1007: config.getSoapVersion());
1008:
1009: message.assertOneWay(false);
1010:
1011: Packet returnPacket = inbound.createServerResponse(response,
1012: constants.getAddressingVersion(), config
1013: .getSoapVersion(), config.getRMVersion()
1014: .getCloseSequenceResponseAction());
1015:
1016: //Generate SequenceAcknowledgmenet with Final element
1017: AbstractSequenceAcknowledgement element = seq
1018: .generateSequenceAcknowledgement(null, marshaller, true);
1019: Header header = createHeader(element);
1020: response.getHeaders().add(header);
1021:
1022: return returnPacket;
1023:
1024: }
1025:
1026: public Packet handleAckRequestedAction(Packet inbound)
1027: throws RMException {
1028:
1029: try {
1030:
1031: Message message = inbound.getMessage();
1032: Header header = message.getHeaders().get(
1033: config.getRMVersion().getAckRequestedQName(), true);
1034: if (header == null) {
1035: logger
1036: .severe(com.sun.xml.ws.rm.jaxws.runtime.server.Messages.INVALID_ACK_REQUESTED
1037: .format());
1038: throw new RMException(
1039: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.INVALID_ACK_REQUESTED
1040: .format());
1041: }
1042:
1043: AbstractAckRequested el = (AbstractAckRequested) header
1044: .readAsJAXB(unmarshaller);
1045: String id = el.getId();
1046:
1047: ServerInboundSequence seq = provider.getInboundSequence(id);
1048:
1049: if (seq == null) {
1050: logger.severe(Constants.UNKNOWN_SEQUENCE_TEXT + id);
1051: throw new InvalidSequenceException(String.format(
1052: Constants.UNKNOWN_SEQUENCE_TEXT, id), id);
1053: }
1054: seq.resetLastActivityTime();
1055:
1056: return generateAckMessage(inbound, seq, config
1057: .getRMVersion().getSequenceAcknowledgementAction());
1058:
1059: } catch (JAXBException e) {
1060: logger
1061: .severe(com.sun.xml.ws.rm.jaxws.runtime.server.Messages.ACK_REQUESTED_EXCEPTION
1062: .format());
1063: throw new RMException(
1064: com.sun.xml.ws.rm.jaxws.runtime.server.Messages.ACK_REQUESTED_EXCEPTION
1065: .format()
1066: + e);
1067: }
1068:
1069: }
1070:
1071: /**
1072: * Handles a raw SequenceAcknowledgement
1073: */
1074: public Packet handleSequenceAcknowledgementAction(Packet inbound)
1075: throws RMException {
1076: try {
1077:
1078: Message message = inbound.getMessage();
1079: Header header = message.getHeaders().get(
1080: config.getRMVersion()
1081: .getSequenceAcknowledgementQName(), false);
1082: if (header == null) {
1083: logger.severe(Messages.INVALID_SEQ_ACKNOWLEDGEMENT
1084: .format());
1085: throw new RMException(
1086: Messages.INVALID_SEQ_ACKNOWLEDGEMENT.format());
1087: }
1088:
1089: AbstractSequenceAcknowledgement el = (AbstractSequenceAcknowledgement) header
1090: .readAsJAXB(unmarshaller);
1091:
1092: String id;
1093: if (el instanceof SequenceAcknowledgementElement) {
1094: id = ((SequenceAcknowledgementElement) el).getId();
1095: } else {
1096: id = ((com.sun.xml.ws.rm.v200702.SequenceAcknowledgementElement) el)
1097: .getId();
1098: }
1099:
1100: ServerInboundSequence seq = provider.getInboundSequence(id);
1101:
1102: //reset inactivity timer
1103: seq.resetLastActivityTime();
1104: handleInboundMessage(inbound);
1105:
1106: inbound.transportBackChannel.close();
1107: Packet ret = new Packet(null);
1108: ret.invocationProperties
1109: .putAll(inbound.invocationProperties);
1110: return ret;
1111:
1112: } catch (JAXBException e) {
1113: logger.severe(Messages.SEQ_ACKNOWLEDGEMENT_EXCEPTION
1114: .format());
1115: throw new RMException(
1116: Messages.SEQ_ACKNOWLEDGEMENT_EXCEPTION.format() + e);
1117: }
1118: }
1119:
1120: public Packet handleMakeConnectionAction(Packet packet)
1121: throws RMException {
1122:
1123: if (version == RMVersion.WSRM10) {
1124: logger
1125: .severe("Unsupported MakeConnection message to WS-RM 1.0 Endpoint.");
1126: throw new RMException(
1127: "Unsupported MakeConnection message to WS-RM 1.0 Endpoint.");
1128: }
1129:
1130: MakeConnectionElement element = null;
1131: String sequenceId = null;
1132: Message message = packet.getMessage();
1133:
1134: try {
1135: element = message.readPayloadAsJAXB(unmarshaller);
1136: } catch (JAXBException e) {
1137: logger.severe("Invalid MakeConnection message.");
1138: throw new RMException("Invalid MakeConnection message.");
1139: }
1140:
1141: sequenceId = element.getIdentifier().getValue();
1142: OutboundSequence outboundSequence = provider
1143: .getOutboundSequence(sequenceId);
1144:
1145: if (outboundSequence == null) {
1146: logger.severe("Invalid sequence id " + sequenceId
1147: + " in MakeConnection message.");
1148: throw new RMException("Invalid sequence id " + sequenceId
1149: + " in MakeConnection message.");
1150: }
1151:
1152: //see if we can find a message in the sequence that needs to be resent.
1153: com.sun.xml.ws.rm.Message mess = outboundSequence
1154: .getUnacknowledgedMessage();
1155: Message jaxwsMessage = null;
1156: if (mess != null) {
1157: jaxwsMessage = mess.getCopy();
1158: } else {
1159: jaxwsMessage = com.sun.xml.ws.api.message.Messages
1160: .createEmpty(config.getSoapVersion());
1161: }
1162:
1163: Packet ret = new Packet();
1164: ret.setMessage(jaxwsMessage);
1165: ret.invocationProperties.putAll(packet.invocationProperties);
1166: return ret;
1167: }
1168:
1169: /***********************************************************************************/
1170: /* Wiring for dispatch Map mapping wsa:Action values to handlers. We are jumping */
1171: /* through some hoops here to create a Map that only needs to be initialized once. */
1172: /***********************************************************************************/
1173:
1174: private interface ActionHandler {
1175: public Packet process(RMServerTube tube, Packet packet)
1176: throws RMException;
1177: }
1178:
1179: private void initActionMap() {
1180: actionMap.put(config.getRMVersion().getCreateSequenceAction(),
1181: new ActionHandler() {
1182: public Packet process(RMServerTube tube,
1183: Packet packet) throws RMException {
1184: return tube.handleCreateSequenceAction(packet);
1185: }
1186: });
1187:
1188: actionMap.put(config.getRMVersion()
1189: .getTerminateSequenceAction(), new ActionHandler() {
1190: public Packet process(RMServerTube tube, Packet packet)
1191: throws RMException {
1192: return tube.handleTerminateSequenceAction(packet);
1193: }
1194: });
1195:
1196: actionMap.put(config.getRMVersion().getAckRequestedAction(),
1197: new ActionHandler() {
1198: public Packet process(RMServerTube tube,
1199: Packet packet) throws RMException {
1200: return tube.handleAckRequestedAction(packet);
1201: }
1202: });
1203:
1204: actionMap.put(config.getRMVersion().getLastAction(),
1205: new ActionHandler() {
1206: public Packet process(RMServerTube tube,
1207: Packet packet) throws RMException {
1208: return tube.handleLastMessageAction(packet);
1209: }
1210: });
1211:
1212: actionMap.put(RMVersion.WSRM11.getCloseSequenceAction(),
1213: new ActionHandler() {
1214: public Packet process(RMServerTube tube,
1215: Packet packet) throws RMException {
1216: return tube.handleCloseSequenceAction(packet);
1217: }
1218: });
1219:
1220: actionMap.put(config.getRMVersion()
1221: .getSequenceAcknowledgementAction(),
1222: new ActionHandler() {
1223: public Packet process(RMServerTube tube,
1224: Packet packet) throws RMException {
1225: return tube
1226: .handleSequenceAcknowledgementAction(packet);
1227: }
1228: });
1229:
1230: actionMap.put(config.getRMVersion().getMakeConnectionAction(),
1231: new ActionHandler() {
1232: public Packet process(RMServerTube tube,
1233: Packet packet) throws RMException {
1234: return tube.handleMakeConnectionAction(packet);
1235: }
1236: });
1237:
1238: }
1239:
1240: /*
1241: * Private helper functions.
1242: */
1243:
1244: /**
1245: * Returns a message containing a fault defined by the WS-RM spec.
1246: *
1247: * @param
1248: * e An Exception mapped to a WS-RM defined fault.
1249: * @return
1250: * The mapped fault
1251: * @throws
1252: * Exception - Exceptions not mapped to well-known fault types are
1253: * rethrown.
1254: */
1255:
1256: /**
1257: * Initialize a <code>SequenceConfig</code> using the metadata passed in the
1258: * ctor.
1259: */
1260: private SequenceConfig getSequenceConfig() {
1261:
1262: SequenceConfig ret;
1263: if (wsdlModel != null) {
1264: /*
1265: If there is a WSDL, use the SequenceConfig ctor taking a WSDLPort and
1266: initialize SOAPVersion according to the value obtained from the binding.
1267: */
1268: ret = new SequenceConfig(wsdlModel, this .binding);
1269: BindingID bindingid = wsdlModel.getBinding().getBindingId();
1270: if (bindingid.equals(BindingID
1271: .parse(SOAPBinding.SOAP11HTTP_BINDING))) {
1272: ret.setSoapVersion(SOAPVersion.SOAP_11);
1273: } else {
1274: ret.setSoapVersion(SOAPVersion.SOAP_12);
1275: }
1276: } else {
1277: /*
1278: Use SequenceConfig initialized with default values.
1279: */
1280: ret = new SequenceConfig();
1281: }
1282: return ret;
1283: }
1284:
1285: /**
1286: * Determine whether the STR used to secure request message is the one passed in
1287: * the CreateSequence message for the sequence.
1288: *
1289: * @param packet The inbound Packet containing the STR in a property
1290: * @param seq The InboundSequence
1291: *
1292: * @throws RMSecurityException if STR is missing or incorrect.
1293: */
1294:
1295: private void checkSTR(Packet packet, InboundSequence seq)
1296: throws RMSecurityException {
1297: SecurityContextToken sct = (SecurityContextToken) packet.invocationProperties
1298: .get(MessageConstants.INCOMING_SCT);
1299: URI uri = sct.getIdentifier();
1300: if (!uri.toString().equals(seq.getStrId())) {
1301: logger.severe(Messages.SECURITY_TOKEN_MISMATCH.format());
1302: throw new RMSecurityException(
1303: Messages.SECURITY_TOKEN_MISMATCH.format());
1304: }
1305: }
1306:
1307: /**
1308: * Create a Packet containing a message with empty body and a single
1309: * SequenceAcknowledgement header reflecting the current status of
1310: * the specified inbound sequence.
1311: *
1312: * @param inbound Packet in request for which this method is being used
1313: * to build a response.
1314: * @param seq The specified InboundSequence
1315: * @throws RMException
1316: */
1317: private Packet generateAckMessage(Packet inbound,
1318: ServerInboundSequence seq) throws RMException {
1319: return generateAckMessage(inbound, seq, null);
1320: }
1321:
1322: /**
1323: * Create a Packet containing a message with empty body and a single
1324: * SequenceAcknowledgement header reflecting the current status of
1325: * the specified inbound sequence.
1326: *
1327: * @param inbound Packet in request for which this method is being used
1328: * to build a response.
1329: * @param seq The specified InboundSequence
1330: * @param action If null, add as value of wsa:Action
1331: * @param isFinal Required when the version is RM 1.1 the SequenceAcknowledgement element should have a
1332: * @throws RMException
1333: */
1334: private Packet generateAckMessage(Packet inbound,
1335: ServerInboundSequence seq, String action)
1336: throws RMException {
1337:
1338: //construct empty non-application message to be used as a conduit for
1339: //this SequenceAcknowledgement header.
1340: Message message = com.sun.xml.ws.api.message.Messages
1341: .createEmpty(config.getSoapVersion());
1342: Packet outbound = new Packet(message);
1343: outbound.invocationProperties
1344: .putAll(inbound.invocationProperties);
1345:
1346: //construct the SequenceAcknowledgement header and add it to thge message.
1347: AbstractSequenceAcknowledgement element = seq
1348: .generateSequenceAcknowledgement(null, marshaller,
1349: false);
1350: //Header header = Headers.create(config.getSoapVersion(),marshaller,element);
1351: Header header = createHeader(element);
1352: message.getHeaders().add(header);
1353: if (action != null) {
1354: Header h = Headers.create(
1355: constants.getAddressingVersion().actionTag, action);
1356: message.getHeaders().add(h);
1357: }
1358:
1359: return outbound;
1360: }
1361:
1362: private SOAPFault newMessageNumberRolloverFault(
1363: MessageNumberRolloverException e) throws RMException {
1364: QName subcode = config.getRMVersion()
1365: .getMessageNumberRolloverQname();
1366: String faultstring = String.format(
1367: Constants.MESSAGE_NUMBER_ROLLOVER_TEXT, e
1368: .getMessageNumber());
1369:
1370: try {
1371: SOAPFactory factory;
1372: SOAPFault fault;
1373: if (binding.getSOAPVersion() == SOAPVersion.SOAP_12) {
1374: factory = SOAPVersion.SOAP_12.saajSoapFactory;
1375: fault = factory.createFault();
1376: fault.setFaultCode(Constants.SOAP12_SENDER_QNAME);
1377: fault.appendFaultSubcode(subcode);
1378: // not sure what more to put in detail element
1379:
1380: } else {
1381: factory = SOAPVersion.SOAP_11.saajSoapFactory;
1382: fault = factory.createFault();
1383: fault.setFaultCode(subcode);
1384: }
1385:
1386: fault.setFaultString(faultstring);
1387:
1388: return fault;
1389: } catch (SOAPException se) {
1390: throw new RMException(se);
1391: }
1392: }
1393:
1394: private SOAPFault newUnknownSequenceFault(InvalidSequenceException e)
1395: throws RMException {
1396: QName subcode = config.getRMVersion().getUnknownSequenceQname();
1397: String faultstring = String.format(
1398: Constants.UNKNOWN_SEQUENCE_TEXT, e.getSequenceId());
1399:
1400: try {
1401: SOAPFactory factory;
1402: SOAPFault fault;
1403: if (binding.getSOAPVersion() == SOAPVersion.SOAP_12) {
1404: factory = SOAPVersion.SOAP_12.saajSoapFactory;
1405: fault = factory.createFault();
1406: fault.setFaultCode(Constants.SOAP12_SENDER_QNAME);
1407: fault.appendFaultSubcode(subcode);
1408: // not sure what more to put in detail element
1409:
1410: } else {
1411: factory = SOAPVersion.SOAP_11.saajSoapFactory;
1412: fault = factory.createFault();
1413: fault.setFaultCode(subcode);
1414: }
1415:
1416: fault.setFaultString(faultstring);
1417:
1418: return fault;
1419: } catch (SOAPException se) {
1420: throw new RMException(se);
1421: }
1422: }
1423:
1424: private SOAPFault newClosedSequenceFault(CloseSequenceException e)
1425: throws RMException {
1426: QName subcode = config.getRMVersion().getClosedSequenceQname();
1427: String faultstring = String.format(
1428: Constants.SEQUENCE_CLOSED_TEXT, e.getSequenceId());
1429:
1430: try {
1431: SOAPFactory factory;
1432: SOAPFault fault;
1433: if (binding.getSOAPVersion() == SOAPVersion.SOAP_12) {
1434: factory = SOAPVersion.SOAP_12.saajSoapFactory;
1435: fault = factory.createFault();
1436: fault.setFaultCode(Constants.SOAP12_SENDER_QNAME);
1437: fault.appendFaultSubcode(subcode);
1438: // not sure what more to put in detail element
1439:
1440: } else {
1441: factory = SOAPVersion.SOAP_11.saajSoapFactory;
1442: fault = factory.createFault();
1443: fault.setFaultCode(subcode);
1444: }
1445:
1446: fault.setFaultString(faultstring);
1447:
1448: return fault;
1449: } catch (SOAPException se) {
1450: throw new RMException(se);
1451: }
1452: }
1453:
1454: private SOAPFault newSequenceTerminatedFault(
1455: TerminateSequenceException e) throws RMException {
1456: QName subcode = config.getRMVersion()
1457: .getSequenceTerminatedQname();
1458: String faultstring = String.format(
1459: Constants.SEQUENCE_TERMINATED_TEXT, e.getMessage());
1460:
1461: try {
1462: SOAPFactory factory;
1463: SOAPFault fault;
1464: if (binding.getSOAPVersion() == SOAPVersion.SOAP_12) {
1465: factory = SOAPVersion.SOAP_12.saajSoapFactory;
1466: fault = factory.createFault();
1467: fault.setFaultCode(Constants.SOAP12_SENDER_QNAME);
1468: fault.appendFaultSubcode(subcode);
1469: // detail empty
1470:
1471: } else {
1472: factory = SOAPVersion.SOAP_11.saajSoapFactory;
1473: fault = factory.createFault();
1474: fault.setFaultCode(subcode);
1475: }
1476:
1477: fault.setFaultString(faultstring);
1478:
1479: return fault;
1480: } catch (SOAPException se) {
1481: throw new RMException(se);
1482: }
1483: }
1484:
1485: private SOAPFault newCreateSequenceRefusedFault(
1486: CreateSequenceException e) throws RMException {
1487: QName subcode = config.getRMVersion()
1488: .getCreateSequenceRefusedQname();
1489: String faultstring = String.format(
1490: Constants.CREATE_SEQUENCE_REFUSED_TEXT, e.getMessage());
1491:
1492: try {
1493: SOAPFactory factory;
1494: SOAPFault fault;
1495: if (binding.getSOAPVersion() == SOAPVersion.SOAP_12) {
1496: factory = SOAPVersion.SOAP_12.saajSoapFactory;
1497: fault = factory.createFault();
1498: fault.setFaultCode(Constants.SOAP12_SENDER_QNAME);
1499: fault.appendFaultSubcode(subcode);
1500: // detail empty
1501:
1502: } else {
1503: factory = SOAPVersion.SOAP_11.saajSoapFactory;
1504: fault = factory.createFault();
1505: fault.setFaultCode(subcode);
1506: }
1507:
1508: fault.setFaultString(faultstring);
1509:
1510: return fault;
1511: } catch (SOAPException se) {
1512: throw new RMException(se);
1513: }
1514:
1515: }
1516:
1517: private Header createHeader(Object obj) {
1518: return Headers.create(config.getRMVersion()
1519: .getJAXBRIContextHeaders(), obj);
1520: }
1521:
1522: /**
1523: * Either creates a new <code>Session</code> for the
1524: * <code>InboundSequence</code> or returns one that has
1525: * already been created by the SC Pipe.
1526: *
1527: * @param sequence The InboundSequence
1528: * @return The Session
1529: */
1530: public Session startSession(InboundSequence sequence) {
1531: String id = sequence.getSessionId();
1532: Session sess = sessionManager.getSession(id);
1533: if (sess == null) {
1534: sess = sessionManager.createSession(id);
1535: }
1536:
1537: sess.setSequence(sequence);
1538: return sess;
1539: }
1540:
1541: /**
1542: * Terminates the session associated with the sequence if
1543: * RM owns the lifetime of the session.. i.e. If SC is not present.
1544: *
1545: * @param sequence The InboundSequence
1546: */
1547: public void endSession(InboundSequence sequence) {
1548: String sessionId = sequence.getSessionId();
1549: if (sessionId.equals(sequence.getId())) {
1550: //we own the session
1551: sessionManager.terminateSession(sessionId);
1552: }
1553: }
1554:
1555: /**
1556: * Sets the session and session id properties in a request packet
1557: * if necessary. This will be the case if SC has not already done
1558: * so.
1559: *
1560: * @param packet The packet.
1561: * @param seq The sequence to which the request message belongs.
1562: */
1563: public void setSessionData(Packet packet, InboundSequence seq) {
1564: if (null == packet.invocationProperties
1565: .get(Session.SESSION_ID_KEY)) {
1566: packet.invocationProperties.put(Session.SESSION_ID_KEY, seq
1567: .getSessionId());
1568: }
1569:
1570: if (null == packet.invocationProperties
1571: .get(Session.SESSION_KEY)) {
1572: Session sess = sessionManager
1573: .getSession(seq.getSessionId());
1574: packet.invocationProperties.put(Session.SESSION_KEY, sess
1575: .getUserData());
1576:
1577: }
1578:
1579: }
1580:
1581: }
|