1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.transport.http;
18
19 import java.io.IOException;
20 import java.io.OutputStream;
21 import java.net.URI;
22 import java.net.URISyntaxException;
23 import java.util.zip.GZIPOutputStream;
24 import javax.servlet.Servlet;
25 import javax.servlet.ServletException;
26 import javax.servlet.http.HttpServlet;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29 import javax.xml.soap.MessageFactory;
30 import javax.xml.soap.MimeHeaders;
31 import javax.xml.soap.SOAPConstants;
32 import javax.xml.soap.SOAPException;
33 import javax.xml.soap.SOAPMessage;
34 import javax.xml.transform.Transformer;
35 import javax.xml.transform.TransformerException;
36 import javax.xml.transform.TransformerFactory;
37 import javax.xml.transform.dom.DOMResult;
38
39 import org.springframework.beans.factory.InitializingBean;
40 import org.springframework.util.FileCopyUtils;
41 import org.springframework.ws.WebServiceMessage;
42 import org.springframework.ws.WebServiceMessageFactory;
43 import org.springframework.ws.soap.saaj.SaajSoapMessage;
44 import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
45 import org.springframework.ws.transport.FaultAwareWebServiceConnection;
46 import org.springframework.ws.transport.WebServiceConnection;
47 import org.springframework.ws.transport.support.FreePortScanner;
48 import org.springframework.xml.transform.StringResult;
49 import org.springframework.xml.transform.StringSource;
50
51 import org.custommonkey.xmlunit.XMLUnit;
52 import org.junit.After;
53 import org.junit.Assert;
54 import org.junit.Before;
55 import org.junit.Test;
56 import org.mortbay.jetty.Server;
57 import org.mortbay.jetty.servlet.Context;
58 import org.mortbay.jetty.servlet.ServletHolder;
59
60 import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
61 import static org.junit.Assert.assertEquals;
62
63 public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase {
64
65 private Server jettyServer;
66
67 private static final String REQUEST_HEADER_NAME = "RequestHeader";
68
69 private static final String REQUEST_HEADER_VALUE = "RequestHeaderValue";
70
71 private static final String RESPONSE_HEADER_NAME = "ResponseHeader";
72
73 private static final String RESPONSE_HEADER_VALUE = "ResponseHeaderValue";
74
75 private static final String REQUEST = "<Request xmlns='http://springframework.org/spring-ws/' />";
76
77 private static final String SOAP_REQUEST =
78 "<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'><SOAP-ENV:Header/><SOAP-ENV:Body>" +
79 REQUEST + "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
80
81 private static final String RESPONSE = "<Response xmlns='http://springframework.org/spring-ws/' />";
82
83 private static final String SOAP_RESPONSE =
84 "<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'><SOAP-ENV:Header/><SOAP-ENV:Body>" +
85 RESPONSE + "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
86
87 private AbstractHttpWebServiceMessageSender messageSender;
88
89 private Context jettyContext;
90
91 private MessageFactory saajMessageFactory;
92
93 private TransformerFactory transformerFactory;
94
95 private WebServiceMessageFactory messageFactory;
96
97 private URI connectionUri;
98
99 @Before
100 public final void setUp() throws Exception {
101 int port = FreePortScanner.getFreePort();
102 connectionUri = new URI("http", null, "localhost", port, null, null, null);
103 jettyServer = new Server(port);
104 jettyContext = new Context(jettyServer, "/");
105 messageSender = createMessageSender();
106 if (messageSender instanceof InitializingBean) {
107 ((InitializingBean) messageSender).afterPropertiesSet();
108 }
109 XMLUnit.setIgnoreWhitespace(true);
110 saajMessageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
111 messageFactory = new SaajSoapMessageFactory(saajMessageFactory);
112 transformerFactory = TransformerFactory.newInstance();
113 }
114
115 protected abstract AbstractHttpWebServiceMessageSender createMessageSender();
116
117 @After
118 public final void tearDown() throws Exception {
119 if (jettyServer.isRunning()) {
120 jettyServer.stop();
121 }
122 }
123
124 @Test
125 public void testSupports() throws URISyntaxException {
126 Assert.assertTrue("Message sender does not support HTTP url", messageSender.supports(connectionUri));
127 }
128
129 @Test
130 public void testSendAndReceiveResponse() throws Exception {
131 MyServlet servlet = new MyServlet();
132 servlet.setResponse(true);
133 validateResponse(servlet);
134 }
135
136 @Test
137 public void testSendAndReceiveNoResponse() throws Exception {
138 validateNonResponse(new MyServlet());
139 }
140
141 @Test
142 public void testSendAndReceiveNoResponseAccepted() throws Exception {
143 MyServlet servlet = new MyServlet();
144 servlet.setResponseStatus(HttpServletResponse.SC_ACCEPTED);
145 validateNonResponse(servlet);
146 }
147
148 @Test
149 public void testSendAndReceiveCompressed() throws Exception {
150 MyServlet servlet = new MyServlet();
151 servlet.setResponse(true);
152 servlet.setGzip(true);
153 validateResponse(servlet);
154 }
155
156 @Test
157 public void testSendAndReceiveInvalidContentSize() throws Exception {
158 MyServlet servlet = new MyServlet();
159 servlet.setResponse(true);
160 servlet.setContentLength(-1);
161 validateResponse(servlet);
162 }
163
164 @Test
165 public void testSendAndReceiveCompressedInvalidContentSize() throws Exception {
166 MyServlet servlet = new MyServlet();
167 servlet.setResponse(true);
168 servlet.setGzip(true);
169 servlet.setContentLength(-1);
170 validateResponse(servlet);
171 }
172
173 @Test
174 public void testSendAndReceiveFault() throws Exception {
175 MyServlet servlet = new MyServlet();
176 servlet.setResponseStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
177 servlet.setResponse(true);
178 jettyContext.addServlet(new ServletHolder(servlet), "/");
179 jettyServer.start();
180 FaultAwareWebServiceConnection connection =
181 (FaultAwareWebServiceConnection) messageSender.createConnection(connectionUri);
182 SOAPMessage request = createRequest();
183 try {
184 connection.send(new SaajSoapMessage(request));
185 connection.receive(messageFactory);
186 Assert.assertTrue("Response has no fault", connection.hasFault());
187 }
188 finally {
189 connection.close();
190 }
191 }
192
193 private void validateResponse(Servlet servlet) throws Exception {
194 jettyContext.addServlet(new ServletHolder(servlet), "/");
195 jettyServer.start();
196 FaultAwareWebServiceConnection connection =
197 (FaultAwareWebServiceConnection) messageSender.createConnection(connectionUri);
198 SOAPMessage request = createRequest();
199 try {
200 connection.send(new SaajSoapMessage(request));
201 SaajSoapMessage response = (SaajSoapMessage) connection.receive(messageFactory);
202 Assert.assertNotNull("No response", response);
203 Assert.assertFalse("Response has fault", connection.hasFault());
204 SOAPMessage saajResponse = response.getSaajMessage();
205 String[] headerValues = saajResponse.getMimeHeaders().getHeader(RESPONSE_HEADER_NAME);
206 Assert.assertNotNull("Response has no header", headerValues);
207 Assert.assertEquals("Response has invalid header", 1, headerValues.length);
208 Assert.assertEquals("Response has invalid header values", RESPONSE_HEADER_VALUE, headerValues[0]);
209 StringResult result = new StringResult();
210 Transformer transformer = transformerFactory.newTransformer();
211 transformer.transform(response.getPayloadSource(), result);
212 assertXMLEqual("Invalid response", RESPONSE, result.toString());
213 }
214 finally {
215 connection.close();
216 }
217 }
218
219 private void validateNonResponse(Servlet servlet) throws Exception {
220 jettyContext.addServlet(new ServletHolder(servlet), "/");
221 jettyServer.start();
222
223 WebServiceConnection connection = messageSender.createConnection(connectionUri);
224 SOAPMessage request = createRequest();
225 try {
226 connection.send(new SaajSoapMessage(request));
227 WebServiceMessage response = connection.receive(messageFactory);
228 Assert.assertNull("Response", response);
229 }
230 finally {
231 connection.close();
232 }
233 }
234
235 private SOAPMessage createRequest() throws TransformerException, SOAPException {
236 SOAPMessage request = saajMessageFactory.createMessage();
237 MimeHeaders mimeHeaders = request.getMimeHeaders();
238 mimeHeaders.addHeader(REQUEST_HEADER_NAME, REQUEST_HEADER_VALUE);
239 Transformer transformer = transformerFactory.newTransformer();
240 transformer.transform(new StringSource(REQUEST), new DOMResult(request.getSOAPBody()));
241 return request;
242 }
243
244 private class MyServlet extends HttpServlet {
245
246 private int responseStatus = HttpServletResponse.SC_OK;
247
248 private Integer contentLength;
249
250 private boolean response;
251
252 private boolean gzip;
253
254 public void setResponseStatus(int responseStatus) {
255 this.responseStatus = responseStatus;
256 }
257
258 public void setContentLength(int contentLength) {
259 this.contentLength = contentLength;
260 }
261
262 public void setResponse(boolean response) {
263 this.response = response;
264 }
265
266 public void setGzip(boolean gzip) {
267 this.gzip = gzip;
268 }
269
270 @Override
271 protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
272 throws ServletException, IOException {
273 try {
274 assertEquals("Invalid header value received on server side", REQUEST_HEADER_VALUE,
275 httpServletRequest.getHeader(REQUEST_HEADER_NAME));
276 String receivedRequest =
277 new String(FileCopyUtils.copyToByteArray(httpServletRequest.getInputStream()), "UTF-8");
278 assertXMLEqual("Invalid request received", SOAP_REQUEST, receivedRequest);
279 if (gzip) {
280 assertEquals("Invalid Accept-Encoding header value received on server side", "gzip",
281 httpServletRequest.getHeader("Accept-Encoding"));
282 }
283
284 httpServletResponse.setStatus(responseStatus);
285 if (response) {
286 httpServletResponse.setContentType("text/xml");
287 if (contentLength != null) {
288 httpServletResponse.setContentLength(contentLength);
289 }
290 if (gzip) {
291 httpServletResponse.addHeader("Content-Encoding", "gzip");
292 }
293 httpServletResponse.setHeader(RESPONSE_HEADER_NAME, RESPONSE_HEADER_VALUE);
294 OutputStream os;
295 if (gzip) {
296 os = new GZIPOutputStream(httpServletResponse.getOutputStream());
297 }
298 else {
299 os = httpServletResponse.getOutputStream();
300 }
301 FileCopyUtils.copy(SOAP_RESPONSE.getBytes("UTF-8"), os);
302 }
303 }
304 catch (Exception ex) {
305 throw new ServletException(ex);
306 }
307 }
308 }
309
310 }