Return-Path: Delivered-To: apmail-ws-axis-cvs-archive@www.apache.org Received: (qmail 67090 invoked from network); 18 Jul 2007 20:33:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 18 Jul 2007 20:33:17 -0000 Received: (qmail 74027 invoked by uid 500); 18 Jul 2007 20:33:03 -0000 Delivered-To: apmail-ws-axis-cvs-archive@ws.apache.org Received: (qmail 73921 invoked by uid 500); 18 Jul 2007 20:33:02 -0000 Mailing-List: contact axis-cvs-help@ws.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list axis-cvs@ws.apache.org Received: (qmail 73910 invoked by uid 500); 18 Jul 2007 20:33:02 -0000 Delivered-To: apmail-ws-axis2-cvs@ws.apache.org Received: (qmail 73907 invoked by uid 99); 18 Jul 2007 20:33:02 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 Jul 2007 13:33:02 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 Jul 2007 13:32:59 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 60C2D1A981A; Wed, 18 Jul 2007 13:32:39 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r557387 - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/dispatchers/ test-resources/ Date: Wed, 18 Jul 2007 20:32:39 -0000 To: axis2-cvs@ws.apache.org From: barrettj@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070718203239.60C2D1A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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"> + + + + + + + + @@ -265,6 +275,15 @@ + + + + + + + --------------------------------------------------------------------- To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org For additional commands, e-mail: axis-cvs-help@ws.apache.org