1   /*
2    * Copyright 2005-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.client.support.interceptor;
18  
19  import java.io.InputStream;
20  import javax.xml.XMLConstants;
21  import javax.xml.soap.MessageFactory;
22  import javax.xml.soap.SOAPConstants;
23  import javax.xml.soap.SOAPMessage;
24  import javax.xml.transform.Transformer;
25  import javax.xml.transform.TransformerFactory;
26  import javax.xml.transform.stream.StreamSource;
27  
28  import org.springframework.core.io.ClassPathResource;
29  import org.springframework.core.io.Resource;
30  import org.springframework.ws.MockWebServiceMessage;
31  import org.springframework.ws.MockWebServiceMessageFactory;
32  import org.springframework.ws.client.WebServiceClientException;
33  import org.springframework.ws.context.DefaultMessageContext;
34  import org.springframework.ws.context.MessageContext;
35  import org.springframework.ws.soap.SoapMessage;
36  import org.springframework.ws.soap.saaj.SaajSoapMessage;
37  import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
38  import org.springframework.ws.soap.saaj.support.SaajUtils;
39  import org.springframework.xml.xsd.SimpleXsdSchema;
40  
41  import org.junit.Assert;
42  import org.junit.Before;
43  import org.junit.Test;
44  
45  public class PayloadValidatingInterceptorTest {
46  
47      private PayloadValidatingInterceptor interceptor;
48  
49      private MessageContext context;
50  
51      private SaajSoapMessageFactory soap11Factory;
52  
53      private Transformer transformer;
54  
55      private static final String INVALID_MESSAGE = "invalidMessage.xml";
56  
57      private static final String SCHEMA = "schema.xsd";
58  
59      private static final String VALID_MESSAGE = "validMessage.xml";
60  
61      private static final String PRODUCT_SCHEMA = "productSchema.xsd";
62  
63      private static final String SIZE_SCHEMA = "sizeSchema.xsd";
64  
65      private static final String VALID_SOAP_MESSAGE = "validSoapMessage.xml";
66  
67      private static final String SCHEMA2 = "schema2.xsd";
68  
69      @Before
70      public void setUp() throws Exception {
71          interceptor = new PayloadValidatingInterceptor();
72          interceptor.setSchema(new ClassPathResource(SCHEMA, getClass()));
73          interceptor.setValidateRequest(true);
74          interceptor.setValidateResponse(true);
75          interceptor.afterPropertiesSet();
76  
77          soap11Factory = new SaajSoapMessageFactory(MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL));
78  
79          transformer = TransformerFactory.newInstance().newTransformer();
80      }
81  
82      @Test
83      public void testHandleInvalidRequest() throws Exception {
84          SoapMessage invalidMessage = (SoapMessage) soap11Factory.createWebServiceMessage();
85          InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
86          transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
87          context = new DefaultMessageContext(invalidMessage, soap11Factory);
88  
89          boolean validated;
90          try {
91              validated = interceptor.handleRequest(context);
92          }
93          catch (WebServiceClientException e) {
94              validated = false;
95              Assert.assertNotNull("No exception details provided in WebServiceClientException", e.getMessage());
96          }
97          Assert.assertFalse("Invalid response from interceptor", validated);
98      }
99  
100     @Test
101     public void testHandlerInvalidRequest() throws Exception {
102         MockWebServiceMessage request = new MockWebServiceMessage();
103         request.setPayload(new ClassPathResource(INVALID_MESSAGE, getClass()));
104         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
105 
106         boolean validated;
107         try {
108             validated = interceptor.handleRequest(context);
109         }
110         catch (WebServiceClientException e) {
111             validated = false;
112             Assert.assertNotNull("No exception details provided in WebServiceClientException", e.getMessage());
113         }
114         Assert.assertFalse("Invalid response from interceptor", validated);
115     }
116 
117     @Test
118     public void testHandleValidRequest() throws Exception {
119         MockWebServiceMessage request = new MockWebServiceMessage();
120         request.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
121         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
122         boolean result = interceptor.handleRequest(context);
123         Assert.assertTrue("Invalid response from interceptor", result);
124         Assert.assertFalse("Response set", context.hasResponse());
125     }
126 
127     @Test
128     public void testHandleInvalidResponse() throws Exception {
129         MockWebServiceMessage request = new MockWebServiceMessage();
130         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
131         MockWebServiceMessage response = (MockWebServiceMessage) context.getResponse();
132         response.setPayload(new ClassPathResource(INVALID_MESSAGE, getClass()));
133 
134         boolean result = interceptor.handleResponse(context);
135         Assert.assertFalse("Invalid response from interceptor", result);
136     }
137 
138     @Test
139     public void testHandleValidResponse() throws Exception {
140         MockWebServiceMessage request = new MockWebServiceMessage();
141         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
142         MockWebServiceMessage response = (MockWebServiceMessage) context.getResponse();
143         response.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
144         boolean result = interceptor.handleResponse(context);
145         Assert.assertTrue("Invalid response from interceptor", result);
146     }
147 
148     @Test
149     public void testNamespacesInType() throws Exception {
150         // Make sure we use Xerces for this testcase: the JAXP implementation used internally by JDK 1.5 has a bug
151         // See http://opensource.atlassian.com/projects/spring/browse/SWS-35
152         String previousSchemaFactory =
153                 System.getProperty("javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI, "");
154         System.setProperty("javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI,
155                 "org.apache.xerces.jaxp.validation.XMLSchemaFactory");
156         try {
157             PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
158             interceptor.setSchema(new ClassPathResource(SCHEMA2, PayloadValidatingInterceptorTest.class));
159             interceptor.afterPropertiesSet();
160             MessageFactory messageFactory = MessageFactory.newInstance();
161             SOAPMessage saajMessage =
162                     SaajUtils.loadMessage(new ClassPathResource(VALID_SOAP_MESSAGE, getClass()), messageFactory);
163             context = new DefaultMessageContext(new SaajSoapMessage(saajMessage),
164                     new SaajSoapMessageFactory(messageFactory));
165 
166             boolean result = interceptor.handleRequest(context);
167             Assert.assertTrue("Invalid response from interceptor", result);
168             Assert.assertFalse("Response set", context.hasResponse());
169         }
170         finally {
171             // Reset the property
172             System.setProperty("javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI,
173                     previousSchemaFactory);
174         }
175     }
176 
177     @Test
178     public void testNonExistingSchema() throws Exception {
179         try {
180             interceptor.setSchema(new ClassPathResource("invalid"));
181             interceptor.afterPropertiesSet();
182             Assert.fail("IllegalArgumentException expected");
183         }
184         catch (IllegalArgumentException ex) {
185             // expected
186         }
187     }
188 
189     @Test
190     public void testHandlerInvalidRequestMultipleSchemas() throws Exception {
191         interceptor.setSchemas(new Resource[]{new ClassPathResource(PRODUCT_SCHEMA, getClass()),
192                 new ClassPathResource(SIZE_SCHEMA, getClass())});
193         interceptor.afterPropertiesSet();
194         MockWebServiceMessage request = new MockWebServiceMessage(new ClassPathResource(INVALID_MESSAGE, getClass()));
195         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
196 
197         boolean validated;
198         try {
199             validated = interceptor.handleRequest(context);
200         }
201         catch (WebServiceClientException e) {
202             validated = false;
203             Assert.assertNotNull("No exception details provided in WebServiceClientException", e.getMessage());
204         }
205         Assert.assertFalse("Invalid response from interceptor", validated);
206     }
207 
208     @Test
209     public void testHandleValidRequestMultipleSchemas() throws Exception {
210         interceptor.setSchemas(new Resource[]{new ClassPathResource(PRODUCT_SCHEMA, getClass()),
211                 new ClassPathResource(SIZE_SCHEMA, getClass())});
212         interceptor.afterPropertiesSet();
213         MockWebServiceMessage request = new MockWebServiceMessage(new ClassPathResource(VALID_MESSAGE, getClass()));
214         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
215 
216         boolean result = interceptor.handleRequest(context);
217         Assert.assertTrue("Invalid response from interceptor", result);
218         Assert.assertFalse("Response set", context.hasResponse());
219     }
220 
221     @Test
222     public void testHandleInvalidResponseMultipleSchemas() throws Exception {
223         interceptor.setSchemas(new Resource[]{new ClassPathResource(PRODUCT_SCHEMA, getClass()),
224                 new ClassPathResource(SIZE_SCHEMA, getClass())});
225         interceptor.afterPropertiesSet();
226         MockWebServiceMessage request = new MockWebServiceMessage();
227         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
228         MockWebServiceMessage response = (MockWebServiceMessage) context.getResponse();
229         response.setPayload(new ClassPathResource(INVALID_MESSAGE, getClass()));
230         boolean result = interceptor.handleResponse(context);
231         Assert.assertFalse("Invalid response from interceptor", result);
232     }
233 
234     @Test
235     public void testHandleValidResponseMultipleSchemas() throws Exception {
236         interceptor.setSchemas(new Resource[]{new ClassPathResource(PRODUCT_SCHEMA, getClass()),
237                 new ClassPathResource(SIZE_SCHEMA, getClass())});
238         interceptor.afterPropertiesSet();
239         MockWebServiceMessage request = new MockWebServiceMessage();
240         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
241         MockWebServiceMessage response = (MockWebServiceMessage) context.getResponse();
242         response.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
243         boolean result = interceptor.handleResponse(context);
244         Assert.assertTrue("Invalid response from interceptor", result);
245     }
246 
247     @Test
248     public void testXsdSchema() throws Exception {
249         PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
250         SimpleXsdSchema schema = new SimpleXsdSchema(new ClassPathResource(SCHEMA, getClass()));
251         schema.afterPropertiesSet();
252         interceptor.setXsdSchema(schema);
253         interceptor.setValidateRequest(true);
254         interceptor.setValidateResponse(true);
255         interceptor.afterPropertiesSet();
256         MockWebServiceMessage request = new MockWebServiceMessage();
257         request.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
258         context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
259         boolean result = interceptor.handleRequest(context);
260         Assert.assertTrue("Invalid response from interceptor", result);
261         Assert.assertFalse("Response set", context.hasResponse());
262     }
263 }