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/02/15 17:41:13 UTC

svn commit: r507996 - in /webservices/axis2/trunk/java/modules/kernel: src/org/apache/axis2/description/AxisService.java test/org/apache/axis2/engine/SOAPActionBasedDispatcherTest.java

Author: barrettj
Date: Thu Feb 15 08:41:12 2007
New Revision: 507996

URL: http://svn.apache.org/viewvc?view=rev&rev=507996
Log:
AXIS2-2178
Don't allow duplicate aliases for different operations under an AxisService to be used to resolve the operation. 
If an attempt is made to add a duplicate alias that resolves to a different operation than a current alias, that alias
is removed from the map and added to a list of invalid aliases.  This prevents routing to an incorrect AxisOperation based
on a duplicate alias.  Also added a test to verify this behavior via the SOAPActionBasedDispatcher.

Added:
    webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/engine/SOAPActionBasedDispatcherTest.java
Modified:
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/AxisService.java

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/AxisService.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/AxisService.java?view=diff&rev=507996&r1=507995&r2=507996
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/AxisService.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/AxisService.java Thu Feb 15 08:41:12 2007
@@ -84,6 +84,9 @@
     private HashMap httpLocationDispatcherMap = null;
 
     private HashMap operationsAliasesMap = null;
+    // Collection of aliases that are invalid for this service because they are duplicated across
+    // multiple operations under this service.
+    private List invalidOperationsAliases = null;
 //    private HashMap operations = new HashMap();
 
     // to store module ref at deploy time parsing
