Package org.springframework.ws.soap.addressing.server

Source Code of org.springframework.ws.soap.addressing.server.AddressingEndpointInterceptor

/*
* Copyright 2005-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.ws.soap.addressing.server;

import java.io.IOException;
import java.net.URI;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.util.Assert;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.addressing.core.EndpointReference;
import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
import org.springframework.ws.soap.addressing.messageid.MessageIdStrategy;
import org.springframework.ws.soap.addressing.version.AddressingVersion;
import org.springframework.ws.soap.server.SoapEndpointInterceptor;
import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.ws.transport.WebServiceMessageSender;

/**
* {@link SoapEndpointInterceptor} implementation that deals with WS-Addressing headers. Stateful, and instantiated by
* the {@link AbstractAddressingEndpointMapping}.
*
* @author Arjen Poutsma
* @since 1.5.0
*/
class AddressingEndpointInterceptor implements SoapEndpointInterceptor {

    private static final Log logger = LogFactory.getLog(AddressingEndpointInterceptor.class);

    private final AddressingVersion version;

    private final MessageIdStrategy messageIdStrategy;

    private final WebServiceMessageSender[] messageSenders;

    private URI replyAction;

    private URI faultAction;

    AddressingEndpointInterceptor(AddressingVersion version,
                                  MessageIdStrategy messageIdStrategy,
                                  WebServiceMessageSender[] messageSenders,
                                  URI replyAction,
                                  URI faultAction) {
        Assert.notNull(version, "version must not be null");
        Assert.notNull(messageIdStrategy, "messageIdStrategy must not be null");
        Assert.notNull(messageSenders, "'messageSenders' must not be null");
        this.version = version;
        this.messageIdStrategy = messageIdStrategy;
        this.messageSenders = messageSenders;
        this.replyAction = replyAction;
        this.faultAction = faultAction;
    }

    @Override
    public final boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
        Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
        SoapMessage request = (SoapMessage) messageContext.getRequest();
        MessageAddressingProperties requestMap = version.getMessageAddressingProperties(request);
        if (!version.hasRequiredProperties(requestMap)) {
            version.addMessageAddressingHeaderRequiredFault((SoapMessage) messageContext.getResponse());
            return false;
        }
        if (messageIdStrategy.isDuplicate(requestMap.getMessageId())) {
            version.addInvalidAddressingHeaderFault((SoapMessage) messageContext.getResponse());
            return false;
        }
        return true;
    }

    @Override
    public final boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        return handleResponseOrFault(messageContext, false);
    }

    @Override
    public final boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
        return handleResponseOrFault(messageContext, true);
    }

    private boolean handleResponseOrFault(MessageContext messageContext, boolean isFault) throws Exception {
        Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
        Assert.isInstanceOf(SoapMessage.class, messageContext.getResponse());
        MessageAddressingProperties requestMap =
                version.getMessageAddressingProperties((SoapMessage) messageContext.getRequest());
        EndpointReference replyEpr = !isFault ? requestMap.getReplyTo() : requestMap.getFaultTo();
        if (handleNoneAddress(messageContext, replyEpr)) {
            return false;
        }
        SoapMessage reply = (SoapMessage) messageContext.getResponse();
        URI replyMessageId = getMessageId(reply);
        URI action = isFault ? faultAction : replyAction;
        MessageAddressingProperties replyMap = requestMap.getReplyProperties(replyEpr, action, replyMessageId);
        version.addAddressingHeaders(reply, replyMap);
        if (handleAnonymousAddress(messageContext, replyEpr)) {
            return true;
        }
        else {
            sendOutOfBand(messageContext, replyEpr);
            return false;
        }
    }

    private boolean handleNoneAddress(MessageContext messageContext, EndpointReference replyEpr) {
        if (replyEpr == null || version.hasNoneAddress(replyEpr)) {
            if (logger.isDebugEnabled()) {
                logger.debug(
                        "Request [" + messageContext.getRequest() + "] has [" + replyEpr + "] reply address; reply [" +
                                messageContext.getResponse() + "] discarded");
            }
            messageContext.clearResponse();
            return true;
        }
        return false;
    }

    private boolean handleAnonymousAddress(MessageContext messageContext, EndpointReference replyEpr) {
        if (version.hasAnonymousAddress(replyEpr)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Request [" + messageContext.getRequest() + "] has [" + replyEpr +
                        "] reply address; sending in-band reply [" + messageContext.getResponse() + "]");
            }
            return true;
        }
        return false;
    }

    private void sendOutOfBand(MessageContext messageContext, EndpointReference replyEpr) throws IOException {
        if (logger.isDebugEnabled()) {
            logger.debug("Request [" + messageContext.getRequest() + "] has [" + replyEpr +
                    "] reply address; sending out-of-band reply [" + messageContext.getResponse() + "]");
        }

        boolean supported = false;
        for (WebServiceMessageSender messageSender : messageSenders) {
            if (messageSender.supports(replyEpr.getAddress())) {
                supported = true;
                WebServiceConnection connection = null;
                try {
                    connection = messageSender.createConnection(replyEpr.getAddress());
                    connection.send(messageContext.getResponse());
                    break;
                }
                finally {
                    messageContext.clearResponse();
                    if (connection != null) {
                        connection.close();
                    }
                }
            }
        }
        if (!supported && logger.isWarnEnabled()) {
            logger.warn("Could not send out-of-band response to [" + replyEpr.getAddress() + "]. " +
                    "Configure WebServiceMessageSenders which support this uri.");
        }
    }

    private URI getMessageId(SoapMessage response) {
        URI responseMessageId = messageIdStrategy.newMessageId(response);
        if (logger.isTraceEnabled()) {
            logger.trace("Generated reply MessageID [" + responseMessageId + "] for [" + response + "]");
        }
        return responseMessageId;
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
    }

    @Override
    public boolean understands(SoapHeaderElement header) {
        return version.understands(header);
    }
}
TOP

Related Classes of org.springframework.ws.soap.addressing.server.AddressingEndpointInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.