You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by ba...@apache.org on 2007/07/18 22:32:39 UTC

svn commit: r557387 - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/dispatchers/ test-resources/

Author: barrettj
Date: Wed Jul 18 13:32:38 2007
New Revision: 557387

URL: http://svn.apache.org/viewvc?view=rev&rev=557387
Log:
JAXWS dispatcher to check for mustUnderstand fault before invalid EPR fault.

Added:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandUtils.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandValidationDispatcher.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandChecker.java
    webservices/axis2/trunk/java/modules/jaxws/test-resources/axis2.xml

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandChecker.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandChecker.java?view=diff&rev=557387&r1=557386&r2=557387
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandChecker.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandChecker.java Wed Jul 18 13:32:38 2007
@@ -46,51 +46,7 @@
     public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
         // Get the list of headers for the roles we're acting in, then mark any we understand
         // as processed.
-        SOAPEnvelope envelope = msgContext.getEnvelope();
-        if (envelope.getHeader() == null) {
-            return InvocationResponse.CONTINUE;
-        }
-        
-        AxisOperation axisOperation = msgContext.getAxisOperation();
-        if (axisOperation == null) {
-            if (log.isDebugEnabled()) {
-                log.debug("Axis operation on messageContext is null: " + msgContext);
-            }
-            return InvocationResponse.CONTINUE;
-        }
-        
-        Parameter headerQNamesParameter = axisOperation.getParameter(OperationDescription.HEADER_PARAMETER_QNAMES);
-        if (headerQNamesParameter == null) {
-            if (log.isDebugEnabled()) {
-                log.debug("Parameter not on AxisOperation " + axisOperation + "; " 
-                          + OperationDescription.HEADER_PARAMETER_QNAMES);
-            }
-            return InvocationResponse.CONTINUE;
-        }
-        
-        ArrayList understoodHeaderQNames = (ArrayList) headerQNamesParameter.getValue();
-        if (understoodHeaderQNames == null || understoodHeaderQNames.isEmpty()) {
-            if (log.isDebugEnabled()) {
-                log.debug("Parameter value on AxisOperation is empty: "  + axisOperation + "; " 
-                          + OperationDescription.HEADER_PARAMETER_QNAMES);
-            }
-            return InvocationResponse.CONTINUE;
-        }
-
-        // Passing in null will get headers targeted for NEXT and ULTIMATE RECEIVER
-        Iterator headerBlocks = envelope.getHeader().getHeadersToProcess(null);
-        while (headerBlocks.hasNext()) {
-            SOAPHeaderBlock headerBlock = (SOAPHeaderBlock) headerBlocks.next();
-            QName headerQN = headerBlock.getQName();
-            if (understoodHeaderQNames.contains(headerQN)) {
-                headerBlock.setProcessed();
-                if (log.isDebugEnabled()) {
-                    log.debug("Header marked as processed by JAXWS MustUnderstandChecker: " 
-                              + headerQN);
-                }
-            }
-        }
-
+        MustUnderstandUtils.markUnderstoodHeaderParameters(msgContext);
         return InvocationResponse.CONTINUE;
     }
 }

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandUtils.java?view=auto&rev=557387
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandUtils.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandUtils.java Wed Jul 18 13:32:38 2007
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *      
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.dispatchers;
+
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPHeaderBlock;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.jaxws.description.OperationDescription;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.namespace.QName;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Static utility methods used in processing mustUnderstand headers relative to JAXWS.
+ */
+public class MustUnderstandUtils {
+    private static final Log log = LogFactory.getLog(MustUnderstandUtils.class);
+    
+    /**
+     * Mark all headers for JAXWS SEI method paramaters as understood.  Note that per the JAXWS
+     * 2.0 specification, a header is considered understood if it used by as a parameter for 
+     * any method on the SEI, not just the method corresponding to the incoming operation.  
+     * See Section 10.2.1 item 3.a which specifically says "mapped to method parameters
+     * in the service endpoint interface".
+     * 
+     * @param msgContext
+     */
+    public static void markUnderstoodHeaderParameters(MessageContext msgContext) {
+        if (msgContext == null) {
+            return;
+        }
+        
+        SOAPEnvelope envelope = msgContext.getEnvelope();
+        if (envelope.getHeader() == null) {
+            return;
+        }
+        
+        ArrayList understoodHeaderQNames = MustUnderstandUtils.getSEIHeaderParamaterList(msgContext);
+        if (understoodHeaderQNames == null) {
+            return;
+        }
+        
+        // Passing in null will get headers targeted for NEXT and ULTIMATE RECEIVER
+        Iterator headerBlocks = envelope.getHeader().getHeadersToProcess(null);
+        while (headerBlocks.hasNext()) {
+            SOAPHeaderBlock headerBlock = (SOAPHeaderBlock) headerBlocks.next();
+            QName headerQN = headerBlock.getQName();
+            if (understoodHeaderQNames.contains(headerQN)) {
+                headerBlock.setProcessed();
+                if (log.isDebugEnabled()) {
+                    log.debug("Header marked as processed by JAXWS MustUnderstandChecker: " 
+                              + headerQN);
+                }
+            }
+        }
+    }
+
+    /**
+     * Return an ArrayList of QNames corresponding to SOAP headers which map to method parameters
+     * for any methods on the corresponding SEI.
+     * 
+     * @param msgContext
+     * @return ArrayList of QNames for all header parameters for an SEI.  The list may be empty but
+     *   will not be null.
+     */
+    public static ArrayList getSEIHeaderParamaterList(MessageContext msgContext) {
+        ArrayList returnList = new ArrayList();
+        // Build a list of understood headers for all the operations under the service
+        AxisService axisService = msgContext.getAxisService();
+        if (log.isDebugEnabled()) {
+            log.debug("Building list of understood headers for all operations under " + axisService);
+        }
+        if (axisService != null) {
+            Iterator operationIterator = axisService.getOperations();
+            if (operationIterator != null) {
+                while (operationIterator.hasNext()) {
+                    AxisOperation operation = (AxisOperation) operationIterator.next();
+                    ArrayList understoodHeaders = getSEIMethodHeaderParameterList(operation);
+                    if (log.isDebugEnabled()) {
+                        log.debug("Adding headers from operation " + operation + "; headers = "
+                                  + understoodHeaders);
+                    }
+                    if (understoodHeaders != null && !understoodHeaders.isEmpty()) {
+                        returnList.addAll(understoodHeaders);
+                    }
+                }
+            }
+        }
+        return returnList;
+    }
+    
+    /**
+     * Return an ArrayList of QNames corresponding to SOAP headers which map to method parameters
+     * for a specific operation.
+     * 
+     * @param axisOperation
+     * @return ArrayList of header QNames for all header paramters on an operation, or null if none.
+     */
+    public static ArrayList getSEIMethodHeaderParameterList(AxisOperation axisOperation) {
+        
+        Parameter headerQNamesParameter = axisOperation.getParameter(OperationDescription.HEADER_PARAMETER_QNAMES);
+        if (headerQNamesParameter == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("Parameter not on AxisOperation " + axisOperation + "; " 
+                          + OperationDescription.HEADER_PARAMETER_QNAMES);
+            }
+            return null;
+        }
+
+        ArrayList understoodHeaderQNames = (ArrayList) headerQNamesParameter.getValue();
+        if (understoodHeaderQNames == null || understoodHeaderQNames.isEmpty()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Parameter value on AxisOperation is empty: "  + axisOperation + "; " 
+                          + OperationDescription.HEADER_PARAMETER_QNAMES);
+            }
+            return null;
+        }
+
+        return understoodHeaderQNames;
+    }
+    
+}

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandValidationDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandValidationDispatcher.java?view=auto&rev=557387
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandValidationDispatcher.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/dispatchers/MustUnderstandValidationDispatcher.java Wed Jul 18 13:32:38 2007
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *      
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.dispatchers;
+
+import org.apache.axiom.soap.SOAP11Constants;
+import org.apache.axiom.soap.SOAP12Constants;
+import org.apache.axiom.soap.SOAPConstants;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPHeaderBlock;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.engine.AbstractDispatcher;
+import org.apache.axis2.engine.Handler.InvocationResponse;
+import org.apache.axis2.i18n.Messages;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.namespace.QName;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Do JAXWS MustUnderstand header processing per the JAXWS 2.0 specification.  This checks for
+ * a specific compliance situation where a non-existant operation with mustUnderstood headers 
+ * that are not understood must throw a mustUnderstandFault rather than an invalid EPR exception.
+ * 
+ *  Note that this handler should be inserted in the inbound dispather chains so that the
+ *  Dispatcher checkPostConditions does not throw the invalid EPR fault if the operation is null.
+ */
+public class MustUnderstandValidationDispatcher extends AbstractDispatcher {
+    private static final Log log = LogFactory.getLog(MustUnderstandValidationDispatcher.class);
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.engine.AbstractDispatcher#findOperation(org.apache.axis2.description.AxisService, org.apache.axis2.context.MessageContext)
+     */
+    @Override
+    public AxisOperation findOperation(AxisService service, MessageContext messageContext)
+            throws AxisFault {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.engine.AbstractDispatcher#findService(org.apache.axis2.context.MessageContext)
+     */
+    @Override
+    public AxisService findService(MessageContext messageContext) throws AxisFault {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.engine.AbstractDispatcher#initDispatcher()
+     */
+    @Override
+    public void initDispatcher() {
+    }
+
+    public InvocationResponse invoke(MessageContext msgctx) throws AxisFault {
+        AxisService axisService = msgctx.getAxisService();
+        AxisOperation axisOperation = msgctx.getAxisOperation();
+        
+        if (log.isDebugEnabled()) {
+            log.debug("JAXWS MustUnderstandValidationDispatcher.invoke on AxisService " 
+                      + axisService
+                      + "; AxisOperation " + axisOperation);
+        }
+        // REVIEW: This will only check do the mustUnderstand checking if the operation is null
+        // That is because JAXWS compliance requires we throw a mustUnderstand fault even if the operation is
+        // invalid.  If the operation is valid, then further mustUnderstand processing will be done
+        // by the JAXWS MustUnderstandChecker handler. 
+        if (axisService != null && axisOperation == null) {
+            checkMustUnderstand(msgctx);
+        }
+        return InvocationResponse.CONTINUE;
+    }
+
+    private boolean checkMustUnderstand(MessageContext msgContext) throws AxisFault {
+        boolean checksPass = true;
+
+        SOAPEnvelope envelope = msgContext.getEnvelope();
+        if (envelope.getHeader() == null) {
+            return checksPass;
+        }
+        
+        // First mark all the headers JAXWS would understand to make sure we don't throw
+        // a mustUnderstand fault inappropriately for those.
+        MustUnderstandUtils.markUnderstoodHeaderParameters(msgContext);
+
+        // Now check all the headers and throw the mustUnderstandFault if any not understood.
+        // REVIEW: Note that QoSes that would run after the dispatch phase will not have marked
+        // their headers yet.
+
+        Iterator headerBlocks = envelope.getHeader().getHeadersToProcess(null);
+        while (headerBlocks.hasNext()) {
+            SOAPHeaderBlock headerBlock = (SOAPHeaderBlock) headerBlocks.next();
+            if (headerBlock.isProcessed() || !headerBlock.getMustUnderstand()) {
+                continue;
+            }
+
+            QName faultQName = headerBlock.getVersion().getMustUnderstandFaultCode();
+            throw new AxisFault(Messages.getMessage("mustunderstandfailed",
+                                                    headerBlock.getNamespace().getNamespaceURI(),
+                                                    headerBlock.getLocalName()), faultQName);
+        }
+        return checksPass;
+    }
+
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/test-resources/axis2.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test-resources/axis2.xml?view=diff&rev=557387&r1=557386&r2=557387
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test-resources/axis2.xml (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test-resources/axis2.xml Wed Jul 18 13:32:38 2007
@@ -211,6 +211,16 @@
                      class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher">
                 <order phase="Dispatch"/>
             </handler>
+
+            <handler name="GenericProviderDispatcher"
+                     class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher">
+                <order phase="Dispatch"/>
+            </handler>
+
+            <handler name="MustUnderstandValidationDispatcher"
+                     class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher">
+                <order phase="Dispatch"/>
+            </handler>
         </phase>
         <phase name="RMPhase"/>
         <!--  System pre defined phases       -->
@@ -265,6 +275,15 @@
 
             <handler name="HTTPLocationBasedDispatcher"
                      class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher">
+                <order phase="Dispatch"/>
+            </handler>
+            <handler name="GenericProviderDispatcher"
+                     class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher">
+                <order phase="Dispatch"/>
+            </handler>
+
+            <handler name="MustUnderstandValidationDispatcher"
+                     class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher">
                 <order phase="Dispatch"/>
             </handler>
         </phase>



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org