@@ -256,6 +259,7 @@
     public AxisService() {
         super();
         this.operationsAliasesMap = new HashMap();
+        this.invalidOperationsAliases = new ArrayList();
         moduleConfigmap = new HashMap();
         //by default service scope is for the request
         scope = Constants.SCOPE_REQUEST;
@@ -595,9 +599,15 @@
     }
 
     /**
-     * Maps an action (aka WSA action) to the given operation. This is used by
-     * addressing based dispatching to figure out which operation it is that a
-     * given message is for.
+     * Maps an action (a SOAPAction or WSA action) to the given operation. This is used by
+     * dispatching (both SOAPAction- and WSAddressing- based dispatching) to figure out which 
+     * operation a given message is for.  Some notes on restrictions of "action"
+     * - A null or empty action will be ignored
+     * - An action that is a duplicate and references an idential operation is allowed
+     * - An acton that is a duplicate and references a different operation is NOT allowed.  In this
+     *   case, the action for the original operation is removed from the alias table, thus removing
+     *   the ability to route based on this action.  This is necessary to prevent mis-directing
+     *   incoming message to the wrong operation based on SOAPAction.
      *
      * @param action        the action key
      * @param axisOperation the operation to map to
@@ -610,9 +620,50 @@
             return;
         }
         if(log.isDebugEnabled()){
-            log.debug("mapActionToOperation: Mapping Action to Operation: action="+action+" operation="+axisOperation);
+            log.debug("mapActionToOperation: Mapping Action to Operation: action: " + action + "; operation: " + axisOperation);
+        }
+
+        // First check if this action has already been flagged as invalid because it is a duplicate. 
+        if (invalidOperationsAliases.contains(action)) {
+            // This SOAPAction has already been determined to be invalid; log a message
+            // and do not add it to the operation alias map.
+            if (log.isDebugEnabled()) {
+                log.debug("mapActionToOperation: The action: " + action + " can not be used for operation: " 
+                        + axisOperation + " with operation name: " + axisOperation.getName() 
+                        + " because that SOAPAction is not unique for this service.");
+            }
+            return;
+        }
+        
+        // Check if the action is currently mapping to an operation.
+        AxisOperation currentlyMappedOperation = getOperationByAction(action);
+        if (currentlyMappedOperation != null) {
+            if (currentlyMappedOperation == axisOperation) {
+                // This maps to the same operation, then it is already in the alias table, so
+                // just silently ignore this mapping request.
+                if (log.isDebugEnabled()) {
+                    log.debug("mapActionToOperation: This operation is already mapped to this action: " + action + "; AxisOperation: " 
+                            + currentlyMappedOperation + " named: " + currentlyMappedOperation.getName());
+                }
+            }
+            else {
+                // This action is already mapped, but it is to a different operation.  Remove
+                // the action mapping from the alias table and add it to the list of invalid mappings
+                operationsAliasesMap.remove(action);
+                invalidOperationsAliases.add(action);
+                if (log.isDebugEnabled()) {
+                    log.debug("mapActionToOperation: The action is already mapped to a different operation.  The mapping of the action to any operations will be removed.  Action: " 
+                            + action + "; original operation: " + currentlyMappedOperation 
+                            + " named " + currentlyMappedOperation.getName() 
+                            + "; new operation: " + axisOperation
+                            + " named " + axisOperation.getName());
+                }
+            }
+            return;
+        }
+        else {
+            operationsAliasesMap.put(action, axisOperation);
         }
-        operationsAliasesMap.put(action, axisOperation);
     }
 
     /**

Added: webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/engine/SOAPActionBasedDispatcherTest.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/engine/SOAPActionBasedDispatcherTest.java?view=auto&rev=507996
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/engine/SOAPActionBasedDispatcherTest.java (added)
+++ webservices/axis2/trunk/java/modules/kernel/test/org/apache/axis2/engine/SOAPActionBasedDispatcherTest.java Thu Feb 15 08:41:12 2007
@@ -0,0 +1,151 @@
+/*
+* 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.
+*/
+package org.apache.axis2.engine;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.InOnlyAxisOperation;
+
+import junit.framework.TestCase;
+
+public class SOAPActionBasedDispatcherTest extends TestCase {
+
+    public void testFindOperation() throws Exception{
+        MessageContext messageContext = new MessageContext();
+        AxisService as = new AxisService("Service1");
+        messageContext.setAxisService(as);
+        
+        AxisOperation operation1 = new InOnlyAxisOperation(new QName("operation1"));
+        operation1.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation1");
+        
+        AxisOperation operation2 = new InOnlyAxisOperation(new QName("operation2"));
+        operation2.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation2");
+        
+        as.addOperation(operation1);
+        as.addOperation(operation2);
+        
+        messageContext.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation1");
+        
+        SOAPActionBasedDispatcher soapActionDispatcher = new SOAPActionBasedDispatcher();
+        soapActionDispatcher.invoke(messageContext);
+        assertEquals(operation1, messageContext.getAxisOperation());
+    }
+    
+    public void testEmptyAction() throws Exception {
+        // We shouldn't be able to route on an emtpy-string action.
+        MessageContext messageContext = new MessageContext();
+        AxisService as = new AxisService("Service1");
+        messageContext.setAxisService(as);
+        
+        AxisOperation operation1 = new InOnlyAxisOperation(new QName("operation1"));
+        operation1.setSoapAction("");
+        
+        AxisOperation operation2 = new InOnlyAxisOperation(new QName("operation2"));
+        operation2.setSoapAction("");
+        
+        as.addOperation(operation1);
+        as.addOperation(operation2);
+        
+        messageContext.setSoapAction("");
+        
+        SOAPActionBasedDispatcher soapActionDispatcher = new SOAPActionBasedDispatcher();
+        soapActionDispatcher.invoke(messageContext);
+        assertNull(messageContext.getAxisOperation());
+    }
+    
+    public void testNullAction() throws Exception {
+        // We shouldn't be able to route on a null action.
+        MessageContext messageContext = new MessageContext();
+        AxisService as = new AxisService("Service1");
+        messageContext.setAxisService(as);
+        
+        AxisOperation operation1 = new InOnlyAxisOperation(new QName("operation1"));
+        operation1.setSoapAction(null);
+        
+        AxisOperation operation2 = new InOnlyAxisOperation(new QName("operation2"));
+        operation2.setSoapAction(null);
+        
+        as.addOperation(operation1);
+        as.addOperation(operation2);
+        
+        messageContext.setSoapAction(null);
+        
+        SOAPActionBasedDispatcher soapActionDispatcher = new SOAPActionBasedDispatcher();
+        soapActionDispatcher.invoke(messageContext);
+        assertNull(messageContext.getAxisOperation());
+    }
+
+    public void testDuplicateAction() throws Exception {
+        // We shouldn't be able to route on a SOAPAction that is a duplicate.
+        MessageContext messageContext = new MessageContext();
+        AxisService as = new AxisService("Service1");
+        messageContext.setAxisService(as);
+        
+        AxisOperation operation1 = new InOnlyAxisOperation(new QName("operation1"));
+        operation1.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation1");
+        
+        AxisOperation operation2 = new InOnlyAxisOperation(new QName("operation2"));
+        operation2.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation2");
+        
+        as.addOperation(operation1);
+        as.addOperation(operation2);
+        
+        messageContext.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation2");
+        
+        SOAPActionBasedDispatcher soapActionDispatcher = new SOAPActionBasedDispatcher();
+        soapActionDispatcher.invoke(messageContext);
+        assertEquals(operation2, messageContext.getAxisOperation());
+        
+        // Now add a duplicate action, then validate we can't route on it anymore.
+        AxisOperation operation3 = new InOnlyAxisOperation(new QName("operation3"));
+        // Note that the SOAPAction is intentionally duplicated with operation 2 above.
+        operation3.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation2");
+        as.addOperation(operation3);
+
+        messageContext = new MessageContext();
+        messageContext.setAxisService(as);
+        messageContext.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation2");
+        soapActionDispatcher.invoke(messageContext);
+        assertNull(messageContext.getAxisOperation());
+        
+        // Now verify that adding another operation with the duplicate SOAPAction 
+        // doesn't somehow get it added back into the valid alias map
+        AxisOperation operation4 = new InOnlyAxisOperation(new QName("operation4"));
+        // Note that the SOAPAction is intentionally duplicated with operation 2 above.
+        operation3.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation2");
+        as.addOperation(operation3);
+        
+        messageContext = new MessageContext();
+        messageContext.setAxisService(as);
+        messageContext.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation2");
+        soapActionDispatcher.invoke(messageContext);
+        assertNull(messageContext.getAxisOperation());
+        
+        // And finally, verify that after all the above, we can still route on a valid
+        // SOAPAction for operation 1 (whose SOAPAction was never duplicated, so should still be
+        // valid)
+        messageContext = new MessageContext();
+        messageContext.setAxisService(as);
+        messageContext.setSoapAction("urn:org.apache.axis2.dispatchers.test:operation1");
+        soapActionDispatcher.invoke(messageContext);
+        assertEquals(operation1, messageContext.getAxisOperation());
+        
+
+    }
+
+
+}



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