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() {