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.core;
18  
19  import java.io.IOException;
20  import java.net.URI;
21  import javax.xml.transform.Result;
22  import javax.xml.transform.Source;
23  
24  import org.springframework.oxm.Marshaller;
25  import org.springframework.oxm.Unmarshaller;
26  import org.springframework.ws.MockWebServiceMessage;
27  import org.springframework.ws.MockWebServiceMessageFactory;
28  import org.springframework.ws.WebServiceMessage;
29  import org.springframework.ws.client.WebServiceTransportException;
30  import org.springframework.ws.client.support.destination.DestinationProvider;
31  import org.springframework.ws.client.support.interceptor.ClientInterceptor;
32  import org.springframework.ws.context.DefaultMessageContext;
33  import org.springframework.ws.context.MessageContext;
34  import org.springframework.ws.transport.FaultAwareWebServiceConnection;
35  import org.springframework.ws.transport.WebServiceConnection;
36  import org.springframework.ws.transport.WebServiceMessageSender;
37  import org.springframework.xml.transform.StringResult;
38  import org.springframework.xml.transform.StringSource;
39  
40  import org.junit.Before;
41  import org.junit.Test;
42  
43  import static org.easymock.EasyMock.*;
44  import static org.junit.Assert.*;
45  
46  public class WebServiceTemplateTest {
47  
48      private WebServiceTemplate template;
49  
50      private FaultAwareWebServiceConnection connectionMock;
51  
52      private MockWebServiceMessageFactory messageFactory;
53  
54      @Before
55      public void setUp() throws Exception {
56          messageFactory = new MockWebServiceMessageFactory();
57          template = new WebServiceTemplate(messageFactory);
58          connectionMock = createMock(FaultAwareWebServiceConnection.class);
59          final URI expectedUri = new URI("http://www.springframework.org/spring-ws");
60          expect(connectionMock.getUri()).andReturn(expectedUri).anyTimes();
61          template.setMessageSender(new WebServiceMessageSender() {
62  
63              public WebServiceConnection createConnection(URI uri) throws IOException {
64                  return connectionMock;
65              }
66  
67              public boolean supports(URI uri) {
68                  assertEquals("Invalid uri", expectedUri, uri);
69                  return true;
70              }
71          });
72          template.setDefaultUri(expectedUri.toString());
73      }
74  
75      @Test
76      public void testMarshalAndSendNoMarshallerSet() throws Exception {
77          connectionMock.close();
78  
79          replay(connectionMock);
80  
81          template.setMarshaller(null);
82          try {
83              template.marshalSendAndReceive(new Object());
84              fail("IllegalStateException expected");
85          }
86          catch (IllegalStateException ex) {
87              // expected behavior
88          }
89  
90          verify(connectionMock);
91      }
92  
93      @Test
94      public void testMarshalAndSendNoUnmarshallerSet() throws Exception {
95          connectionMock.close();
96  
97          replay(connectionMock);
98  
99          template.setUnmarshaller(null);
100         try {
101             template.marshalSendAndReceive(new Object());
102             fail("IllegalStateException expected");
103         }
104         catch (IllegalStateException ex) {
105             // expected behavior
106         }
107 
108         verify(connectionMock);
109     }
110 
111     @Test
112     public void testSendAndReceiveMessageResponse() throws Exception {
113         WebServiceMessageCallback requestCallback = createMock(WebServiceMessageCallback.class);
114         requestCallback.doWithMessage(isA(WebServiceMessage.class));
115 
116         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
117         Object extracted = new Object();
118         expect(extractorMock.extractData(isA(WebServiceMessage.class))).andReturn(extracted);
119 
120         connectionMock.send(isA(WebServiceMessage.class));
121         expect(connectionMock.hasError()).andReturn(false);
122         expect(connectionMock.receive(messageFactory)).andReturn(new MockWebServiceMessage("<response/>"));
123         expect(connectionMock.hasFault()).andReturn(false);
124         connectionMock.close();
125 
126         replay(connectionMock, requestCallback, extractorMock);
127 
128         Object result = template.sendAndReceive(requestCallback, extractorMock);
129         assertEquals("Invalid response", extracted, result);
130 
131         verify(connectionMock, requestCallback, extractorMock);
132     }
133 
134     @Test
135     public void testSendAndReceiveMessageNoResponse() throws Exception {
136         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
137 
138         connectionMock.send(isA(WebServiceMessage.class));
139         expect(connectionMock.hasError()).andReturn(false);
140         expect(connectionMock.receive(messageFactory)).andReturn(null);
141         connectionMock.close();
142 
143         replay(connectionMock, extractorMock);
144 
145         Object result = template.sendAndReceive(null, extractorMock);
146         assertNull("Invalid response", result);
147 
148         verify(connectionMock, extractorMock);
149     }
150 
151     @Test
152     public void testSendAndReceiveMessageFault() throws Exception {
153         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
154 
155         FaultMessageResolver faultMessageResolverMock = createMock(FaultMessageResolver.class);
156         template.setFaultMessageResolver(faultMessageResolverMock);
157         faultMessageResolverMock.resolveFault(isA(WebServiceMessage.class));
158 
159         MockWebServiceMessage response = new MockWebServiceMessage("<response/>");
160         response.setFault(true);
161 
162         connectionMock.send(isA(WebServiceMessage.class));
163         expect(connectionMock.hasError()).andReturn(false);
164         expect(connectionMock.hasFault()).andReturn(true);
165         expect(connectionMock.receive(messageFactory)).andReturn(response);
166         connectionMock.close();
167 
168         replay(connectionMock, extractorMock, faultMessageResolverMock);
169 
170         Object result = template.sendAndReceive(null, extractorMock);
171         assertNull("Invalid response", result);
172 
173         verify(connectionMock, extractorMock, faultMessageResolverMock);
174     }
175 
176     @Test
177     public void testSendAndReceiveConnectionError() throws Exception {
178         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
179 
180         template.setFaultMessageResolver(null);
181 
182         connectionMock.send(isA(WebServiceMessage.class));
183         expect(connectionMock.hasError()).andReturn(true);
184         expect(connectionMock.hasFault()).andReturn(false);
185         String errorMessage = "errorMessage";
186         expect(connectionMock.getErrorMessage()).andReturn(errorMessage);
187         connectionMock.close();
188 
189         replay(connectionMock, extractorMock);
190 
191         try {
192             template.sendAndReceive(null, extractorMock);
193             fail("Expected WebServiceTransportException");
194         }
195         catch (WebServiceTransportException ex) {
196             //expected
197             assertEquals("Invalid exception message", errorMessage, ex.getMessage());
198         }
199 
200         verify(connectionMock, extractorMock);
201     }
202 
203     @Test
204     public void testSendAndReceiveSourceResponse() throws Exception {
205         SourceExtractor extractorMock = createMock(SourceExtractor.class);
206         Object extracted = new Object();
207         expect(extractorMock.extractData(isA(Source.class))).andReturn(extracted);
208 
209         connectionMock.send(isA(WebServiceMessage.class));
210         expect(connectionMock.hasError()).andReturn(false);
211         expect(connectionMock.receive(messageFactory)).andReturn(new MockWebServiceMessage("<response/>"));
212         expect(connectionMock.hasFault()).andReturn(false);
213         connectionMock.close();
214 
215         replay(connectionMock, extractorMock);
216 
217         Object result = template.sendSourceAndReceive(new StringSource("<request />"), extractorMock);
218         assertEquals("Invalid response", extracted, result);
219 
220         verify(connectionMock, extractorMock);
221     }
222 
223     @Test
224     public void testSendAndReceiveSourceNoResponse() throws Exception {
225         SourceExtractor extractorMock = createMock(SourceExtractor.class);
226 
227         connectionMock.send(isA(WebServiceMessage.class));
228         expect(connectionMock.hasError()).andReturn(false);
229         expect(connectionMock.receive(messageFactory)).andReturn(null);
230         connectionMock.close();
231 
232         replay(connectionMock, extractorMock);
233 
234         Object result = template.sendSourceAndReceive(new StringSource("<request />"), extractorMock);
235         assertNull("Invalid response", result);
236 
237         verify(connectionMock, extractorMock);
238     }
239 
240     @Test
241     public void testSendAndReceiveResultResponse() throws Exception {
242         connectionMock.send(isA(WebServiceMessage.class));
243         expect(connectionMock.hasError()).andReturn(false);
244         expect(connectionMock.receive(messageFactory)).andReturn(new MockWebServiceMessage("<response/>"));
245         expect(connectionMock.hasFault()).andReturn(false);
246         connectionMock.close();
247 
248         replay(connectionMock);
249 
250         StringResult result = new StringResult();
251         boolean b = template.sendSourceAndReceiveToResult(new StringSource("<request />"), result);
252         assertTrue("Invalid result", b);
253 
254         verify(connectionMock);
255     }
256 
257     @Test
258     public void testSendAndReceiveResultNoResponse() throws Exception {
259         connectionMock.send(isA(WebServiceMessage.class));
260         expect(connectionMock.hasError()).andReturn(false);
261         expect(connectionMock.receive(messageFactory)).andReturn(null);
262         connectionMock.close();
263 
264         replay(connectionMock);
265 
266         StringResult result = new StringResult();
267         boolean b = template.sendSourceAndReceiveToResult(new StringSource("<request />"), result);
268         assertFalse("Invalid result", b);
269 
270         verify(connectionMock);
271     }
272 
273     @Test
274     public void testSendAndReceiveResultNoResponsePayload() throws Exception {
275         connectionMock.send(isA(WebServiceMessage.class));
276         expect(connectionMock.hasError()).andReturn(false);
277         WebServiceMessage response = createMock(WebServiceMessage.class);
278         expect(connectionMock.receive(messageFactory)).andReturn(response);
279         expect(connectionMock.hasFault()).andReturn(false);
280         expect(response.getPayloadSource()).andReturn(null);
281         connectionMock.close();
282 
283         replay(connectionMock, response);
284 
285         StringResult result = new StringResult();
286         boolean b = template.sendSourceAndReceiveToResult(new StringSource("<request />"), result);
287         assertTrue("Invalid result", b);
288 
289         verify(connectionMock, response);
290     }
291 
292 
293     @Test
294     public void testSendAndReceiveMarshalResponse() throws Exception {
295         Marshaller marshallerMock = createMock(Marshaller.class);
296         template.setMarshaller(marshallerMock);
297         marshallerMock.marshal(isA(Object.class), isA(Result.class));
298 
299         Unmarshaller unmarshallerMock = createMock(Unmarshaller.class);
300         template.setUnmarshaller(unmarshallerMock);
301         Object unmarshalled = new Object();
302         expect(unmarshallerMock.unmarshal(isA(Source.class))).andReturn(unmarshalled);
303 
304         connectionMock.send(isA(WebServiceMessage.class));
305         expect(connectionMock.hasError()).andReturn(false);
306         expect(connectionMock.receive(messageFactory)).andReturn(new MockWebServiceMessage("<response/>"));
307         expect(connectionMock.hasFault()).andReturn(false);
308         connectionMock.close();
309 
310         replay(connectionMock, marshallerMock, unmarshallerMock);
311 
312         Object result = template.marshalSendAndReceive(new Object());
313         assertEquals("Invalid result", unmarshalled, result);
314 
315         verify(connectionMock, marshallerMock, unmarshallerMock);
316     }
317 
318     @Test
319     public void testSendAndReceiveMarshalNoResponse() throws Exception {
320         Marshaller marshallerMock = createMock(Marshaller.class);
321         template.setMarshaller(marshallerMock);
322         marshallerMock.marshal(isA(Object.class), isA(Result.class));
323 
324         connectionMock.send(isA(WebServiceMessage.class));
325         expect(connectionMock.hasError()).andReturn(false);
326         expect(connectionMock.receive(messageFactory)).andReturn(null);
327         connectionMock.close();
328 
329         replay(connectionMock, marshallerMock);
330 
331         Object result = template.marshalSendAndReceive(new Object());
332         assertNull("Invalid result", result);
333 
334         verify(connectionMock, marshallerMock);
335     }
336 
337     @Test
338     public void testSendAndReceiveCustomUri() throws Exception {
339         final URI customUri = new URI("http://www.springframework.org/spring-ws/custom");
340         template.setMessageSender(new WebServiceMessageSender() {
341 
342             public WebServiceConnection createConnection(URI uri) throws IOException {
343                 return connectionMock;
344             }
345 
346             public boolean supports(URI uri) {
347                 assertEquals("Invalid uri", customUri, uri);
348                 return true;
349             }
350         });
351         WebServiceMessageCallback requestCallback = createMock(WebServiceMessageCallback.class);
352         requestCallback.doWithMessage(isA(WebServiceMessage.class));
353 
354         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
355         Object extracted = new Object();
356         expect(extractorMock.extractData(isA(WebServiceMessage.class))).andReturn(extracted);
357 
358         connectionMock.send(isA(WebServiceMessage.class));
359         expect(connectionMock.hasError()).andReturn(false);
360         expect(connectionMock.receive(messageFactory)).andReturn(new MockWebServiceMessage("<response/>"));
361         expect(connectionMock.hasFault()).andReturn(false);
362         connectionMock.close();
363 
364         replay(connectionMock, requestCallback, extractorMock);
365 
366         Object result = template.sendAndReceive(customUri.toString(), requestCallback, extractorMock);
367         assertEquals("Invalid response", extracted, result);
368 
369         verify(connectionMock, requestCallback, extractorMock);
370     }
371 
372     @Test
373     public void testInterceptors() throws Exception {
374         ClientInterceptor interceptorMock1 = createStrictMock("interceptor1", ClientInterceptor.class);
375         ClientInterceptor interceptorMock2 = createStrictMock("interceptor2", ClientInterceptor.class);
376         template.setInterceptors(new ClientInterceptor[]{interceptorMock1, interceptorMock2});
377         expect(interceptorMock1.handleRequest(isA(MessageContext.class))).andReturn(true);
378         expect(interceptorMock2.handleRequest(isA(MessageContext.class))).andReturn(true);
379         expect(interceptorMock2.handleResponse(isA(MessageContext.class))).andReturn(true);
380         expect(interceptorMock1.handleResponse(isA(MessageContext.class))).andReturn(true);
381 
382         WebServiceMessageCallback requestCallback = createMock(WebServiceMessageCallback.class);
383         requestCallback.doWithMessage(isA(WebServiceMessage.class));
384 
385         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
386         Object extracted = new Object();
387         expect(extractorMock.extractData(isA(WebServiceMessage.class))).andReturn(extracted);
388 
389         connectionMock.send(isA(WebServiceMessage.class));
390         expect(connectionMock.hasError()).andReturn(false);
391         expect(connectionMock.receive(messageFactory)).andReturn(new MockWebServiceMessage("<response/>"));
392         expect(connectionMock.hasFault()).andReturn(false);
393         connectionMock.close();
394 
395         replay(connectionMock, interceptorMock1, interceptorMock2, requestCallback, extractorMock);
396 
397         Object result = template.sendAndReceive(requestCallback, extractorMock);
398         assertEquals("Invalid response", extracted, result);
399 
400         verify(connectionMock, interceptorMock1, interceptorMock2, requestCallback, extractorMock);
401     }
402 
403     @Test
404     public void testInterceptorsIntercepted() throws Exception {
405         MessageContext messageContext = new DefaultMessageContext(messageFactory);
406 
407         ClientInterceptor interceptorMock1 = createStrictMock("interceptor1", ClientInterceptor.class);
408         ClientInterceptor interceptorMock2 = createStrictMock("interceptor2", ClientInterceptor.class);
409         template.setInterceptors(new ClientInterceptor[]{interceptorMock1, interceptorMock2});
410         expect(interceptorMock1.handleRequest(isA(MessageContext.class))).andReturn(false);
411         expect(interceptorMock1.handleResponse(isA(MessageContext.class))).andReturn(true);
412 
413         WebServiceMessageCallback requestCallback = createMock(WebServiceMessageCallback.class);
414         requestCallback.doWithMessage(messageContext.getRequest());
415 
416         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
417         Object extracted = new Object();
418         expect(extractorMock.extractData(isA(WebServiceMessage.class))).andReturn(extracted);
419 
420         connectionMock.send(isA(WebServiceMessage.class));
421         expect(connectionMock.hasError()).andReturn(false);
422         expect(connectionMock.receive(messageFactory)).andReturn(new MockWebServiceMessage("<response/>"));
423         expect(connectionMock.hasFault()).andReturn(false);
424 
425         replay(connectionMock, interceptorMock1, interceptorMock2, requestCallback, extractorMock);
426 
427         Object result = template.doSendAndReceive(messageContext, connectionMock, requestCallback, extractorMock);
428         assertEquals("Invalid response", extracted, result);
429 
430         verify(connectionMock, interceptorMock1, interceptorMock2, requestCallback, extractorMock);
431     }
432 
433     @Test
434     public void testInterceptorsInterceptedCreateResponse() throws Exception {
435         MessageContext messageContext = new DefaultMessageContext(messageFactory);
436         // force creation of response
437         messageContext.getResponse();
438 
439         ClientInterceptor interceptorMock1 = createStrictMock("interceptor1", ClientInterceptor.class);
440         ClientInterceptor interceptorMock2 = createStrictMock("interceptor2", ClientInterceptor.class);
441         template.setInterceptors(new ClientInterceptor[]{interceptorMock1, interceptorMock2});
442         expect(interceptorMock1.handleRequest(isA(MessageContext.class))).andReturn(false);
443         expect(interceptorMock1.handleResponse(isA(MessageContext.class))).andReturn(true);
444 
445         WebServiceMessageCallback requestCallback = createMock(WebServiceMessageCallback.class);
446         requestCallback.doWithMessage(messageContext.getRequest());
447 
448         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
449         Object extracted = new Object();
450         expect(extractorMock.extractData(messageContext.getResponse())).andReturn(extracted);
451 
452         expect(connectionMock.hasFault()).andReturn(false);
453 
454         replay(connectionMock, interceptorMock1, interceptorMock2, requestCallback, extractorMock);
455 
456         Object result = template.doSendAndReceive(messageContext, connectionMock, requestCallback, extractorMock);
457         assertEquals("Invalid response", extracted, result);
458 
459         verify(connectionMock, interceptorMock1, interceptorMock2, requestCallback, extractorMock);
460     }
461 
462     @Test
463     public void testDestinationResolver() throws Exception {
464         DestinationProvider providerMock = createMock(DestinationProvider.class);
465         template.setDestinationProvider(providerMock);
466         final URI providerUri = new URI("http://www.springframework.org/spring-ws/destinationProvider");
467         expect(providerMock.getDestination()).andReturn(providerUri);
468 
469         template.setMessageSender(new WebServiceMessageSender() {
470 
471             public WebServiceConnection createConnection(URI uri) throws IOException {
472                 return connectionMock;
473             }
474 
475             public boolean supports(URI uri) {
476                 assertEquals("Invalid uri", providerUri, uri);
477                 return true;
478             }
479         });
480 
481         WebServiceMessageExtractor extractorMock = createMock(WebServiceMessageExtractor.class);
482 
483         reset(connectionMock);
484         expect(connectionMock.getUri()).andReturn(providerUri);
485         connectionMock.send(isA(WebServiceMessage.class));
486         expect(connectionMock.hasError()).andReturn(false);
487         expect(connectionMock.receive(messageFactory)).andReturn(null);
488         connectionMock.close();
489 
490         replay(connectionMock, extractorMock, providerMock);
491 
492         Object result = template.sendAndReceive(null, extractorMock);
493         assertNull("Invalid response", result);
494 
495         verify(connectionMock, extractorMock, providerMock);
496     }
497 
498 
499 }