You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2009/07/30 23:04:56 UTC

svn commit: r799439 - in /cxf/trunk: rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ systests/src/test/java/org/apache/cxf/systest/outofband/header/

Author: dkulp
Date: Thu Jul 30 21:04:55 2009
New Revision: 799439

URL: http://svn.apache.org/viewvc?rev=799439&view=rev
Log:
Allow and endpoint to specify what headers it can process itself thus
allowing other mustUnderstands to be caught before invoke

Modified:
    cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/MustUnderstandInterceptor.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/OOBHeaderTest.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/Server.java

Modified: cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/MustUnderstandInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/MustUnderstandInterceptor.java?rev=799439&r1=799438&r2=799439&view=diff
==============================================================================
--- cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/MustUnderstandInterceptor.java (original)
+++ cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/MustUnderstandInterceptor.java Thu Jul 30 21:04:55 2009
@@ -20,7 +20,10 @@
 package org.apache.cxf.binding.soap.interceptor;
 
 import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.ResourceBundle;
 import java.util.Set;
@@ -37,6 +40,7 @@
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.headers.Header;
+import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.interceptor.Interceptor;
 import org.apache.cxf.phase.Phase;
@@ -63,22 +67,62 @@
         Set<Header> ultimateReceiverHeaders = new HashSet<Header>();
         Set<QName> mustUnderstandQNames = new HashSet<QName>();
 
+        initServiceSideInfo(mustUnderstandQNames, soapMessage, serviceRoles);
         buildMustUnderstandHeaders(mustUnderstandHeaders, soapMessage,
                                    serviceRoles, ultimateReceiverHeaders);
-        initServiceSideInfo(mustUnderstandQNames, soapMessage, serviceRoles);
         
-        checkUnderstand(mustUnderstandHeaders, mustUnderstandQNames,
-                             notUnderstandHeaders);
+        checkUnderstand(mustUnderstandHeaders, mustUnderstandQNames, notUnderstandHeaders);
+        
         if (!notUnderstandHeaders.isEmpty()) {
             throw new SoapFault(new Message("MUST_UNDERSTAND", BUNDLE, notUnderstandHeaders),
                             soapVersion.getMustUnderstand());
         }
         if (!ultimateReceiverHeaders.isEmpty() && !isRequestor(soapMessage)) {
-            soapMessage.getInterceptorChain()
-                .add(new UltimateReceiverMustUnderstandInterceptor(mustUnderstandQNames));
+            checkUltimateReceiverHeaders(ultimateReceiverHeaders, mustUnderstandQNames, soapMessage);
         }
     }
 
+    private void checkUltimateReceiverHeaders(Set<Header> ultimateReceiverHeaders,
+                                              Set<QName> mustUnderstandQNames, 
+                                              SoapMessage soapMessage) {
+        soapMessage.getInterceptorChain()
+            .add(new UltimateReceiverMustUnderstandInterceptor(mustUnderstandQNames));
+        Object o = soapMessage.getContextualProperty("endpoint.handles.headers");
+        if (o == null) {
+            //The default here really should be to make o = "" and process
+            //so any mustUnderstands are kill immediately. That will break
+            //existing apps though.  Thus, it's a migration issue.
+            return;
+        }
+        Collection<Object> o2;
+        if (o instanceof Collection) {
+            o2 = CastUtils.cast((Collection<?>)o);
+        } else {
+            o2 = Collections.singleton(o);
+        }
+        for (Object obj : o2) {
+            QName qn;
+            if (obj instanceof QName) {
+                qn = (QName)obj;
+            } else {
+                qn = QName.valueOf((String)obj);
+            }
+            Iterator<Header> hit = ultimateReceiverHeaders.iterator();
+            while (hit.hasNext()) {
+                if (qn.equals(hit.next().getName())) {
+                    hit.remove();
+                }
+            }
+        }
+        if (!ultimateReceiverHeaders.isEmpty()) {
+            Set<QName> notFound = new HashSet<QName>();
+            for (Header h : ultimateReceiverHeaders) {
+                notFound.add(h.getName());
+            }
+            throw new SoapFault(new Message("MUST_UNDERSTAND", BUNDLE, notFound),
+                                soapMessage.getVersion().getMustUnderstand());
+        }
+    }
     private void initServiceSideInfo(Set<QName> mustUnderstandQNames, SoapMessage soapMessage,
                     Set<URI> serviceRoles) {
 

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/OOBHeaderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/OOBHeaderTest.java?rev=799439&r1=799438&r2=799439&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/OOBHeaderTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/OOBHeaderTest.java Thu Jul 30 21:04:55 2009
@@ -34,6 +34,8 @@
 import javax.xml.namespace.QName;
 import javax.xml.ws.BindingProvider;
 import javax.xml.ws.Holder;
+import javax.xml.ws.soap.SOAPFaultException;
+
 import org.w3c.dom.Node;
 
 import org.apache.cxf.BusFactory;
@@ -79,7 +81,7 @@
         assertTrue("server did not launch correctly", launchServer(Server.class, true));
     }
     
