INT-2475 Fix WS Gateway Result Payload

Fixed the return value of a non-SOAP message to return the extracted result as is, added tests

INT-2475 polishing based on PR comments

INT-2475 added POX tests for DomSource and Document as per PR suggestion
This commit is contained in:
Oleg Zhurakousky
2012-03-20 12:07:37 -04:00
committed by Gary Russell
parent 2eb3fa3783
commit 3ef9177248
3 changed files with 126 additions and 34 deletions

View File

@@ -237,7 +237,7 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
return siMessage;
}
else {
return message.getPayloadSource();
return resultObject;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-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.
@@ -16,16 +16,25 @@
package org.springframework.integration.ws.config;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.pox.dom.DomPoxMessage;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* @author Mark Fisher
@@ -40,7 +49,16 @@ public class StubMessageFactory implements WebServiceMessageFactory {
}
public WebServiceMessage createWebServiceMessage(InputStream inputStream) throws IOException {
return null;
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource( new InputStreamReader(inputStream));
Document document = builder.parse(is);
return new DomPoxMessage(document, transformer, "text/xml");
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-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.
@@ -16,6 +16,11 @@
package org.springframework.integration.ws.config;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
@@ -24,15 +29,14 @@ import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
@@ -49,17 +53,16 @@ import org.springframework.oxm.XmlMappingException;
import org.springframework.util.xml.DomUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.SoapMessageFactory;
import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.ws.transport.WebServiceMessageSender;
import org.springframework.xml.namespace.QNameUtils;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.springframework.xml.transform.StringResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* @author Oleg Zhurakousky
@@ -67,13 +70,16 @@ import static org.junit.Assert.assertNull;
*/
public class WebServiceOutboundGatewayWithHeaderMapperTests {
String responseMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> " +
String responseSoapMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> " +
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"> " +
"<SOAP-ENV:Header/>" +
"<SOAP-ENV:Body> " +
"<root><name>jane</name></root>" +
"</SOAP-ENV:Body> " +
"</SOAP-ENV:Envelope>";
String responseNonSoapMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> " +
"<person><name>oleg</name></person>";
@SuppressWarnings("unchecked")
@Test
@@ -96,7 +102,18 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
@Test
public void withHeaderMapperString() throws Exception{
String payload = "<root><name>bill</name></root>";
this.process(payload, "withHeaderMapper", "inputChannel");
Message<?> replyMessage = this.process(payload, "withHeaderMapper", "inputChannel", true);
assertTrue(replyMessage.getPayload() instanceof String);
assertEquals("bar", replyMessage.getHeaders().get("bar"));
assertNull(replyMessage.getHeaders().get("baz"));
}
@Test
public void withHeaderMapperStringPOX() throws Exception{
String payload = "<root><name>bill</name></root>";
Message<?> replyMessage = this.process(payload, "withHeaderMapper", "inputChannel", false);
assertTrue(replyMessage.getPayload() instanceof String);
assertTrue(((String)replyMessage.getPayload()).contains("<person><name>oleg</name></person>"));
}
@Test
@@ -105,7 +122,21 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document document = docBuilder.parse(new ByteArrayInputStream("<root><name>bill</name></root>".getBytes()));
DOMSource payload = new DOMSource(document);
this.process(payload, "withHeaderMapper", "inputChannel");
Message<?> replyMessage = this.process(payload, "withHeaderMapper", "inputChannel", true);
assertTrue(replyMessage.getPayload() instanceof DOMSource);
assertEquals("bar", replyMessage.getHeaders().get("bar"));
assertNull(replyMessage.getHeaders().get("baz"));
}
@Test
public void withHeaderMapperSourcePOX() throws Exception{
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document document = docBuilder.parse(new ByteArrayInputStream("<root><name>bill</name></root>".getBytes()));
DOMSource payload = new DOMSource(document);
Message<?> replyMessage = this.process(payload, "withHeaderMapper", "inputChannel", false);
assertTrue(replyMessage.getPayload() instanceof DOMSource);
assertTrue(this.extractStringResult(replyMessage).contains("<person><name>oleg</name></person>"));
}
@Test
@@ -113,21 +144,41 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document payload = docBuilder.parse(new ByteArrayInputStream("<root><name>bill</name></root>".getBytes()));
this.process(payload, "withHeaderMapper", "inputChannel");
Message<?> replyMessage = this.process(payload, "withHeaderMapper", "inputChannel", true);
assertTrue(replyMessage.getPayload() instanceof Document);
assertEquals("bar", replyMessage.getHeaders().get("bar"));
assertNull(replyMessage.getHeaders().get("baz"));
}
@Test
public void withHeaderMapperDocumentPOX() throws Exception{
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document payload = docBuilder.parse(new ByteArrayInputStream("<root><name>bill</name></root>".getBytes()));
Message<?> replyMessage = this.process(payload, "withHeaderMapper", "inputChannel", false);
assertTrue(replyMessage.getPayload() instanceof Document);
assertTrue(this.extractStringResult(replyMessage).contains("<person><name>oleg</name></person>"));
}
@Test
public void withHeaderMapperAndMarshaller() throws Exception{
Person person = new Person();
person.setName("Bill Clinton");
this.process(person, "marshallingWithHeaderMapper", "inputMarshallingChannel");
Message<?> replyMessage = this.process(person, "marshallingWithHeaderMapper", "inputMarshallingChannel", true);
assertEquals("bar", replyMessage.getHeaders().get("bar"));
assertNull(replyMessage.getHeaders().get("baz"));
}
@SuppressWarnings("rawtypes")
public void process(Object payload, String gatewayName, String channelName) throws Exception{
public Message<?> process(Object payload, String gatewayName, String channelName, final boolean soap) throws Exception{
ApplicationContext context = new ClassPathXmlApplicationContext("ws-outbound-gateway-with-headermappers.xml", this.getClass());
AbstractWebServiceOutboundGateway gateway = TestUtils.getPropertyValue(context.getBean(gatewayName), "handler", AbstractWebServiceOutboundGateway.class);
if (!soap){
WebServiceTemplate template = TestUtils.getPropertyValue(gateway, "webServiceTemplate", WebServiceTemplate.class);
template.setMessageFactory(new StubMessageFactory());
}
WebServiceMessageSender messageSender = Mockito.mock(WebServiceMessageSender.class);
WebServiceConnection wsConnection = Mockito.mock(WebServiceConnection.class);
Mockito.when(messageSender.createConnection(Mockito.any(URI.class))).thenReturn(wsConnection);
@@ -136,7 +187,7 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
Mockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
SoapMessage soapMessage = (SoapMessage) args[0];
WebServiceMessage wsMessage = (WebServiceMessage) args[0];
// try { // uncomment if you want to see a pretty-print of SOAP message
// Transformer transformer = TransformerFactory.newInstance().newTransformer();
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
@@ -144,11 +195,14 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
// } catch (Exception e) {
// // ignore
// }
SoapHeader soapHeader = soapMessage.getSoapHeader();
assertNotNull(soapHeader.getAttributeValue(QNameUtils.parseQNameString("foo")));
assertNotNull(soapHeader.getAttributeValue(QNameUtils.parseQNameString("foobar")));
assertNotNull(soapHeader.getAttributeValue(QNameUtils.parseQNameString("abaz")));
assertNull(soapHeader.getAttributeValue(QNameUtils.parseQNameString("bar")));
if (soap){
SoapHeader soapHeader = ((SoapMessage)wsMessage).getSoapHeader();
assertNotNull(soapHeader.getAttributeValue(QNameUtils.parseQNameString("foo")));
assertNotNull(soapHeader.getAttributeValue(QNameUtils.parseQNameString("foobar")));
assertNotNull(soapHeader.getAttributeValue(QNameUtils.parseQNameString("abaz")));
assertNull(soapHeader.getAttributeValue(QNameUtils.parseQNameString("bar")));
}
return null;
}})
.when(wsConnection).send(Mockito.any(WebServiceMessage.class));
@@ -156,10 +210,15 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
Mockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) throws Exception{
Object[] args = invocation.getArguments();
SoapMessageFactory factory = (SoapMessageFactory) args[0];
SoapMessage soapMessage = factory.createWebServiceMessage(new ByteArrayInputStream(responseMessage.getBytes()));
soapMessage.getSoapHeader().addAttribute(QNameUtils.parseQNameString("bar"), "bar");
soapMessage.getSoapHeader().addAttribute(QNameUtils.parseQNameString("baz"), "baz");
WebServiceMessageFactory factory = (WebServiceMessageFactory) args[0];
String responseMessage = factory instanceof SoapMessageFactory ? responseSoapMessage : responseNonSoapMessage;
WebServiceMessage wsMessage = factory.createWebServiceMessage(new ByteArrayInputStream(responseMessage.getBytes()));
if (soap){
((SoapMessage)wsMessage).getSoapHeader().addAttribute(QNameUtils.parseQNameString("bar"), "bar");
((SoapMessage)wsMessage).getSoapHeader().addAttribute(QNameUtils.parseQNameString("baz"), "baz");
}
// try { // uncomment if you want to see a pretty-print of SOAP message
// Transformer transformer = TransformerFactory.newInstance().newTransformer();
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
@@ -167,7 +226,7 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
// } catch (Exception e) {
// // ignore
// }
return soapMessage;
return wsMessage;
}})
.when(wsConnection).receive(Mockito.any(WebServiceMessageFactory.class));
@@ -181,8 +240,7 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
inputChannel.send(message);
QueueChannel outputChannel = context.getBean("outputChannel", QueueChannel.class);
Message<?> replyMessage = outputChannel.receive(0);
assertEquals("bar", replyMessage.getHeaders().get("bar"));
assertNull(replyMessage.getHeaders().get("baz"));
return replyMessage;
}
public static class Person{
@@ -212,4 +270,20 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests {
return person;
}
}
private String extractStringResult(Message<?> replyMessage) throws Exception{
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StringResult result = new StringResult();
Object payload = replyMessage.getPayload();
if (payload instanceof DOMSource){
transformer.transform(((DOMSource)replyMessage.getPayload()), result);
}
else if (payload instanceof Document){
transformer.transform(new DOMSource((Document)replyMessage.getPayload()), result);
}
else {
throw new IllegalArgumentException("Unsupported payload type: " + payload.getClass().getName());
}
return result.toString();
}
}