1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.server.endpoint.interceptor;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.InputStream;
21 import java.util.Locale;
22 import javax.xml.XMLConstants;
23 import javax.xml.soap.MessageFactory;
24 import javax.xml.soap.SOAPConstants;
25 import javax.xml.soap.SOAPMessage;
26 import javax.xml.transform.Transformer;
27 import javax.xml.transform.TransformerFactory;
28 import javax.xml.transform.stream.StreamSource;
29
30 import org.custommonkey.xmlunit.XMLTestCase;
31 import org.xml.sax.SAXParseException;
32 import org.xml.sax.helpers.LocatorImpl;
33
34 import org.springframework.core.io.ClassPathResource;
35 import org.springframework.core.io.Resource;
36 import org.springframework.ws.MockWebServiceMessage;
37 import org.springframework.ws.MockWebServiceMessageFactory;
38 import org.springframework.ws.WebServiceMessage;
39 import org.springframework.ws.context.DefaultMessageContext;
40 import org.springframework.ws.context.MessageContext;
41 import org.springframework.ws.soap.SoapMessage;
42 import org.springframework.ws.soap.SoapVersion;
43 import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
44 import org.springframework.ws.soap.saaj.SaajSoapMessage;
45 import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
46 import org.springframework.ws.soap.saaj.support.SaajUtils;
47 import org.springframework.ws.soap.soap11.Soap11Fault;
48 import org.springframework.ws.soap.soap12.Soap12Fault;
49 import org.springframework.ws.transport.MockTransportInputStream;
50 import org.springframework.ws.transport.TransportInputStream;
51 import org.springframework.xml.xsd.SimpleXsdSchema;
52
53 public class PayloadValidatingInterceptorTest extends XMLTestCase {
54
55 private PayloadValidatingInterceptor interceptor;
56
57 private MessageContext context;
58
59 private SaajSoapMessageFactory soap11Factory;
60
61 private SaajSoapMessageFactory soap12Factory;
62
63 private Transformer transformer;
64
65 private static final String INVALID_MESSAGE = "invalidMessage.xml";
66
67 private static final String SCHEMA = "schema.xsd";
68
69 private static final String VALID_MESSAGE = "validMessage.xml";
70
71 private static final String PRODUCT_SCHEMA = "productSchema.xsd";
72
73 private static final String SIZE_SCHEMA = "sizeSchema.xsd";
74
75 private static final String VALID_SOAP_MESSAGE = "validSoapMessage.xml";
76
77 private static final String SCHEMA2 = "schema2.xsd";
78
79 protected void setUp() throws Exception {
80 interceptor = new PayloadValidatingInterceptor();
81 interceptor.setSchema(new ClassPathResource(SCHEMA, getClass()));
82 interceptor.setValidateRequest(true);
83 interceptor.setValidateResponse(true);
84 interceptor.afterPropertiesSet();
85
86 soap11Factory = new SaajSoapMessageFactory(MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL));
87 soap12Factory = new SaajSoapMessageFactory(MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL));
88 transformer = TransformerFactory.newInstance().newTransformer();
89 }
90
91 public void testHandleInvalidRequestSoap11() throws Exception {
92 SoapMessage invalidMessage = (SoapMessage) soap11Factory.createWebServiceMessage();
93 InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
94 transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
95 context = new DefaultMessageContext(invalidMessage, soap11Factory);
96
97 boolean result = interceptor.handleRequest(context, null);
98 assertFalse("Invalid response from interceptor", result);
99 assertTrue("Context has no response", context.hasResponse());
100 SoapMessage response = (SoapMessage) context.getResponse();
101 assertTrue("Response has no fault", response.getSoapBody().hasFault());
102 Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
103 assertEquals("Invalid fault code on fault", SoapVersion.SOAP_11.getClientOrSenderFaultName(),
104 fault.getFaultCode());
105 assertEquals("Invalid fault string on fault", PayloadValidatingInterceptor.DEFAULT_FAULTSTRING_OR_REASON,
106 fault.getFaultStringOrReason());
107 assertNotNull("No Detail on fault", fault.getFaultDetail());
108 }
109
110 public void testHandleInvalidRequestSoap12() throws Exception {
111 SoapMessage invalidMessage = (SoapMessage) soap12Factory.createWebServiceMessage();
112 InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
113 transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
114 context = new DefaultMessageContext(invalidMessage, soap12Factory);
115
116 boolean result = interceptor.handleRequest(context, null);
117 assertFalse("Invalid response from interceptor", result);
118 assertTrue("Context has no response", context.hasResponse());
119 SoapMessage response = (SoapMessage) context.getResponse();
120 assertTrue("Response has no fault", response.getSoapBody().hasFault());
121 Soap12Fault fault = (Soap12Fault) response.getSoapBody().getFault();
122 assertEquals("Invalid fault code on fault", SoapVersion.SOAP_12.getClientOrSenderFaultName(),
123 fault.getFaultCode());
124 assertEquals("Invalid fault string on fault", PayloadValidatingInterceptor.DEFAULT_FAULTSTRING_OR_REASON,
125 fault.getFaultReasonText(Locale.ENGLISH));
126 assertNotNull("No Detail on fault", fault.getFaultDetail());
127 }
128
129 public void testHandleInvalidRequestOverridenProperties() throws Exception {
130 String faultString = "fout";
131 Locale locale = new Locale("nl");
132 interceptor.setFaultStringOrReason(faultString);
133 interceptor.setFaultStringOrReasonLocale(locale);
134 interceptor.setAddValidationErrorDetail(false);
135
136 SoapMessage invalidMessage = (SoapMessage) soap11Factory.createWebServiceMessage();
137 InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
138 transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
139 context = new DefaultMessageContext(invalidMessage, soap11Factory);
140
141 boolean result = interceptor.handleRequest(context, null);
142 assertFalse("Invalid response from interceptor", result);
143 assertTrue("Context has no response", context.hasResponse());
144 SoapMessage response = (SoapMessage) context.getResponse();
145 assertTrue("Response has no fault", response.getSoapBody().hasFault());
146 Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
147 assertEquals("Invalid fault code on fault", SoapVersion.SOAP_11.getClientOrSenderFaultName(),
148 fault.getFaultCode());
149 assertEquals("Invalid fault string on fault", faultString, fault.getFaultStringOrReason());
150 assertEquals("Invalid fault string locale on fault", locale, fault.getFaultStringLocale());
151 assertNull("Detail on fault", fault.getFaultDetail());
152 }
153
154 public void testHandlerInvalidRequest() throws Exception {
155 MockWebServiceMessage request = new MockWebServiceMessage();
156 request.setPayload(new ClassPathResource(INVALID_MESSAGE, getClass()));
157 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
158 boolean result = interceptor.handleRequest(context, null);
159 assertFalse("Invalid response from interceptor", result);
160 }
161
162 public void testHandleValidRequest() throws Exception {
163 MockWebServiceMessage request = new MockWebServiceMessage();
164 request.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
165 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
166 boolean result = interceptor.handleRequest(context, null);
167 assertTrue("Invalid response from interceptor", result);
168 assertFalse("Response set", context.hasResponse());
169 }
170
171 public void testHandleInvalidResponse() throws Exception {
172 MockWebServiceMessage request = new MockWebServiceMessage();
173 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
174 MockWebServiceMessage response = (MockWebServiceMessage) context.getResponse();
175 response.setPayload(new ClassPathResource(INVALID_MESSAGE, getClass()));
176 boolean result = interceptor.handleResponse(context, null);
177 assertFalse("Invalid response from interceptor", result);
178 }
179
180 public void testHandleValidResponse() throws Exception {
181 MockWebServiceMessage request = new MockWebServiceMessage();
182 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
183 MockWebServiceMessage response = (MockWebServiceMessage) context.getResponse();
184 response.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
185 boolean result = interceptor.handleResponse(context, null);
186 assertTrue("Invalid response from interceptor", result);
187 }
188
189 public void testNamespacesInType() throws Exception {
190
191
192 String previousSchemaFactory =
193 System.getProperty("javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI, "");
194 System.setProperty("javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI,
195 "org.apache.xerces.jaxp.validation.XMLSchemaFactory");
196 try {
197 PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
198 interceptor.setSchema(new ClassPathResource(SCHEMA2, PayloadValidatingInterceptorTest.class));
199 interceptor.afterPropertiesSet();
200 MessageFactory messageFactory = MessageFactory.newInstance();
201 SOAPMessage saajMessage =
202 SaajUtils.loadMessage(new ClassPathResource(VALID_SOAP_MESSAGE, getClass()), messageFactory);
203 context = new DefaultMessageContext(new SaajSoapMessage(saajMessage),
204 new SaajSoapMessageFactory(messageFactory));
205
206 boolean result = interceptor.handleRequest(context, null);
207 assertTrue("Invalid response from interceptor", result);
208 assertFalse("Response set", context.hasResponse());
209 }
210 finally {
211
212 System.setProperty("javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI,
213 previousSchemaFactory);
214 }
215 }
216
217 public void testNonExistingSchema() throws Exception {
218 try {
219 interceptor.setSchema(new ClassPathResource("invalid"));
220 interceptor.afterPropertiesSet();
221 fail("IllegalArgumentException expected");
222 }
223 catch (IllegalArgumentException ex) {
224
225 }
226 }
227
228 public void testHandlerInvalidRequestMultipleSchemas() throws Exception {
229 interceptor.setSchemas(new Resource[]{new ClassPathResource(PRODUCT_SCHEMA, getClass()),
230 new ClassPathResource(SIZE_SCHEMA, getClass())});
231 interceptor.afterPropertiesSet();
232 MockWebServiceMessage request = new MockWebServiceMessage(new ClassPathResource(INVALID_MESSAGE, getClass()));
233 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
234 boolean result = interceptor.handleRequest(context, null);
235 assertFalse("Invalid response from interceptor", result);
236 }
237
238 public void testHandleValidRequestMultipleSchemas() throws Exception {
239 interceptor.setSchemas(new Resource[]{new ClassPathResource(PRODUCT_SCHEMA, getClass()),
240 new ClassPathResource(SIZE_SCHEMA, getClass())});
241 interceptor.afterPropertiesSet();
242 MockWebServiceMessage request = new MockWebServiceMessage(new ClassPathResource(VALID_MESSAGE, getClass()));
243 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
244
245 boolean result = interceptor.handleRequest(context, null);
246 assertTrue("Invalid response from interceptor", result);
247 assertFalse("Response set", context.hasResponse());
248 }
249
250 public void testHandleInvalidResponseMultipleSchemas() throws Exception {
251 interceptor.setSchemas(new Resource[]{new ClassPathResource(PRODUCT_SCHEMA, getClass()),
252 new ClassPathResource(SIZE_SCHEMA, getClass())});
253 interceptor.afterPropertiesSet();
254 MockWebServiceMessage request = new MockWebServiceMessage();
255 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
256 MockWebServiceMessage response = (MockWebServiceMessage) context.getResponse();
257 response.setPayload(new ClassPathResource(INVALID_MESSAGE, getClass()));
258 boolean result = interceptor.handleResponse(context, null);
259 assertFalse("Invalid response from interceptor", result);
260 }
261
262 public void testHandleValidResponseMultipleSchemas() throws Exception {
263 interceptor.setSchemas(new Resource[]{new ClassPathResource(PRODUCT_SCHEMA, getClass()),
264 new ClassPathResource(SIZE_SCHEMA, getClass())});
265 interceptor.afterPropertiesSet();
266 MockWebServiceMessage request = new MockWebServiceMessage();
267 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
268 MockWebServiceMessage response = (MockWebServiceMessage) context.getResponse();
269 response.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
270 boolean result = interceptor.handleResponse(context, null);
271 assertTrue("Invalid response from interceptor", result);
272 }
273
274 public void testCreateRequestValidationFaultAxiom() throws Exception {
275 LocatorImpl locator = new LocatorImpl();
276 locator.setLineNumber(0);
277 locator.setColumnNumber(0);
278 SAXParseException[] exceptions = new SAXParseException[]{new SAXParseException("Message 1", locator),
279 new SAXParseException("Message 2", locator),};
280 MessageContext messageContext = new DefaultMessageContext(new AxiomSoapMessageFactory());
281 interceptor.handleRequestValidationErrors(messageContext, exceptions);
282 ByteArrayOutputStream os = new ByteArrayOutputStream();
283 messageContext.getResponse().writeTo(os);
284 assertXMLEqual(
285 "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" + "<soapenv:Body>" +
286 "<soapenv:Fault>" + "<faultcode>soapenv:Client</faultcode>" +
287 "<faultstring xml:lang='en'>Validation error</faultstring>" + "<detail>" +
288 "<spring-ws:ValidationError xmlns:spring-ws=\"http://springframework.org/spring-ws\">Message 1</spring-ws:ValidationError>" +
289 "<spring-ws:ValidationError xmlns:spring-ws=\"http://springframework.org/spring-ws\">Message 2</spring-ws:ValidationError>" +
290 "</detail>" + "</soapenv:Fault>" + "</soapenv:Body>" + "</soapenv:Envelope>", os.toString());
291
292 }
293
294 public void testXsdSchema() throws Exception {
295 PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
296 SimpleXsdSchema schema = new SimpleXsdSchema(new ClassPathResource(SCHEMA, getClass()));
297 schema.afterPropertiesSet();
298 interceptor.setXsdSchema(schema);
299 interceptor.setValidateRequest(true);
300 interceptor.setValidateResponse(true);
301 interceptor.afterPropertiesSet();
302 MockWebServiceMessage request = new MockWebServiceMessage();
303 request.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
304 context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
305 boolean result = interceptor.handleRequest(context, null);
306 assertTrue("Invalid response from interceptor", result);
307 assertFalse("Response set", context.hasResponse());
308 }
309
310 public void testAxiom() throws Exception {
311 AxiomSoapMessageFactory messageFactory = new AxiomSoapMessageFactory();
312 messageFactory.setPayloadCaching(true);
313 messageFactory.afterPropertiesSet();
314
315 PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
316 interceptor.setSchema(new ClassPathResource("codexws.xsd", getClass()));
317 interceptor.afterPropertiesSet();
318
319 Resource resource = new ClassPathResource("axiom.xml", getClass());
320 TransportInputStream tis = new MockTransportInputStream(resource.getInputStream());
321 WebServiceMessage message = messageFactory.createWebServiceMessage(tis);
322 MessageContext context = new DefaultMessageContext(message, messageFactory);
323 boolean result = interceptor.handleRequest(context, null);
324 assertTrue("Invalid response from interceptor", result);
325
326 }
327
328 public void testMultipleNamespacesAxiom() throws Exception {
329 AxiomSoapMessageFactory messageFactory = new AxiomSoapMessageFactory();
330 messageFactory.setPayloadCaching(true);
331 messageFactory.afterPropertiesSet();
332
333 PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
334 interceptor.setSchema(new ClassPathResource("multipleNamespaces.xsd", getClass()));
335 interceptor.afterPropertiesSet();
336
337 Resource resource = new ClassPathResource("multipleNamespaces.xml", getClass());
338 TransportInputStream tis = new MockTransportInputStream(resource.getInputStream());
339 WebServiceMessage message = messageFactory.createWebServiceMessage(tis);
340 MessageContext context = new DefaultMessageContext(message, messageFactory);
341 boolean result = interceptor.handleRequest(context, null);
342 assertTrue("Invalid response from interceptor", result);
343
344 }
345
346 }