Author: dims
Date: Fri Apr 14 13:52:58 2006
New Revision: 394199

URL: http://svn.apache.org/viewcvs?rev=394199&view=rev
Log:
Fix for AXIS2-571 - WS-Addressing - InvalidCardinality processing incorrect 
with multiple MessageID elements

from David Illsley


Added:
    
webservices/axis2/trunk/java/modules/addressing/test-resources/invalidCardinalityReplyToMessage.xml
Modified:
    
webservices/axis2/trunk/java/modules/addressing/src/org/apache/axis2/handlers/addressing/AddressingInHandler.java
    
webservices/axis2/trunk/java/modules/addressing/test/org/apache/axis2/handlers/addressing/AddressingInHandlerTest.java

Modified: 
webservices/axis2/trunk/java/modules/addressing/src/org/apache/axis2/handlers/addressing/AddressingInHandler.java
URL: 
http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/addressing/src/org/apache/axis2/handlers/addressing/AddressingInHandler.java?rev=394199&r1=394198&r2=394199&view=diff
==============================================================================
--- 
webservices/axis2/trunk/java/modules/addressing/src/org/apache/axis2/handlers/addressing/AddressingInHandler.java
 (original)
+++ 
webservices/axis2/trunk/java/modules/addressing/src/org/apache/axis2/handlers/addressing/AddressingInHandler.java
 Fri Apr 14 13:52:58 2006
@@ -79,75 +79,94 @@
                                                    ArrayList 
