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.soap.server;
18  
19  import java.util.Iterator;
20  import java.util.Locale;
21  import javax.xml.namespace.QName;
22  import javax.xml.soap.MessageFactory;
23  import javax.xml.soap.SOAPConstants;
24  import javax.xml.soap.SOAPHeaderElement;
25  import javax.xml.soap.SOAPMessage;
26  
27  import org.springframework.ws.context.DefaultMessageContext;
28  import org.springframework.ws.context.MessageContext;
29  import org.springframework.ws.soap.SoapBody;
30  import org.springframework.ws.soap.SoapHeader;
31  import org.springframework.ws.soap.SoapHeaderElement;
32  import org.springframework.ws.soap.SoapMessage;
33  import org.springframework.ws.soap.SoapMessageFactory;
34  import org.springframework.ws.soap.saaj.SaajSoapMessage;
35  import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
36  import org.springframework.ws.soap.soap11.Soap11Fault;
37  import org.springframework.ws.soap.soap12.Soap12Fault;
38  
39  import org.junit.Assert;
40  import org.junit.Before;
41  import org.junit.Test;
42  
43  import static org.easymock.EasyMock.*;
44  
45  public class SoapMessageDispatcherTest {
46  
47      private SoapMessageDispatcher dispatcher;
48  
49      private SoapEndpointInterceptor interceptorMock;
50  
51      @Before
52      public void setUp() throws Exception {
53          interceptorMock = createMock(SoapEndpointInterceptor.class);
54          dispatcher = new SoapMessageDispatcher();
55      }
56  
57      @Test
58      public void testProcessMustUnderstandHeadersUnderstoodSoap11() throws Exception {
59          MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
60          SOAPMessage request = messageFactory.createMessage();
61          SOAPHeaderElement header =
62                  request.getSOAPHeader().addHeaderElement(new QName("http://www.springframework.org", "Header"));
63          header.setActor(SOAPConstants.URI_SOAP_ACTOR_NEXT);
64          header.setMustUnderstand(true);
65          SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
66          MessageContext context = new DefaultMessageContext(new SaajSoapMessage(request), factory);
67          expect(interceptorMock.understands(isA(SoapHeaderElement.class))).andReturn(true);
68  
69          replay(interceptorMock);
70  
71          SoapEndpointInvocationChain chain =
72                  new SoapEndpointInvocationChain(new Object(), new SoapEndpointInterceptor[]{interceptorMock});
73  
74          boolean result = dispatcher.handleRequest(chain, context);
75          Assert.assertTrue("Header not understood", result);
76  
77          verify(interceptorMock);
78      }
79  
80      @Test
81      public void testProcessMustUnderstandHeadersUnderstoodSoap12() throws Exception {
82          MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
83          SOAPMessage request = messageFactory.createMessage();
84          SOAPHeaderElement header =
85                  request.getSOAPHeader().addHeaderElement(new QName("http://www.springframework.org", "Header"));
86          header.setMustUnderstand(true);
87          header.setRole(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT);
88          SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
89          MessageContext context = new DefaultMessageContext(new SaajSoapMessage(request), factory);
90          expect(interceptorMock.understands(isA(SoapHeaderElement.class))).andReturn(true);
91  
92          replay(interceptorMock);
93  
94          SoapEndpointInvocationChain chain =
95                  new SoapEndpointInvocationChain(new Object(), new SoapEndpointInterceptor[]{interceptorMock});
96  
97          boolean result = dispatcher.handleRequest(chain, context);
98          Assert.assertTrue("Header not understood", result);
99  
100         verify(interceptorMock);
101     }
102 
103     @Test
104     public void testProcessMustUnderstandHeadersNotUnderstoodSoap11() throws Exception {
105         MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
106         SOAPMessage request = messageFactory.createMessage();
107         SOAPHeaderElement header = request.getSOAPHeader()
108                 .addHeaderElement(new QName("http://www.springframework.org", "Header", "spring-ws"));
109         header.setActor(SOAPConstants.URI_SOAP_ACTOR_NEXT);
110         header.setMustUnderstand(true);
111         SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
112         MessageContext context = new DefaultMessageContext(new SaajSoapMessage(request), factory);
113         expect(interceptorMock.understands(isA(SoapHeaderElement.class))).andReturn(false);
114 
115         replay(interceptorMock);
116 
117         SoapEndpointInvocationChain chain =
118                 new SoapEndpointInvocationChain(new Object(), new SoapEndpointInterceptor[]{interceptorMock});
119 
120         boolean result = dispatcher.handleRequest(chain, context);
121         Assert.assertFalse("Header understood", result);
122         Assert.assertTrue("Context has no response", context.hasResponse());
123         SoapBody responseBody = ((SoapMessage) context.getResponse()).getSoapBody();
124         Assert.assertTrue("Response body has no fault", responseBody.hasFault());
125         Soap11Fault fault = (Soap11Fault) responseBody.getFault();
126         Assert.assertEquals("Invalid fault code", new QName(SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE, "MustUnderstand"),
127                 fault.getFaultCode());
128         Assert.assertEquals("Invalid fault string", SoapMessageDispatcher.DEFAULT_MUST_UNDERSTAND_FAULT_STRING,
129                 fault.getFaultStringOrReason());
130         Assert.assertEquals("Invalid fault string locale", Locale.ENGLISH, fault.getFaultStringLocale());
131 
132         verify(interceptorMock);
133     }
134 
135     @Test
136     public void testProcessMustUnderstandHeadersNotUnderstoodSoap12() throws Exception {
137         MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
138         SOAPMessage request = messageFactory.createMessage();
139         SOAPHeaderElement header = request.getSOAPHeader()
140                 .addHeaderElement(new QName("http://www.springframework.org", "Header", "spring-ws"));
141         header.setMustUnderstand(true);
142         header.setRole(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT);
143         SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
144         MessageContext context = new DefaultMessageContext(new SaajSoapMessage(request), factory);
145         expect(interceptorMock.understands(isA(SoapHeaderElement.class))).andReturn(false);
146 
147         replay(interceptorMock);
148 
149         SoapEndpointInvocationChain chain =
150                 new SoapEndpointInvocationChain(new Object(), new SoapEndpointInterceptor[]{interceptorMock});
151 
152         boolean result = dispatcher.handleRequest(chain, context);
153         Assert.assertFalse("Header understood", result);
154         Assert.assertTrue("Context has no response", context.hasResponse());
155         SoapMessage response = (SoapMessage) context.getResponse();
156         SoapBody responseBody = response.getSoapBody();
157         Assert.assertTrue("Response body has no fault", responseBody.hasFault());
158         Soap12Fault fault = (Soap12Fault) responseBody.getFault();
159         Assert.assertEquals("Invalid fault code", new QName(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "MustUnderstand"),
160                 fault.getFaultCode());
161         Assert.assertEquals("Invalid fault string", SoapMessageDispatcher.DEFAULT_MUST_UNDERSTAND_FAULT_STRING,
162                 fault.getFaultReasonText(Locale.ENGLISH));
163         SoapHeader responseHeader = response.getSoapHeader();
164         Iterator<SoapHeaderElement> iterator = responseHeader.examineAllHeaderElements();
165         Assert.assertTrue("Response header has no elements", iterator.hasNext());
166         SoapHeaderElement headerElement = iterator.next();
167         Assert.assertEquals("No NotUnderstood header",
168                 new QName(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "NotUnderstood"), headerElement.getName());
169 
170         verify(interceptorMock);
171     }
172 
173     @Test
174     public void testProcessMustUnderstandHeadersForActorSoap11() throws Exception {
175         MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
176         SOAPMessage request = messageFactory.createMessage();
177         SOAPHeaderElement header = request.getSOAPHeader()
178                 .addHeaderElement(new QName("http://www.springframework.org", "Header", "spring-ws"));
179         String headerActor = "http://www/springframework.org/role";
180         header.setActor(headerActor);
181         header.setMustUnderstand(true);
182         SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
183         MessageContext context = new DefaultMessageContext(new SaajSoapMessage(request), factory);
184         expect(interceptorMock.understands(isA(SoapHeaderElement.class))).andReturn(true);
185 
186         replay(interceptorMock);
187 
188         SoapEndpointInvocationChain chain = new SoapEndpointInvocationChain(new Object(),
189                 new SoapEndpointInterceptor[]{interceptorMock}, new String[]{headerActor}, true);
190 
191         boolean result = dispatcher.handleRequest(chain, context);
192         Assert.assertTrue("actor-specific header not understood", result);
193 
194         verify(interceptorMock);
195     }
196 
197     @Test
198     public void testProcessMustUnderstandHeadersForRoleSoap12() throws Exception {
199         MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
200         SOAPMessage request = messageFactory.createMessage();
201         SOAPHeaderElement header = request.getSOAPHeader()
202                 .addHeaderElement(new QName("http://www.springframework.org", "Header", "spring-ws"));
203         String headerRole = "http://www/springframework.org/role";
204         header.setRole(headerRole);
205         header.setMustUnderstand(true);
206         SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
207         MessageContext context = new DefaultMessageContext(new SaajSoapMessage(request), factory);
208         expect(interceptorMock.understands(isA(SoapHeaderElement.class))).andReturn(true);
209 
210         replay(interceptorMock);
211 
212         SoapEndpointInvocationChain chain = new SoapEndpointInvocationChain(new Object(),
213                 new SoapEndpointInterceptor[]{interceptorMock}, new String[]{headerRole}, true);
214 
215         boolean result = dispatcher.handleRequest(chain, context);
216         Assert.assertTrue("role-specific header not understood", result);
217 
218         verify(interceptorMock);
219     }
220 
221     @Test
222     public void testProcessNoHeader() throws Exception {
223         MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
224         SOAPMessage request = messageFactory.createMessage();
225         request.getSOAPHeader().detachNode();
226         SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
227         MessageContext context = new DefaultMessageContext(new SaajSoapMessage(request), factory);
228         replay(interceptorMock);
229 
230         SoapEndpointInvocationChain chain = new SoapEndpointInvocationChain(new Object(),
231                 new SoapEndpointInterceptor[]{interceptorMock}, new String[]{"role"}, true);
232 
233         boolean result = dispatcher.handleRequest(chain, context);
234         Assert.assertTrue("Invalid result", result);
235         verify(interceptorMock);
236     }
237 
238     @Test
239     public void testProcessMustUnderstandHeadersNoInterceptors() throws Exception {
240         MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
241         SOAPMessage request = messageFactory.createMessage();
242         SOAPHeaderElement header =
243                 request.getSOAPHeader().addHeaderElement(new QName("http://www.springframework.org", "Header"));
244         header.setActor(SOAPConstants.URI_SOAP_ACTOR_NEXT);
245         header.setMustUnderstand(true);
246         SoapMessageFactory factory = new SaajSoapMessageFactory(messageFactory);
247         MessageContext context = new DefaultMessageContext(new SaajSoapMessage(request), factory);
248         replay(interceptorMock);
249 
250         SoapEndpointInvocationChain chain = new SoapEndpointInvocationChain(new Object(), null);
251 
252         boolean result = dispatcher.handleRequest(chain, context);
253         Assert.assertFalse("Header understood", result);
254         verify(interceptorMock);
255     }
256 
257 }