ee.ria.xroad.proxy.messagelog.SoapMessageBodyManipulator.java Source code

Java tutorial

Introduction

Here is the source code for ee.ria.xroad.proxy.messagelog.SoapMessageBodyManipulator.java

Source

/**
 * The MIT License
 * Copyright (c) 2015 Estonian Information System Authority (RIA), Population Register Centre (VRK)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package ee.ria.xroad.proxy.messagelog;

import java.util.Collection;
import java.util.Objects;

import com.google.common.collect.Iterables;

import ee.ria.xroad.common.identifier.ClientId;
import ee.ria.xroad.common.message.SoapBuilder;
import ee.ria.xroad.common.message.SoapHeader;
import ee.ria.xroad.common.message.SoapMessageImpl;
import ee.ria.xroad.common.message.SoapUtils;
import ee.ria.xroad.common.messagelog.MessageLogProperties;
import lombok.Setter;

/**
 * Utility class for processing SoapMessages and removing altered message with <soap:body>
 * section removed.
 */
public class SoapMessageBodyManipulator {

    /**
     * Extract configuration reading for better testability
     */
    public class Configurator {
        /**
         * Returns list of local producer subsystem ClientIds for which global SOAP body logging
         * setting is overridden
         * @return list of ClientId
         */
        public Collection<ClientId> getLocalProducerOverrides() {
            return MessageLogProperties.getSoapBodyLoggingLocalProducerOverrides();
        }

        /**
         * Returns list of remote producer subsystem ClientIds for which global SOAP body logging
         * setting is overridden
         * @return list of ClientId
         */
        public Collection<ClientId> getRemoteProducerOverrides() {
            return MessageLogProperties.getSoapBodyLoggingRemoteProducerOverrides();
        }

        /**
         * Tells whether SOAP body logging is enabled
         * @return true if enabled
         */
        public boolean isSoapBodyLoggingEnabled() {
            return MessageLogProperties.isSoapBodyLoggingEnabled();
        }
    }

    @Setter
    private Configurator configurator = new Configurator();

    /**
     * Returns the string that should be logged. This will either be the original soap message
     * (when soap:body logging is used for this message) or manipulated soap message with
     * soap:body element cleared.
     * @param message soap message
     * @param clientSide whether we are calling external service (true) or someone else is calling our service (false)
     * @return the string that should be logged
     * @throws Exception when error occurs
     */
    public String getLoggableMessageText(SoapMessageImpl message, boolean clientSide) throws Exception {
        if (isSoapBodyLogged(message, clientSide)) {
            return message.getXml();
        } else {
            return buildBodyRemovedMessage(message);
        }
    }

    private String buildBodyRemovedMessage(SoapMessageImpl message) throws Exception {
        // build a new empty message with SoapBuilder and
        // set old SoapHeader to it
        SoapHeader oldHeader = message.getHeader();
        SoapBuilder builder = new SoapBuilder();
        builder.setHeader(oldHeader);
        builder.setRpcEncoded(false);
        SoapMessageImpl blankedMessage = builder.build();
        if (message.isResponse()) {
            // need to convert this to response message (changes body element name)
            // otherwise asicverifier gets confused
            blankedMessage = SoapUtils.toResponse(blankedMessage);
        }
        return blankedMessage.getXml();
    }

    /**
     * Tells whether SOAP body should be logged for this message.
     * @param message SOAP message
     * @param clientSide whether we are calling external service (true) or someone
     *                   else is calling our service (false)
     * @return true if this message's body is logged
     */
    public boolean isSoapBodyLogged(SoapMessageImpl message, boolean clientSide) {

        Collection<ClientId> overrides;
        if (clientSide) {
            overrides = configurator.getRemoteProducerOverrides();
        } else {
            overrides = configurator.getLocalProducerOverrides();
        }

        boolean producerSubsystemIsOverridden = isClientInCollection(message.getService().getClientId(), overrides);

        if (configurator.isSoapBodyLoggingEnabled()) {
            return !producerSubsystemIsOverridden;
        } else {
            return producerSubsystemIsOverridden;
        }
    }

    /**
     * Takes one ClientId object, and searches whether it is in searched group of ClientIds
     * @param searchParam ClientId to search
     * @param searched collection to search from
     * @return true if ClientId is in the collection
     */
    public boolean isClientInCollection(ClientId searchParam, Iterable<ClientId> searched) {
        ClientId searchResult = Iterables.find(searched, input -> (input.memberEquals(searchParam)
                && Objects.equals(input.getSubsystemCode(), searchParam.getSubsystemCode())), null);
        return (searchResult != null);
    }

}