addressingHeaders, String addressingNamespace) throws AxisFault {
 
         Options messageContextOptions = messageContext.getOptions();
-        Map alreadyFoundAddrHeader = new HashMap(7); // there are seven 
frequently used WS-A headers
-
+        
+        ArrayList checkedHeaderNames = new ArrayList(7); // Up to 7 header 
names to be recorded
+        ArrayList duplicateHeaderNames = new ArrayList(1); // Normally will 
not be used for more than 1 header
+        
+        // Per the SOAP Binding spec "headers with an incorrect cardinality 
MUST NOT be used" So these variables
+        // are used to keep track of invalid cardinality headers so they are 
not deserialised.
+        boolean ignoreTo = false, ignoreFrom = false, ignoreReplyTo = false, 
ignoreFaultTo = false, ignoreMessageID = false, ignoreAction = false, 
ignoreRelatesTo = false; 
+        
         // First pass just check for duplicates
         Iterator addressingHeadersIt = addressingHeaders.iterator();
         while (addressingHeadersIt.hasNext()) {
             SOAPHeaderBlock soapHeaderBlock = (SOAPHeaderBlock) 
addressingHeadersIt.next();
             if 
(SOAP12Constants.SOAP_ROLE_NONE.equals(soapHeaderBlock.getRole()))
                 continue;
-            if (WSA_TO.equals(soapHeaderBlock.getLocalName())) {
-                checkDuplicateHeaders(WSA_TO, messageContext, 
alreadyFoundAddrHeader);
-            } else if (WSA_FROM.equals(soapHeaderBlock.getLocalName())) {
-                checkDuplicateHeaders(WSA_FROM, messageContext, 
alreadyFoundAddrHeader);
-            } else if (WSA_REPLY_TO.equals(soapHeaderBlock.getLocalName())) {
-                checkDuplicateHeaders(WSA_REPLY_TO, messageContext, 
alreadyFoundAddrHeader);
-            } else if (WSA_FAULT_TO.equals(soapHeaderBlock.getLocalName())) {
-                checkDuplicateHeaders(WSA_FAULT_TO, messageContext, 
alreadyFoundAddrHeader);
-            } else if (WSA_MESSAGE_ID.equals(soapHeaderBlock.getLocalName())) {
-                checkDuplicateHeaders(WSA_MESSAGE_ID, messageContext, 
alreadyFoundAddrHeader);
-            } else if (WSA_ACTION.equals(soapHeaderBlock.getLocalName())) {
-                checkDuplicateHeaders(WSA_ACTION, messageContext, 
alreadyFoundAddrHeader);
-            } else if (WSA_RELATES_TO.equals(soapHeaderBlock.getLocalName())) {
-                checkDuplicateHeaders(WSA_RELATES_TO, messageContext, 
alreadyFoundAddrHeader);
-            }
-        }
 
+               if (WSA_TO.equals(soapHeaderBlock.getLocalName())) {
+                   ignoreTo = checkDuplicateHeaders(WSA_TO, 
checkedHeaderNames, duplicateHeaderNames);
+               } else if (WSA_FROM.equals(soapHeaderBlock.getLocalName())) {
+                   ignoreFrom = checkDuplicateHeaders(WSA_FROM, 
checkedHeaderNames, duplicateHeaderNames);
+               } else if (WSA_REPLY_TO.equals(soapHeaderBlock.getLocalName())) 
{
+                   ignoreReplyTo = checkDuplicateHeaders(WSA_REPLY_TO, 
checkedHeaderNames, duplicateHeaderNames);
+               } else if (WSA_FAULT_TO.equals(soapHeaderBlock.getLocalName())) 
{
+                   ignoreFaultTo = checkDuplicateHeaders(WSA_FAULT_TO, 
checkedHeaderNames, duplicateHeaderNames);
+               } else if 
(WSA_MESSAGE_ID.equals(soapHeaderBlock.getLocalName())) {
+                   ignoreMessageID = checkDuplicateHeaders(WSA_MESSAGE_ID, 
checkedHeaderNames, duplicateHeaderNames);
+               } else if (WSA_ACTION.equals(soapHeaderBlock.getLocalName())) {
+                   ignoreAction = checkDuplicateHeaders(WSA_ACTION, 
checkedHeaderNames, duplicateHeaderNames);
+               } else if 
(WSA_RELATES_TO.equals(soapHeaderBlock.getLocalName())) {
+                   ignoreRelatesTo = checkDuplicateHeaders(WSA_RELATES_TO, 
checkedHeaderNames, duplicateHeaderNames);
+               }
+        }
+        
         // Now extract information
         Iterator addressingHeadersIt2 = addressingHeaders.iterator();
         while (addressingHeadersIt2.hasNext()) {
             SOAPHeaderBlock soapHeaderBlock = (SOAPHeaderBlock) 
addressingHeadersIt2.next();
             if 
(SOAP12Constants.SOAP_ROLE_NONE.equals(soapHeaderBlock.getRole()))
                 continue;
-            if (WSA_TO.equals(soapHeaderBlock.getLocalName())) {
+            
+            if (WSA_TO.equals(soapHeaderBlock.getLocalName()) && !ignoreTo) {
                 extractToEPRInformation(soapHeaderBlock, 
messageContextOptions, header);
-            } else if (WSA_FROM.equals(soapHeaderBlock.getLocalName())) {
+            } else if (WSA_FROM.equals(soapHeaderBlock.getLocalName()) && 
!ignoreFrom) {
                 extractFromEPRInformation(messageContextOptions, 
soapHeaderBlock, addressingNamespace);
-            } else if (WSA_REPLY_TO.equals(soapHeaderBlock.getLocalName())) {
+            } else if (WSA_REPLY_TO.equals(soapHeaderBlock.getLocalName()) && 
!ignoreReplyTo) {
                 extractReplyToEPRInformation(messageContextOptions, 
soapHeaderBlock, addressingNamespace);
-            } else if (WSA_FAULT_TO.equals(soapHeaderBlock.getLocalName())) {
+            } else if (WSA_FAULT_TO.equals(soapHeaderBlock.getLocalName()) && 
!ignoreFaultTo) {
                 extractFaultToEPRInformation(messageContextOptions, 
soapHeaderBlock, addressingNamespace);
-            } else if (WSA_MESSAGE_ID.equals(soapHeaderBlock.getLocalName())) {
+            } else if (WSA_MESSAGE_ID.equals(soapHeaderBlock.getLocalName()) 
&& !ignoreMessageID) {
                 messageContextOptions.setMessageId(soapHeaderBlock.getText());
                 soapHeaderBlock.setProcessed();
-            } else if (WSA_ACTION.equals(soapHeaderBlock.getLocalName())) {
+            } else if (WSA_ACTION.equals(soapHeaderBlock.getLocalName()) && 
!ignoreAction) {
                 messageContextOptions.setAction(soapHeaderBlock.getText());
                 soapHeaderBlock.setProcessed();
-            } else if (WSA_RELATES_TO.equals(soapHeaderBlock.getLocalName())) {
+            } else if (WSA_RELATES_TO.equals(soapHeaderBlock.getLocalName()) 
&& !ignoreRelatesTo) {
                 extractRelatesToInformation(soapHeaderBlock, 
addressingNamespace, messageContextOptions);
             }
         }
 
-        // check for the presense of madatory addressing headers
-        checkForMandatoryHeaders(alreadyFoundAddrHeader, messageContext);
+        // Now that all the valid wsa headers have been read, throw an 
exception if there was an invalid cardinality
+        // This means that if for example there are multiple MessageIDs and a 
FaultTo, the FaultTo will be respected.
+        if(!duplicateHeaderNames.isEmpty()){
+               // Simply choose the first problem header we came across as we 
can only fault for one of them.
+               
throwFault(messageContext,(String)duplicateHeaderNames.get(0),Final.FAULT_INVALID_HEADER,
 Final.FAULT_INVALID_CARDINALITY);
+        }
+        
+        // check for the presence of madatory addressing headers
+        checkForMandatoryHeaders(checkedHeaderNames, messageContext);
 
         return messageContextOptions;
     }
 
