SWS-786 - SOAP envelope Matcher / MessageCreator

This commit is contained in:
Arjen Poutsma
2012-08-14 09:40:18 +00:00
parent 690eebcf58
commit 71e81b0650
9 changed files with 383 additions and 17 deletions

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 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
* 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,
@@ -85,10 +85,9 @@ public interface SoapMessage extends MimeMessage, FaultAwareWebServiceMessage {
Document getDocument();
/**
* Returns this message as a {@link Document}.
* Sets the contents of the message to the given {@link Document}.
*
* Depending on the underlying implementation, this Document may be 'live' or not.
* @return this soap message as a DOM document
* @param document the soap message as a DOM document
*/
void setDocument(Document document);

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 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
* 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,
@@ -27,6 +27,7 @@ import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.test.support.matcher.PayloadDiffMatcher;
import org.springframework.ws.test.support.matcher.SchemaValidatingMatcher;
import org.springframework.ws.test.support.matcher.SoapEnvelopeDiffMatcher;
import org.springframework.ws.test.support.matcher.SoapHeaderMatcher;
import org.springframework.xml.transform.ResourceSource;
@@ -54,6 +55,8 @@ public abstract class RequestMatchers {
};
}
// Payload
/**
* Expects the given {@link javax.xml.transform.Source} XML payload.
*
@@ -108,6 +111,32 @@ public abstract class RequestMatchers {
return new XPathExpectationsHelperAdapter(xpathExpression, namespaceMapping);
}
// SOAP
/**
* Expects the given {@link javax.xml.transform.Source} XML SOAP envelope.
*
* @param soapEnvelope the XML SOAP envelope
* @return the request matcher
* @since 2.1.1
*/
public static RequestMatcher soapEnvelope(Source soapEnvelope) {
Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null");
return new WebServiceMessageMatcherAdapter(new SoapEnvelopeDiffMatcher(soapEnvelope));
}
/**
* Expects the given {@link org.springframework.core.io.Resource} XML SOAP envelope.
*
* @param soapEnvelope the XML SOAP envelope
* @return the request matcher
* @since 2.1.1
*/
public static RequestMatcher soapEnvelope(Resource soapEnvelope) throws IOException {
Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null");
return soapEnvelope(new ResourceSource(soapEnvelope));
}
/**
* Expects the given SOAP header in the outgoing message.
*
@@ -119,6 +148,8 @@ public abstract class RequestMatchers {
return new WebServiceMessageMatcherAdapter(new SoapHeaderMatcher(soapHeaderName));
}
// Other
/**
* Expects a connection to the given URI.
*

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 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
* 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,
@@ -27,6 +27,7 @@ import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.soap.SoapBody;
import org.springframework.ws.test.support.creator.PayloadMessageCreator;
import org.springframework.ws.test.support.creator.SoapEnvelopeMessageCreator;
import org.springframework.ws.test.support.creator.WebServiceMessageCreator;
import org.springframework.xml.transform.ResourceSource;
@@ -42,6 +43,8 @@ public abstract class ResponseCreators {
private ResponseCreators() {
}
// Payload
/**
* Respond with the given {@link javax.xml.transform.Source} XML as payload response.
*
@@ -64,6 +67,8 @@ public abstract class ResponseCreators {
return withPayload(new ResourceSource(payload));
}
// Error/Exception
/**
* Respond with an error.
*
@@ -99,6 +104,33 @@ public abstract class ResponseCreators {
return new ExceptionResponseCreator(ex);
}
// SOAP
/**
* Respond with the given {@link javax.xml.transform.Source} XML as SOAP envelope response.
*
* @param soapEnvelope the response SOAP envelope
* @return the response callback
* @since 2.1.1
*/
public static ResponseCreator withSoapEnvelope(Source soapEnvelope) {
Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null");
return new WebServiceMessageCreatorAdapter(new SoapEnvelopeMessageCreator(soapEnvelope));
}
/**
* Respond with the given {@link org.springframework.core.io.Resource} XML as SOAP envelope response.
*
* @param soapEnvelope the response SOAP envelope
* @return the response callback
* @since 2.1.1
*/
public static ResponseCreator withSoapEnvelope(Resource soapEnvelope) throws IOException {
Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null");
return withSoapEnvelope(new ResourceSource(soapEnvelope));
}
/**
* Respond with a {@code MustUnderstand} fault.
*

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 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
* 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,
@@ -24,6 +24,7 @@ import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.test.support.creator.PayloadMessageCreator;
import org.springframework.ws.test.support.creator.SoapEnvelopeMessageCreator;
import org.springframework.ws.test.support.creator.WebServiceMessageCreator;
import org.springframework.xml.transform.ResourceSource;
@@ -39,6 +40,8 @@ public abstract class RequestCreators {
private RequestCreators() {
}
// Payload
/**
* Create a request with the given {@link Source} XML as payload.
*
@@ -61,6 +64,32 @@ public abstract class RequestCreators {
return withPayload(new ResourceSource(payload));
}
// SOAP
/**
* Create a request with the given {@link Source} XML as SOAP envelope.
*
* @param soapEnvelope the request SOAP envelope
* @return the request creator
* @since 2.1.1
*/
public static RequestCreator withSoapEnvelope(Source soapEnvelope) {
Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null");
return new WebServiceMessageCreatorAdapter(new SoapEnvelopeMessageCreator(soapEnvelope));
}
/**
* Create a request with the given {@link Resource} XML as SOAP envelope.
*
* @param soapEnvelope the request SOAP envelope
* @return the request creator
* @since 2.1.1
*/
public static RequestCreator withSoapEnvelope(Resource soapEnvelope) throws IOException {
Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null");
return withSoapEnvelope(new ResourceSource(soapEnvelope));
}
/**
* Adapts a {@link WebServiceMessageCreator} to the {@link RequestCreator} contract.
*/

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 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
* 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,
@@ -29,6 +29,7 @@ import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.soap.SoapVersion;
import org.springframework.ws.test.support.matcher.PayloadDiffMatcher;
import org.springframework.ws.test.support.matcher.SchemaValidatingMatcher;
import org.springframework.ws.test.support.matcher.SoapEnvelopeDiffMatcher;
import org.springframework.ws.test.support.matcher.SoapHeaderMatcher;
import org.springframework.xml.transform.ResourceSource;
@@ -45,7 +46,7 @@ public abstract class ResponseMatchers {
private ResponseMatchers() {
}
// Payload
/**
@@ -100,9 +101,30 @@ public abstract class ResponseMatchers {
return new XPathExpectationsHelperAdapter(xpathExpression, namespaceMapping);
}
// SOAP
/**
* Expects the given {@link Source} XML SOAP envelope.
*
* @param soapEnvelope the XML SOAP envelope
* @return the response matcher
* @since 2.1.1
*/
public static ResponseMatcher soapEnvelope(Source soapEnvelope) {
return new WebServiceMessageMatcherAdapter(new SoapEnvelopeDiffMatcher(soapEnvelope));
}
/**
* Expects the given {@link Resource} XML SOAP envelope.
*
* @param soapEnvelope the XML SOAP envelope
* @return the response matcher
* @since 2.1.1
*/
public static ResponseMatcher soapEnvelope(Resource soapEnvelope) throws IOException {
return soapEnvelope(new ResourceSource(soapEnvelope));
}
/**
* Expects the given SOAP header in the outgoing message.
*

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2005-2012 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.test.support.creator;
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.xml.transform.TransformerHelper;
import org.w3c.dom.Document;
import static org.springframework.ws.test.support.AssertionErrors.assertTrue;
import static org.springframework.ws.test.support.AssertionErrors.fail;
/**
* Implementation of {@link WebServiceMessageCreator} that creates a request based on a SOAP envelope {@link Source}.
*
* @author Alexander Shutyaev
* @since 2.1.1
*/
public class SoapEnvelopeMessageCreator extends AbstractMessageCreator {
private final Source soapEnvelope;
private final TransformerHelper transformerHelper = new TransformerHelper();
/**
* Creates a new instance of the {@code SoapEnvelopeMessageCreator} with the given SOAP envelope source.
*
* @param soapEnvelope the SOAP envelope source
*/
public SoapEnvelopeMessageCreator(Source soapEnvelope) {
Assert.notNull(soapEnvelope, "'soapEnvelope' must not be null");
this.soapEnvelope = soapEnvelope;
}
@Override
protected void doWithMessage(WebServiceMessage message) throws IOException {
assertTrue("Message created with factory is not a SOAP message", message instanceof SoapMessage);
SoapMessage soapMessage = (SoapMessage) message;
try {
DOMResult result = new DOMResult();
transformerHelper.transform(soapEnvelope, result);
soapMessage.setDocument((Document) result.getNode());
}
catch (TransformerException ex) {
fail("Could not transform request SOAP envelope to message: " + ex.getMessage());
}
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2005-2012 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.test.support.matcher;
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import org.springframework.util.Assert;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.xml.transform.TransformerHelper;
import org.custommonkey.xmlunit.Diff;
import org.w3c.dom.Document;
import static org.springframework.ws.test.support.AssertionErrors.assertTrue;
import static org.springframework.ws.test.support.AssertionErrors.fail;
/**
* Matches {@link Source} SOAP envelopes.
*
* @author Alexander Shutyaev
* @since 2.1.1
*/
public class SoapEnvelopeDiffMatcher extends AbstractSoapMessageMatcher {
private final Source expected;
private final TransformerHelper transformerHelper = new TransformerHelper();
public SoapEnvelopeDiffMatcher(Source expected) {
Assert.notNull(expected, "'expected' must not be null");
this.expected = expected;
}
@Override
protected void match(SoapMessage soapMessage) throws IOException, AssertionError {
Document actualDocument = soapMessage.getDocument();
Document expectedDocument = createDocumentFromSource(expected);
Diff diff = new Diff(expectedDocument, actualDocument);
assertTrue("Envelopes are different, " + diff.toString(), diff.similar());
}
private Document createDocumentFromSource(Source source) {
try {
DOMResult result = new DOMResult();
transformerHelper.transform(source, result);
return (Document) result.getNode();
}
catch (TransformerException ex) {
fail("Could not transform source to DOMResult" + ex.getMessage());
return null;
}
}
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 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
* 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,
@@ -21,6 +21,7 @@ import java.util.Locale;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.ws.WebServiceMessage;
@@ -71,6 +72,34 @@ public class ResponseCreatorsTest {
assertXMLEqual(payload, getPayloadAsString(response));
}
@Test
public void withSoapEnvelopeSource() throws Exception {
StringBuilder xmlBuilder = new StringBuilder();
xmlBuilder.append("<?xml version='1.0'?>");
xmlBuilder.append("<soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope'>");
xmlBuilder.append("<soap:Header><header xmlns='http://springframework.org'/></soap:Header>");
xmlBuilder.append("<soap:Body><payload xmlns='http://springframework.org'/></soap:Body>");
xmlBuilder.append("</soap:Envelope>");
String envelope = xmlBuilder.toString();
ResponseCreator responseCreator = ResponseCreators.withSoapEnvelope(new StringSource(envelope));
WebServiceMessage response = responseCreator.createResponse(null, null, messageFactory);
assertXMLEqual(envelope, getSoapEnvelopeAsString((SoapMessage)response));
}
@Test
public void withSoapEnvelopeResource() throws Exception {
StringBuilder xmlBuilder = new StringBuilder();
xmlBuilder.append("<?xml version='1.0'?>");
xmlBuilder.append("<soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope'>");
xmlBuilder.append("<soap:Header><header xmlns='http://springframework.org'/></soap:Header>");
xmlBuilder.append("<soap:Body><payload xmlns='http://springframework.org'/></soap:Body>");
xmlBuilder.append("</soap:Envelope>");
String envelope = xmlBuilder.toString();
ResponseCreator responseCreator = ResponseCreators.withSoapEnvelope(new ByteArrayResource(envelope.getBytes("UTF-8")));
WebServiceMessage response = responseCreator.createResponse(null, null, messageFactory);
assertXMLEqual(envelope, getSoapEnvelopeAsString((SoapMessage)response));
}
@Test
public void withIOException() throws Exception {
@@ -145,4 +174,11 @@ public class ResponseCreatorsTest {
transformerHelper.transform(message.getPayloadSource(), result);
return result.toString();
}
private String getSoapEnvelopeAsString(SoapMessage message) throws TransformerException {
DOMSource source = new DOMSource(message.getDocument());
Result result = new StringResult();
transformerHelper.transform(source, result);
return result.toString();
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2005-2012 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.test.support.matcher;
import javax.xml.transform.dom.DOMResult;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.xml.transform.StringSource;
import org.springframework.xml.transform.TransformerHelper;
import org.junit.Test;
import org.w3c.dom.Document;
import static org.easymock.EasyMock.*;
public class SoapEnvelopeDiffMatcherTest {
@Test
public void match() throws Exception {
StringBuilder xmlBuilder = new StringBuilder();
xmlBuilder.append("<?xml version='1.0'?>");
xmlBuilder.append("<soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope'>");
xmlBuilder.append("<soap:Header><header xmlns='http://example.com'/></soap:Header>");
xmlBuilder.append("<soap:Body><payload xmlns='http://example.com'/></soap:Body>");
xmlBuilder.append("</soap:Envelope>");
String xml = xmlBuilder.toString();
DOMResult result = new DOMResult();
TransformerHelper transformerHelper = new TransformerHelper();
transformerHelper.transform(new StringSource(xml), result);
SoapMessage message = createMock(SoapMessage.class);
expect(message.getDocument()).andReturn((Document)result.getNode()).once();
replay(message);
SoapEnvelopeDiffMatcher matcher = new SoapEnvelopeDiffMatcher(new StringSource(xml));
matcher.match(message);
verify(message);
}
@Test(expected = AssertionError.class)
public void nonMatch() throws Exception {
StringBuilder xmlBuilder = new StringBuilder();
xmlBuilder.append("<?xml version='1.0'?>");
xmlBuilder.append("<soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope'>");
xmlBuilder.append("<soap:Header><header xmlns='http://example.com'/></soap:Header>");
xmlBuilder.append("<soap:Body><payload%s xmlns='http://example.com'/></soap:Body>");
xmlBuilder.append("</soap:Envelope>");
String xml = xmlBuilder.toString();
String actual = String.format(xml, "1");
DOMResult result = new DOMResult();
TransformerHelper transformerHelper = new TransformerHelper();
transformerHelper.transform(new StringSource(actual), result);
SoapMessage message = createMock(SoapMessage.class);
expect(message.getDocument()).andReturn((Document)result.getNode()).once();
replay(message);
String expected = String.format(xml, "2");
SoapEnvelopeDiffMatcher matcher = new SoapEnvelopeDiffMatcher(new StringSource(expected));
matcher.match(message);
}
}