001: /*
002: * Copyright 2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.ws.transport.http;
018:
019: import java.io.IOException;
020: import java.io.OutputStream;
021: import java.util.zip.GZIPOutputStream;
022: import javax.servlet.Servlet;
023: import javax.servlet.ServletException;
024: import javax.servlet.http.HttpServlet;
025: import javax.servlet.http.HttpServletRequest;
026: import javax.servlet.http.HttpServletResponse;
027: import javax.xml.soap.MessageFactory;
028: import javax.xml.soap.MimeHeaders;
029: import javax.xml.soap.SOAPConstants;
030: import javax.xml.soap.SOAPException;
031: import javax.xml.soap.SOAPMessage;
032: import javax.xml.transform.Transformer;
033: import javax.xml.transform.TransformerException;
034: import javax.xml.transform.TransformerFactory;
035: import javax.xml.transform.dom.DOMResult;
036:
037: import org.custommonkey.xmlunit.XMLTestCase;
038: import org.custommonkey.xmlunit.XMLUnit;
039: import org.mortbay.jetty.Server;
040: import org.mortbay.jetty.servlet.Context;
041: import org.mortbay.jetty.servlet.ServletHolder;
042: import org.springframework.util.FileCopyUtils;
043: import org.springframework.ws.WebServiceMessage;
044: import org.springframework.ws.WebServiceMessageFactory;
045: import org.springframework.ws.soap.saaj.SaajSoapMessage;
046: import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
047: import org.springframework.ws.transport.FaultAwareWebServiceConnection;
048: import org.springframework.ws.transport.WebServiceConnection;
049: import org.springframework.xml.transform.StringResult;
050: import org.springframework.xml.transform.StringSource;
051:
052: public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase
053: extends XMLTestCase {
054:
055: private Server jettyServer;
056:
057: private static final String REQUEST_HEADER_NAME = "RequestHeader";
058:
059: private static final String REQUEST_HEADER_VALUE = "RequestHeaderValue";
060:
061: private static final String RESPONSE_HEADER_NAME = "ResponseHeader";
062:
063: private static final String RESPONSE_HEADER_VALUE = "ResponseHeaderValue";
064:
065: private static final String REQUEST = "<Request xmlns='http://springframework.org/spring-ws/' />";
066:
067: private static final String SOAP_REQUEST = "<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'><SOAP-ENV:Header/><SOAP-ENV:Body>"
068: + REQUEST + "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
069:
070: private static final String RESPONSE = "<Response xmlns='http://springframework.org/spring-ws/' />";
071:
072: private static final String SOAP_RESPONSE = "<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'><SOAP-ENV:Header/><SOAP-ENV:Body>"
073: + RESPONSE + "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
074:
075: private AbstractHttpWebServiceMessageSender messageSender;
076:
077: private Context jettyContext;
078:
079: private static final String URI = "http://localhost:8888/";
080:
081: private MessageFactory saajMessageFactory;
082:
083: private TransformerFactory transformerFactory;
084:
085: private WebServiceMessageFactory messageFactory;
086:
087: protected final void setUp() throws Exception {
088: jettyServer = new Server(8888);
089: jettyContext = new Context(jettyServer, "/");
090: messageSender = createMessageSender();
091: XMLUnit.setIgnoreWhitespace(true);
092: saajMessageFactory = MessageFactory
093: .newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
094: messageFactory = new SaajSoapMessageFactory(saajMessageFactory);
095: transformerFactory = TransformerFactory.newInstance();
096: }
097:
098: protected abstract AbstractHttpWebServiceMessageSender createMessageSender();
099:
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 testSendAndReceiveFault() throws Exception {
137: MyServlet servlet = new MyServlet();
138: servlet
139: .setResponseStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
140: jettyContext.addServlet(new ServletHolder(servlet), "/");
141: jettyServer.start();
142: FaultAwareWebServiceConnection connection = (FaultAwareWebServiceConnection) messageSender
143: .createConnection(URI);
144: SOAPMessage request = createRequest();
145: try {
146: connection.send(new SaajSoapMessage(request));
147: connection.receive(messageFactory);
148: assertTrue("Response has no fault", connection.hasFault());
149: } finally {
150: connection.close();
151: }
152: }
153:
154: private void validateResponse(Servlet servlet) throws Exception {
155: jettyContext.addServlet(new ServletHolder(servlet), "/");
156: jettyServer.start();
157: FaultAwareWebServiceConnection connection = (FaultAwareWebServiceConnection) messageSender
158: .createConnection(URI);
159: SOAPMessage request = createRequest();
160: try {
161: connection.send(new SaajSoapMessage(request));
162: SaajSoapMessage response = (SaajSoapMessage) connection
163: .receive(messageFactory);
164: assertNotNull("No response", response);
165: assertFalse("Response has fault", connection.hasFault());
166: SOAPMessage saajResponse = response.getSaajMessage();
167: String[] headerValues = saajResponse.getMimeHeaders()
168: .getHeader(RESPONSE_HEADER_NAME);
169: assertNotNull("Response has no header", headerValues);
170: assertEquals("Response has invalid header", 1,
171: headerValues.length);
172: assertEquals("Response has invalid header values",
173: RESPONSE_HEADER_VALUE, headerValues[0]);
174: StringResult result = new StringResult();
175: Transformer transformer = transformerFactory
176: .newTransformer();
177: transformer.transform(response.getPayloadSource(), result);
178: assertXMLEqual("Invalid response", RESPONSE, result
179: .toString());
180: } finally {
181: connection.close();
182: }
183: }
184:
185: private void validateNonResponse(Servlet servlet) throws Exception {
186: jettyContext.addServlet(new ServletHolder(servlet), "/");
187: jettyServer.start();
188:
189: WebServiceConnection connection = messageSender
190: .createConnection(URI);
191: SOAPMessage request = createRequest();
192: try {
193: connection.send(new SaajSoapMessage(request));
194: WebServiceMessage response = connection
195: .receive(messageFactory);
196: assertNull("Response", response);
197: } finally {
198: connection.close();
199: }
200: }
201:
202: private SOAPMessage createRequest() throws TransformerException,
203: SOAPException {
204: SOAPMessage request = saajMessageFactory.createMessage();
205: MimeHeaders mimeHeaders = request.getMimeHeaders();
206: mimeHeaders
207: .addHeader(REQUEST_HEADER_NAME, REQUEST_HEADER_VALUE);
208: Transformer transformer = transformerFactory.newTransformer();
209: transformer.transform(new StringSource(REQUEST), new DOMResult(
210: request.getSOAPBody()));
211: return request;
212: }
213:
214: private class MyServlet extends HttpServlet {
215:
216: private int responseStatus = HttpServletResponse.SC_OK;
217:
218: private Integer contentLength;
219:
220: private boolean response;
221:
222: private boolean gzip;
223:
224: public void setResponseStatus(int responseStatus) {
225: this .responseStatus = responseStatus;
226: }
227:
228: public void setContentLength(int contentLength) {
229: this .contentLength = new Integer(contentLength);
230: }
231:
232: public void setResponse(boolean response) {
233: this .response = response;
234: }
235:
236: public void setGzip(boolean gzip) {
237: this .gzip = gzip;
238: }
239:
240: protected void doPost(HttpServletRequest httpServletRequest,
241: HttpServletResponse httpServletResponse)
242: throws ServletException, IOException {
243: try {
244: assertEquals(
245: "Invalid header value received on server side",
246: REQUEST_HEADER_VALUE, httpServletRequest
247: .getHeader(REQUEST_HEADER_NAME));
248: String receivedRequest = new String(FileCopyUtils
249: .copyToByteArray(httpServletRequest
250: .getInputStream()), "UTF-8");
251: assertXMLEqual("Invalid request received",
252: SOAP_REQUEST, receivedRequest);
253: if (gzip) {
254: assertEquals(
255: "Invalid Accept-Encoding header value received on server side",
256: "gzip", httpServletRequest
257: .getHeader("Accept-Encoding"));
258: }
259:
260: httpServletResponse.setStatus(responseStatus);
261: if (response) {
262: httpServletResponse.setContentType("text/xml");
263: if (contentLength != null) {
264: httpServletResponse
265: .setContentLength(contentLength
266: .intValue());
267: }
268: if (gzip) {
269: httpServletResponse.addHeader(
270: "Content-Encoding", "gzip");
271: }
272: httpServletResponse.setHeader(RESPONSE_HEADER_NAME,
273: RESPONSE_HEADER_VALUE);
274: OutputStream os;
275: if (gzip) {
276: os = new GZIPOutputStream(httpServletResponse
277: .getOutputStream());
278: } else {
279: os = httpServletResponse.getOutputStream();
280: }
281: FileCopyUtils.copy(SOAP_RESPONSE.getBytes("UTF-8"),
282: os);
283: }
284: } catch (Exception ex) {
285: throw new ServletException(ex);
286: }
287: }
288: }
289:
290: }
|