-    private void checkForMandatoryHeaders(Map alreadyFoundAddrHeader, 
MessageContext messageContext) throws AxisFault {
-        if (alreadyFoundAddrHeader.get(WSA_ACTION) == null) {
+    private void checkForMandatoryHeaders(ArrayList alreadyFoundAddrHeader, 
MessageContext messageContext) throws AxisFault {
+        if (!alreadyFoundAddrHeader.contains(WSA_ACTION)) {
             throwFault(messageContext, WSA_ACTION, 
Final.FAULT_ADDRESSING_HEADER_REQUIRED, null);
         } 
     }
 
-    private boolean checkDuplicateHeaders(String addressingHeaderName, 
MessageContext messageContext, Map alreadyFoundAddressingHeaders) throws 
AxisFault {
-        if (alreadyFoundAddressingHeaders.get(addressingHeaderName) != null) {
-            throwFault(messageContext, addressingHeaderName, 
Final.FAULT_INVALID_HEADER, Final.FAULT_INVALID_CARDINALITY);
-        } else {
-            alreadyFoundAddressingHeaders.put(addressingHeaderName, 
addressingHeaderName);
-        }
-        return false;
+    private boolean checkDuplicateHeaders(String addressingHeaderName, 
ArrayList checkedHeaderNames, ArrayList duplicateHeaderNames) {//throws 
AxisFault {
+       // If the header name has been seen before then we should return true 
and add it to the list
+       // of duplicate header names. Otherwise it is the first time we've seen 
the header so add it
+       // to the checked liat and return false. 
+       boolean shouldIgnore = 
checkedHeaderNames.contains(addressingHeaderName);
+       if(shouldIgnore){
+               duplicateHeaderNames.add(addressingHeaderName);
+       }else{
+               checkedHeaderNames.add(addressingHeaderName);
+       }
+       return shouldIgnore;
     }
 
     private void throwFault(MessageContext messageContext, String 
addressingHeaderName, String faultCode, String faultSubCode) throws AxisFault {
@@ -159,9 +178,8 @@
 
         if(messageContext.getMessageID() != null) {
             
faultInformation.put(AddressingConstants.WSA_RELATES_TO,messageContext.getMessageID());
-        } else {
-            
faultInformation.put(AddressingConstants.WSA_RELATES_TO,getMessageID(messageContext));
         }
+        
         faultInformation.put(Final.FAULT_HEADER_PROB_HEADER_QNAME, 
WSA_DEFAULT_PREFIX + ":" + addressingHeaderName);
         faultInformation.put(Final.WSA_FAULT_ACTION, Final.WSA_FAULT_ACTION);
         if (!messageContext.isSOAP11()) {
@@ -169,23 +187,6 @@
         }
         throw new AxisFault("A header representing a Message Addressing 
Property is not valid and the message cannot be processed", WSA_DEFAULT_PREFIX 
+ ":" + faultCode);
     }
-
-    private String getMessageID(MessageContext msgContext) {
-        SOAPHeader header = msgContext.getEnvelope().getHeader();
-        if (header != null) {
-            ArrayList addressingHeaders = 
header.getHeaderBlocksWithNSURI(addressingNamespace);
-            Iterator addressingHeadersIt = addressingHeaders.iterator();
-            while (addressingHeadersIt.hasNext()) {
-                SOAPHeaderBlock soapHeaderBlock = (SOAPHeaderBlock) 
addressingHeadersIt.next();
-                if (WSA_MESSAGE_ID.equals(soapHeaderBlock.getLocalName())) {
-                    return soapHeaderBlock.getText();
-                }
-            }
-        }
-        return null;
-    }
-
-
 
     protected abstract void extractToEprReferenceParameters(EndpointReference 
toEPR, SOAPHeader header);
 

Added: 
webservices/axis2/trunk/java/modules/addressing/test-resources/invalidCardinalityReplyToMessage.xml
URL: 
http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/addressing/test-resources/invalidCardinalityReplyToMessage.xml?rev=394199&view=auto
==============================================================================
--- 
webservices/axis2/trunk/java/modules/addressing/test-resources/invalidCardinalityReplyToMessage.xml
 (added)
+++ 
webservices/axis2/trunk/java/modules/addressing/test-resources/invalidCardinalityReplyToMessage.xml
 Fri Apr 14 13:52:58 2006
@@ -0,0 +1,59 @@
+<!--
+ Copyright 2004,2005 The Apache Software Foundation.
+ Copyright 2006 International Business Machines Corp.
+ 
+ Licensed 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.
+ -->
+<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";
+                  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
+                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+                  xmlns:wsa="http://www.w3.org/2005/08/addressing";>
+    <soapenv:Header xmlns:fabrikam="http://example.com/fabrikam"; 
xmlns:axis2="http://ws.apache.org/namespaces/axis2";>
+        <wsa:MessageID soapenv:mustUnderstand="0">
+            uuid:920C5190-0B8F-11D9-8CED-F22EDEEBF7E5</wsa:MessageID>
+        <wsa:To 
soapenv:mustUnderstand="0">http://localhost:8081/axis/services/BankPort</wsa:To>
+        <wsa:From soapenv:mustUnderstand="0">
+            <wsa:Address>
+                http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
+        </wsa:From>
+        <axis2:ParamOne 
wsa:IsReferenceParameter='true'>123456789</axis2:ParamOne>
+        <axis2:ParamTwo 
wsa:IsReferenceParameter='true'>ABCDEFG</axis2:ParamTwo>
+        <wsa:ReplyTo>
+            <wsa:Address>http://example.com/fabrikam/acct</wsa:Address>
+            <wsa:ReferenceParameters>
+                <fabrikam:CustomerKey>123456789</fabrikam:CustomerKey>
+                <fabrikam:ShoppingCart>ABCDEFG</fabrikam:ShoppingCart>
+            </wsa:ReferenceParameters>
+        </wsa:ReplyTo>
+        <wsa:Action>http://ws.apache.org/tests/action</wsa:Action>
+        <wsa:ReplyTo>
+            <wsa:Address>http://example.com/fabrikam/acct2</wsa:Address>
+            <wsa:ReferenceParameters>
+                <fabrikam:CustomerKey>123456789</fabrikam:CustomerKey>
+            </wsa:ReferenceParameters>
+        </wsa:ReplyTo>
+        <wsa:FaultTo>
+            <wsa:Address>http://example.com/fabrikam/fault</wsa:Address>
+        </wsa:FaultTo>
+    </soapenv:Header>
+    <soapenv:Body>
+        <ns1:getBalance 
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";
+                        
xmlns:ns1="http://localhost:8081/axis/services/BankPort";>
+            <accountNo href="#id0"/>
+        </ns1:getBalance>
+        <multiRef id="id0" soapenc:root="0"
+                  
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";
+                  xsi:type="xsd:int" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/";>
+            1001</multiRef>
+    </soapenv:Body>
+</soapenv:Envelope>
\ No newline at end of file

Modified: 
webservices/axis2/trunk/java/modules/addressing/test/org/apache/axis2/handlers/addressing/AddressingInHandlerTest.java
URL: 
http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/addressing/test/org/apache/axis2/handlers/addressing/AddressingInHandlerTest.java?rev=394199&r1=394198&r2=394199&view=diff
==============================================================================
--- 
webservices/axis2/trunk/java/modules/addressing/test/org/apache/axis2/handlers/addressing/AddressingInHandlerTest.java
 (original)
+++ 
webservices/axis2/trunk/java/modules/addressing/test/org/apache/axis2/handlers/addressing/AddressingInHandlerTest.java
 Fri Apr 14 13:52:58 2006
@@ -20,6 +20,7 @@
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.soap.SOAPHeader;
 import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+import org.apache.axis2.AxisFault;
 import org.apache.axis2.addressing.AddressingConstants;
 import org.apache.axis2.addressing.EndpointReference;
 import org.apache.axis2.client.Options;
@@ -37,10 +38,12 @@
     TestUtil testUtil = new TestUtil();
     private static final String testFileName = "soapmessage.xml";
     private static final String wsaFinalTestFile = "soapWithWSAFinalInfo.xml";
+    private static final String invalidCardinalityTestFile = 
"invalidCardinalityReplyToMessage.xml";
 
     private String action = "http://ws.apache.org/tests/action";;
     private String messageID = "uuid:920C5190-0B8F-11D9-8CED-F22EDEEBF7E5";
     private String fromAddress = 
"http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous";;
+    private String faultAddress = "http://example.com/fabrikam/fault";;
 
     /**
      * @param testName
@@ -87,11 +90,49 @@
             fail(" An Exception has occured " + e.getMessage());
         }
     }
+    
+    public void 
testExtractAddressingInformationFromHeadersInvalidCardinality() {
+        try {
+            StAXSOAPModelBuilder omBuilder = 
testUtil.getOMBuilder(invalidCardinalityTestFile);
+
+            SOAPHeader header = ((SOAPEnvelope) 
omBuilder.getDocumentElement()).getHeader();
+            MessageContext mc = new MessageContext();
+            try{
+               inHandler.extractAddressingInformation(header,
+                               mc,
+                            header.getHeaderBlocksWithNSURI(
+                                    AddressingConstants.Final.WSA_NAMESPACE),
+                            AddressingConstants.Final.WSA_NAMESPACE);
+
+            
+               fail("An AxisFault should have been thrown due to 2 wsa:ReplyTo 
headers.");
+            }catch(AxisFault af){
+               assertNull("No ReplyTo should be set on the MessageContext", 
mc.getReplyTo());
+               assertFaultEPR(mc.getFaultTo());
+               assertEquals("WSAAction property is not correct",
+                               mc.getWSAAction(),
+                        action);
+                assertEquals("MessageID property is not correct",
+                               mc.getMessageID().trim(),
+                        messageID.trim());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.info(e.getMessage());
+            fail(" An Exception has occured " + e.getMessage());
+        }
+    }
 
     private void assertFromEPR(EndpointReference fromEPR) {
-        assertEquals("Address in EPR is not valid",
+        assertEquals("Address in From EPR is not valid",
                 fromEPR.getAddress().trim(),
                 fromAddress.trim());
+    }
+    
+    private void assertFaultEPR(EndpointReference faultEPR) {
+        assertEquals("Address in FaultTo EPR is not valid",
+                       faultEPR.getAddress().trim(),
+                faultAddress.trim());
     }
 
     public void testWSAFinalInformation() {


Reply via email to