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