SWS-544 - Added XSD validation
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2005-2010 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.mock.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.xml.validation.XmlValidator;
|
||||
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/**
|
||||
* Uses the {@link XmlValidator} to validate request payload.
|
||||
*
|
||||
* @author Lukas Krecan
|
||||
* @since 2.0
|
||||
*/
|
||||
class SchemaValidatingRequestMatcher implements RequestMatcher {
|
||||
|
||||
private final XmlValidator xmlValidator;
|
||||
|
||||
public SchemaValidatingRequestMatcher(XmlValidator xmlValidator) {
|
||||
Assert.notNull(xmlValidator, "XmlValidator has to be set");
|
||||
this.xmlValidator = xmlValidator;
|
||||
}
|
||||
|
||||
public void match(URI uri, WebServiceMessage request) throws IOException, AssertionError {
|
||||
SAXParseException[] exceptions = xmlValidator.validate(request.getPayloadSource());
|
||||
if (!ObjectUtils.isEmpty(exceptions)) {
|
||||
throw new AssertionError("XML is not valid: " + Arrays.toString(exceptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.client.core.WebServiceTemplate;
|
||||
import org.springframework.xml.transform.ResourceSource;
|
||||
import org.springframework.xml.validation.XmlValidator;
|
||||
import org.springframework.xml.validation.XmlValidatorFactory;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
@@ -84,6 +86,27 @@ public abstract class WebServiceMock {
|
||||
return new PayloadDiffMatcher(createResourceSource(payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects the payload to validate against the given XSD schema(s).
|
||||
*
|
||||
* @param schema the schema
|
||||
* @param furtherSchemas further schemas, if necessary
|
||||
* @return the request matcher
|
||||
*/
|
||||
public static RequestMatcher validPayload(Resource schema, Resource... furtherSchemas) {
|
||||
try {
|
||||
Resource[] joinedSchemas = new Resource[furtherSchemas.length + 1];
|
||||
joinedSchemas[0] = schema;
|
||||
System.arraycopy(furtherSchemas, 0, joinedSchemas, 1, furtherSchemas.length);
|
||||
XmlValidator validator =
|
||||
XmlValidatorFactory.createValidator(joinedSchemas, XmlValidatorFactory.SCHEMA_W3C_XML);
|
||||
return new SchemaValidatingRequestMatcher(validator);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalArgumentException("Schema(s) could not be opened", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects the given SOAP header in the outgoing message.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2005-2010 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.mock.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.xml.transform.StringSource;
|
||||
import org.springframework.xml.validation.XmlValidator;
|
||||
import org.springframework.xml.validation.XmlValidatorFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.easymock.EasyMock.*;
|
||||
|
||||
public class SchemaValidatingRequestMatcherTest {
|
||||
|
||||
private Resource schema2;
|
||||
|
||||
private Resource schema1;
|
||||
|
||||
private WebServiceMessage message;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
message = createMock(WebServiceMessage.class);
|
||||
schema1 = new ClassPathResource("schemaValidatingRequestMatcherTest.xsd", SchemaValidatingRequestMatcherTest.class);
|
||||
schema2 = new ByteArrayResource("".getBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleSchemaMatch() throws IOException, AssertionError {
|
||||
expect(message.getPayloadSource()).andReturn(new StringSource(
|
||||
"<test xmlns=\"http://www.example.org/schema\"><number>0</number><text>text</text></test>"));
|
||||
|
||||
RequestMatcher requestMatcher = WebServiceMock.validPayload(schema1);
|
||||
|
||||
replay(message);
|
||||
|
||||
requestMatcher.match(null, message);
|
||||
|
||||
verify(message);
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void singleSchemaNonMatch() throws IOException, AssertionError {
|
||||
expect(message.getPayloadSource()).andReturn(new StringSource(
|
||||
"<test xmlns=\"http://www.example.org/schema\"><number>a</number><text>text</text></test>"));
|
||||
|
||||
RequestMatcher requestMatcher = WebServiceMock.validPayload(schema1);
|
||||
|
||||
replay(message);
|
||||
|
||||
requestMatcher.match(null, message);
|
||||
|
||||
verify(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleSchemaMatch() throws IOException, AssertionError {
|
||||
expect(message.getPayloadSource()).andReturn(new StringSource(
|
||||
"<test xmlns=\"http://www.example.org/schema\"><number>0</number><text>text</text></test>"));
|
||||
|
||||
RequestMatcher requestMatcher = WebServiceMock.validPayload(schema1, schema2);
|
||||
|
||||
replay(message);
|
||||
|
||||
requestMatcher.match(null, message);
|
||||
|
||||
verify(message);
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void multipleSchemaNotOk() throws IOException, AssertionError {
|
||||
expect(message.getPayloadSource()).andReturn(new StringSource(
|
||||
"<test xmlns=\"http://www.example.org/schema\"><number>a</number><text>text</text></test>"));
|
||||
|
||||
RequestMatcher requestMatcher = WebServiceMock.validPayload(schema1, schema2);
|
||||
|
||||
replay(message);
|
||||
|
||||
requestMatcher.match(null, message);
|
||||
|
||||
verify(message);
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void multipleSchemaDifferentOrderNotOk() throws IOException, AssertionError {
|
||||
expect(message.getPayloadSource()).andReturn(new StringSource(
|
||||
"<test xmlns=\"http://www.example.org/schema\"><number>a</number><text>text</text></test>"));
|
||||
|
||||
RequestMatcher requestMatcher = WebServiceMock.validPayload(schema2, schema1);
|
||||
|
||||
replay(message);
|
||||
|
||||
requestMatcher.match(null, message);
|
||||
|
||||
verify(message);
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void xmlValidatorNotOk() throws IOException, AssertionError {
|
||||
expect(message.getPayloadSource()).andReturn(new StringSource(
|
||||
"<test xmlns=\"http://www.example.org/schema\"><number>a</number><text>text</text></test>"));
|
||||
|
||||
XmlValidator validator = XmlValidatorFactory.createValidator(schema1, XmlValidatorFactory.SCHEMA_W3C_XML);
|
||||
RequestMatcher requestMatcher = new SchemaValidatingRequestMatcher(validator);
|
||||
|
||||
replay(message);
|
||||
|
||||
requestMatcher.match(null, message);
|
||||
|
||||
verify(message);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@ import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.client.core.WebServiceMessageCallback;
|
||||
import org.springframework.ws.client.core.WebServiceTemplate;
|
||||
@@ -154,7 +156,7 @@ public class WebServiceMockTest {
|
||||
template.sendSourceAndReceiveToResult(request, new StringResult());
|
||||
assertNull(MockWebServiceMessageSenderHolder.get());
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void unexpectedConnection() throws Exception {
|
||||
Source request = new StringSource("<request xmlns='http://example.com'/>");
|
||||
@@ -166,5 +168,28 @@ public class WebServiceMockTest {
|
||||
template.sendSourceAndReceiveToResult(request, new StringResult());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void xsdMatch() throws Exception {
|
||||
Resource schema = new ByteArrayResource(
|
||||
"<schema xmlns=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://example.com\" elementFormDefault=\"qualified\"><element name=\"request\"/></schema>".getBytes());
|
||||
|
||||
expect(validPayload(schema));
|
||||
|
||||
StringResult result = new StringResult();
|
||||
String actual = "<request xmlns='http://example.com'/>";
|
||||
template.sendSourceAndReceiveToResult(new StringSource(actual), result);
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void xsdNonMatch() throws Exception {
|
||||
Resource schema = new ByteArrayResource(
|
||||
"<schema xmlns=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://example.com\" elementFormDefault=\"qualified\"><element name=\"request\"/></schema>".getBytes());
|
||||
|
||||
expect(validPayload(schema));
|
||||
|
||||
StringResult result = new StringResult();
|
||||
String actual = "<request2 xmlns='http://example.com'/>";
|
||||
template.sendSourceAndReceiveToResult(new StringSource(actual), result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/schema" xmlns:tns="http://www.example.org/schema" elementFormDefault="qualified">
|
||||
|
||||
<element name="test" type="tns:testMessage"/>
|
||||
|
||||
<complexType name="testMessage">
|
||||
<sequence>
|
||||
<element name="number" type="int"/>
|
||||
<element name="text" type="string" minOccurs="0"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
</schema>
|
||||
Reference in New Issue
Block a user