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