-    private void addOutOfBoundHeader(PutLastTradedPricePortType portType, boolean invalid) {
+    private void addOutOfBoundHeader(PutLastTradedPricePortType portType, boolean invalid, boolean mu) {
         InvocationHandler handler  = Proxy.getInvocationHandler(portType);
         BindingProvider  bp = null;
 
@@ -97,7 +99,7 @@
                         new QName(TEST_HDR_NS, TEST_HDR_REQUEST_ELEM), 
                         ob, 
                         new JAXBDataBinding(ob.getClass()));
-                hdr.setMustUnderstand(true);
+                hdr.setMustUnderstand(mu);
 
                 List<Header> holder = new ArrayList<Header>();
                 holder.add(hdr);
@@ -180,18 +182,52 @@
         TradePriceData priceData = new TradePriceData();
         priceData.setTickerPrice(1.0f);
         priceData.setTickerSymbol("CELTIX");
-        Holder<TradePriceData> holder = new Holder<TradePriceData>(priceData);
-        
-        addOutOfBoundHeader(putLastTradedPrice, false);
-        putLastTradedPrice.sayHi(holder);
-        checkReturnedOOBHeader(putLastTradedPrice);
+
+        assertTrue(check(0, putLastTradedPrice, false, true, priceData));
+        assertFalse(check(1, putLastTradedPrice, false, true, priceData));
+        assertTrue(check(2, putLastTradedPrice, false, true, priceData));        
+
+        assertFalse(check(0, putLastTradedPrice, true, true, priceData));
+        assertFalse(check(1, putLastTradedPrice, true, true, priceData));
+        assertFalse(check(2, putLastTradedPrice, true, true, priceData));        
+
+        assertTrue(check(0, putLastTradedPrice, false, false, priceData));
+        assertTrue(check(1, putLastTradedPrice, false, false, priceData));
+        assertTrue(check(2, putLastTradedPrice, false, false, priceData));        
+
+        assertTrue(check(0, putLastTradedPrice, true, false, priceData));
+        assertTrue(check(1, putLastTradedPrice, true, false, priceData));
+        assertTrue(check(2, putLastTradedPrice, true, false, priceData));        
+    }
+    
+    private boolean check(int i, PutLastTradedPricePortType putLastTradedPrice, 
+                       boolean invalid, boolean mu,
+                       TradePriceData priceData) {
+        String address = "";
+        switch (i) {
+        case 0:
+            address = "http://localhost:9107/SOAPDocLitBareService/SoapPort";
+            break;
+        case 1:
+            address = "http://localhost:9107/SOAPDocLitBareService/SoapPortNoHeader";
+            break;
+        default:
+            address = "http://localhost:9107/SOAPDocLitBareService/SoapPortHeader";                
+        }
+        ((BindingProvider)putLastTradedPrice).getRequestContext()
+            .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
         
-        addOutOfBoundHeader(putLastTradedPrice, true);
+        Holder<TradePriceData> holder = new Holder<TradePriceData>(priceData);
         try {
+            addOutOfBoundHeader(putLastTradedPrice, invalid, mu);
             putLastTradedPrice.sayHi(holder);
-            fail("mustUnderstand header should not have been processed");
-        } catch (Exception ex) {
-            assertTrue(ex.getMessage(), ex.getMessage().contains("MustUnderstand"));
+            checkReturnedOOBHeader(putLastTradedPrice);
+            return true;
+        } catch (SOAPFaultException ex) {
+            if (ex.getMessage().contains("MustUnderstand")) {
+                return false;
+            }
+            throw ex;
         }
     }
 }

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/Server.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/Server.java?rev=799439&r1=799438&r2=799439&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/Server.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/outofband/header/Server.java Thu Jul 30 21:04:55 2009
@@ -49,14 +49,32 @@
         // Register expected Headers (namespace, element and class type mapping)
         
         Object implementor = new OOBHdrServiceImpl();
-        String address = "http://localhost:9107/SOAPDocLitBareService/SoapPort";      
         Endpoint ep = Endpoint.create(implementor);
         Map<String, Object> props = new HashMap<String, Object>(2);
         props.put(Endpoint.WSDL_SERVICE, new QName("http://apache.org/hello_world_doc_lit_bare", 
                                                    "SOAPService"));
         props.put(Endpoint.WSDL_PORT, new QName("http://apache.org/hello_world_doc_lit_bare", "SoapPort"));
         ep.setProperties(props);
-        ep.publish(address);
+        ep.publish("http://localhost:9107/SOAPDocLitBareService/SoapPort");
+        
+        ep = Endpoint.create(implementor);
+        props = new HashMap<String, Object>(2);
+        props.put(Endpoint.WSDL_SERVICE, new QName("http://apache.org/hello_world_doc_lit_bare", 
+                                                   "SOAPService"));
+        props.put(Endpoint.WSDL_PORT, new QName("http://apache.org/hello_world_doc_lit_bare", "SoapPort"));
+        props.put("endpoint.handles.headers", "");
+        ep.setProperties(props);
+        ep.publish("http://localhost:9107/SOAPDocLitBareService/SoapPortNoHeader");
+        
+        ep = Endpoint.create(implementor);
+        props = new HashMap<String, Object>(2);
+        props.put(Endpoint.WSDL_SERVICE, new QName("http://apache.org/hello_world_doc_lit_bare", 
+                                                   "SOAPService"));
+        props.put(Endpoint.WSDL_PORT, new QName("http://apache.org/hello_world_doc_lit_bare", "SoapPort"));
+        props.put("endpoint.handles.headers", "{http://cxf.apache.org/outofband/Header}outofbandHeader");
+        ep.setProperties(props);
+        ep.publish("http://localhost:9107/SOAPDocLitBareService/SoapPortHeader");
+
     }