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