ee.ria.xroad.common.message.SoapMessageTest.java Source code

Java tutorial

Introduction

Here is the source code for ee.ria.xroad.common.message.SoapMessageTest.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.common.message;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;

import org.apache.commons.io.IOUtils;

import org.bouncycastle.util.Arrays;

import org.junit.Rule;
import org.junit.Test;

import ee.ria.xroad.common.identifier.CentralServiceId;
import ee.ria.xroad.common.identifier.ClientId;
import ee.ria.xroad.common.identifier.ServiceId;
import ee.ria.xroad.common.util.ExpectedCodedException;
import ee.ria.xroad.common.util.MimeTypes;

import static ee.ria.xroad.common.ErrorCodes.*;
import static ee.ria.xroad.common.message.SoapMessageTestUtil.*;
import static ee.ria.xroad.common.message.SoapUtils.getChildElements;
import static org.junit.Assert.*;

/**
 * This class tests the basic functionality (parsing the soap message etc.) of the SoapMessage class.
 */
public class SoapMessageTest {

    @Rule
    public ExpectedCodedException thrown = ExpectedCodedException.none();

    /**
     * Test that reading a normal request message is successful and that header and body are correctly parsed.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void simpleRequest() throws Exception {
        SoapMessageImpl message = createRequest("simple.query");

        ClientId expectedClient = ClientId.create("EE", "BUSINESS", "consumer");
        ServiceId expectedService = ServiceId.create("EE", "BUSINESS", "producer", null, "testQuery");

        assertTrue(message.isRequest());
        assertEquals(expectedClient, message.getClient());
        assertEquals(expectedService, message.getService());
        assertEquals("EE37702211234", message.getUserId());
        assertEquals("1234567890", message.getQueryId());
    }

    /**
     * Test that reading a normal RPC encoded request message is successful
     * and that header and body are correctly parsed.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void simpleRpcRequest() throws Exception {
        SoapMessageImpl message = createRequest("simple-rpc.query");

        ClientId expectedClient = ClientId.create("EE", "BUSINESS", "consumer");
        ServiceId expectedService = ServiceId.create("EE", "BUSINESS", "producer", null, "testQuery");

        assertTrue(message.isRpcEncoded());
        assertTrue(message.isRequest());
        assertEquals(expectedClient, message.getClient());
        assertEquals(expectedService, message.getService());
        assertEquals("EE37702211234", message.getUserId());
        assertEquals("1234567890", message.getQueryId());
    }

    /**
     * Test that reading a normal response message is successful and that header and body are correctly parsed.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void simpleResponse() throws Exception {
        SoapMessageImpl message = createResponse("simple.answer");

        ClientId expectedClient = ClientId.create("EE", "BUSINESS", "consumer");
        ServiceId expectedService = ServiceId.create("EE", "BUSINESS", "producer", null, "testQuery");

        assertTrue(message.isResponse());
        assertEquals(expectedClient, message.getClient());
        assertEquals(expectedService, message.getService());
        assertEquals("EE37702211234", message.getUserId());
        assertEquals("1234567890", message.getQueryId());
    }

    /**
     * Test that represented party header element is correctly parsed.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void simpleRepresentedPartyAndIssueInHeaderRequest() throws Exception {
        SoapMessageImpl message = createRequest("simple-representedparty.query");
        RepresentedParty expectedRepresentedParty = new RepresentedParty("COM", "MEMBER3");
        String expectedIssue = "issue-1";

        assertEquals(expectedRepresentedParty, message.getRepresentedParty());
        assertEquals(expectedIssue, message.getIssue());
    }

    /**
     * Tests that missing header is detected on not fault messages.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void missingHeader() throws Exception {
        thrown.expectError(X_MISSING_HEADER);
        createSoapMessage("no-header.query");
    }

    /**
     * Tests that missing body is detected.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void missingBody() throws Exception {
        thrown.expectError(X_MISSING_BODY);
        createSoapMessage("missing-body.query");
    }

    /**
     * Tests that missing required header fields are detected.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void missingRequiredHeaderField() throws Exception {
        thrown.expectError(X_MISSING_HEADER_FIELD);
        createSoapMessage("faulty-header.query");
    }

    /**
     * Tests that userId header field is optional.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void optionalUserIdField() throws Exception {
        createSoapMessage("missing-userId.query");
    }

    /**
     * Tests that duplicate header fields are detected.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void duplicateHeaderField() throws Exception {
        thrown.expectError(X_DUPLICATE_HEADER_FIELD);
        createSoapMessage("faulty-header2.query");
    }

    /**
     * Tests that body with more than one child elements is detected.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void malformedBody() throws Exception {
        thrown.expectError(X_INVALID_BODY);
        createSoapMessage("malformed-body1.query");
    }

    /**
     * Tests that service name mismatch in header and body is detected.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void inconsistentHeaders() throws Exception {
        thrown.expectError(X_INCONSISTENT_HEADERS);
        createSoapMessage("inconsistent-headers.query");
    }

    /**
     * Tests that message with invalid content type is detected.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void invalidContentType() throws Exception {
        thrown.expectError(X_INVALID_CONTENT_TYPE);

        try (FileInputStream in = new FileInputStream(QUERY_DIR + "simple.query")) {
            new SaxSoapParserImpl().parse(MimeTypes.TEXT_HTML_UTF8, in);
        }
    }

    /**
     * Tests that SoapMessage class understands fault messages.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void faultMessage() throws Exception {
        String soapFaultXml = SoapFault.createFaultXml("foo.bar", "baz", "xxx", "yyy");
        Soap message = new SaxSoapParserImpl().parse(MimeTypes.TEXT_XML_UTF8,
                new ByteArrayInputStream(soapFaultXml.getBytes()));

        assertTrue(message instanceof SoapFault);

        SoapFault fault = (SoapFault) message;
        assertEquals("foo.bar", fault.getCode());
        assertEquals("baz", fault.getString());
        assertEquals("xxx", fault.getActor());
        assertEquals("yyy", fault.getDetail());
    }

    /**
     * Checks that inconsistencies between two messages are detected.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void consistentMessages() throws Exception {
        SoapMessageImpl m1 = createRequest("getstate.query");
        SoapMessageImpl m2 = createResponse("getstate.answer");
        SoapUtils.checkConsistency(m1, m2);
    }

    /**
     * Checks that inconsistencies between two messages are detected.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void inconsistentMessages() throws Exception {
        SoapMessageImpl m1 = createRequest("simple.query");
        SoapUtils.checkConsistency(m1, m1);

        SoapMessageImpl m2 = createResponse("getstate.answer");
        thrown.expectError(X_INCONSISTENT_HEADERS);
        SoapUtils.checkConsistency(m1, m2);
    }

    /**
     * Checks that a request message can be converted to a response message.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void requestToResponse() throws Exception {
        SoapMessageImpl request = createRequest("simple.query");

        SoapMessageImpl response = SoapUtils.toResponse(request);
        assertTrue(response.isResponse());
    }

    /**
     * Test that request with are quest suffix is correctly converted to a request.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void removeRequestSuffixFromResponse() throws Exception {
        SoapMessageImpl request = createRequest("request-suffix.query");

        SoapMessageImpl response = SoapUtils.toResponse(request);

        QName responseChild = getResponseChild(response);
        assertEquals("testQueryResponse", responseChild.getLocalPart());
    }

    private QName getResponseChild(SoapMessageImpl response) throws SOAPException {
        List<SOAPElement> bodyChildren = getChildElements(response.getSoap().getSOAPBody());
        return bodyChildren.get(0).getElementQName();
    }

    /**
     * Tests that we can parse our own created Soap messages.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void shouldParseBuiltMessage() throws Exception {
        ClientId client = ClientId.create("EE", "BUSINESS", "producer");
        ServiceId service = ServiceId.create("EE", "BUSINESS", "consumer", null, "test");
        CentralServiceId centralService = CentralServiceId.create("EE", "central");
        String userId = "foobar";
        String queryId = "barbaz";

        SoapMessageImpl built = build(client, service, userId, queryId);
        assertNotNull(built);
        assertEquals(userId, built.getUserId());
        assertEquals(queryId, built.getQueryId());
        assertEquals(client, built.getClient());
        assertEquals(service, built.getService());

        Soap parsedSoap = new SaxSoapParserImpl().parse(built.getContentType(),
                new ByteArrayInputStream(built.getBytes()));
        assertTrue(parsedSoap instanceof SoapMessageImpl);

        SoapMessageImpl parsed = (SoapMessageImpl) parsedSoap;
        assertNotNull(parsed);

        SoapUtils.checkConsistency(built, parsed);
        assertEquals(built.isRequest(), parsed.isRequest());

        // Central Service ----------------------------------------------------

        built = build(client, centralService, userId, queryId);
        assertNotNull(built);
        assertEquals(userId, built.getUserId());
        assertEquals(queryId, built.getQueryId());
        assertEquals(client, built.getClient());
        assertEquals(centralService, built.getCentralService());

        parsedSoap = new SaxSoapParserImpl().parse(built.getContentType(), IOUtils.toInputStream(built.getXml()));
        assertTrue(parsedSoap instanceof SoapMessageImpl);

        parsed = (SoapMessageImpl) parsedSoap;
        assertNotNull(parsed);

        SoapUtils.checkConsistency(built, parsed);
        assertEquals(built.isRequest(), parsed.isRequest());
    }

    /**
     * Tests that we can parse our own created Soap messages.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void shouldBuildRpcMessage() throws Exception {
        ClientId client = ClientId.create("EE", "BUSINESS", "producer");
        ServiceId service = ServiceId.create("EE", "BUSINESS", "consumer", null, "test");
        String userId = "foobar";
        String queryId = "barbaz";

        SoapMessageImpl built = build(true, client, service, userId, queryId);

        assertNotNull(built);
        assertTrue(built.isRpcEncoded());
        assertEquals(userId, built.getUserId());
        assertEquals(queryId, built.getQueryId());
        assertEquals(client, built.getClient());
        assertEquals(service, built.getService());
    }

    /**
     * Tests that missing header field is checked.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void shouldNotBuildWithoutMissingHeaderFields() throws Exception {
        thrown.expectError(X_MISSING_HEADER_FIELD);

        ClientId client = null;
        ServiceId service = ServiceId.create("EE", "BUSINESS", "consumer", null, "test");
        String userId = "foobar";
        String queryId = "barbaz";

        build(client, service, userId, queryId);
    }

    /**
     * Test that input message is not re-encoded when getting XML.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void shouldNotReencodeInputMessage() throws Exception {
        byte[] in = fileToBytes("simple.query");
        byte[] out = messageToBytes(createSoapMessage(in));

        assertTrue(Arrays.areEqual(in, out));
    }

    /**
     * Test that central service query is parsed correctly.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void centralServiceMessage() throws Exception {
        SoapMessageImpl message = createRequest("simple-centralservice.query");

        ClientId expectedClient = ClientId.create("EE", "BUSINESS", "consumer");

        CentralServiceId expectedService = CentralServiceId.create("EE", "centralservice");

        assertTrue(message.isRequest());
        assertEquals(expectedClient, message.getClient());
        assertEquals(expectedService, message.getCentralService());
        assertEquals("EE37702211234", message.getUserId());
        assertEquals("1234567890", message.getQueryId());
    }

    /**
     * Test that central service query is parsed correctly.
     * @throws Exception in case of any unexpected errors
     */
    @Test
    public void wrongProtocolVersion() throws Exception {
        thrown.expectError(X_INVALID_PROTOCOL_VERSION);
        createRequest("wrong-version.query");
    }
}