You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by gd...@apache.org on 2002/01/14 22:17:47 UTC

cvs commit: xml-axis/java/test/soap PackageTests.java TestHandler.java TestHeaderAttrs.java TestService.java

gdaniels    02/01/14 13:17:47

  Modified:    java/src/org/apache/axis/message SOAPEnvelope.java
  Added:       java/test/soap PackageTests.java TestHandler.java
                        TestHeaderAttrs.java TestService.java
  Log:
  Improve SOAPEnvelope's respect for actors, making the various getHeader()
  methods filter on the current engine's actor list by default.  There are new
  APIs which allow access to the entire header list with no filtering.
  
  Add unit test for MustUnderstand and actor combinations.
  
  Revision  Changes    Path
  1.49      +74 -2     xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java
  
  Index: SOAPEnvelope.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java,v
  retrieving revision 1.48
  retrieving revision 1.49
  diff -u -r1.48 -r1.49
  --- SOAPEnvelope.java	9 Jan 2002 20:43:05 -0000	1.48
  +++ SOAPEnvelope.java	14 Jan 2002 21:17:47 -0000	1.49
  @@ -251,16 +251,48 @@
           _isDirty = true;
       }
   
  +    /**
  +     * Get a header by name (always respecting the currently in-scope
  +     * actors list)
  +     */ 
       public SOAPHeader getHeaderByName(String namespace, String localPart)
           throws AxisFault
       {
  +        return getHeaderByName(namespace, localPart, false);
  +    }
  +    
  +    /**
  +     * Get a header by name, filtering for headers targeted at this
  +     * engine depending on the accessAllHeaders parameter.
  +     */ 
  +    public SOAPHeader getHeaderByName(String namespace, String localPart,
  +                                      boolean accessAllHeaders)
  +        throws AxisFault
  +    {
           SOAPHeader header = (SOAPHeader)findElement(headers,
                                                       namespace,
                                                       localPart);
  +
  +        // If we're operating within an AxisEngine, respect its actor list
  +        // unless told otherwise
  +        if (!accessAllHeaders) {
  +            MessageContext mc = MessageContext.getCurrentContext();
  +            if (mc != null) {
  +                if (header != null) {
  +                    String actor = header.getActor();
  +                    ArrayList actors = mc.getAxisEngine().getActorURIs();
  +                    if ((actor != null) &&
  +                            !Constants.ACTOR_NEXT.equals(actor) &&
  +                            (actors == null || !actors.contains(actor))) {
  +                        header = null;
  +                    }
  +                }
  +            }
  +        }
           
           return header;
       }
  -
  +    
       public SOAPBodyElement getBodyByName(String namespace, String localPart)
           throws AxisFault
       {
  @@ -290,6 +322,26 @@
       public Enumeration getHeadersByName(String namespace, String localPart)
           throws AxisFault
       {
  +        return getHeadersByName(namespace, localPart, false);
  +    }
  +
  +    /**
  +     * Return an Enumeration of headers which match the given namespace
  +     * and localPart.  Depending on the value of the accessAllHeaders
  +     * parameter, we will attempt to filter on the current engine's list
  +     * of actors.
  +     * 
  +     * !!! NOTE THAT RIGHT NOW WE ALWAYS ASSUME WE'RE THE "ULTIMATE
  +     * DESTINATION" (i.e. we match on null actor).  IF WE WANT TO FULLY SUPPORT
  +     * INTERMEDIARIES WE'LL NEED TO FIX THIS.
  +     */ 
  +    public Enumeration getHeadersByName(String namespace, String localPart,
  +                                        boolean accessAllHeaders)
  +        throws AxisFault
  +    {
  +        ArrayList actors;
  +        boolean firstTime = false;
  +        
           /** This might be optimizable by creating a custom Enumeration
            * which moves through the headers list (parsing on demand, again),
            * returning only the next one each time.... this is Q&D for now.
  @@ -300,8 +352,28 @@
           while (e.hasMoreElements()) {
               header = (SOAPHeader)e.nextElement();
               if (header.getNamespaceURI().equals(namespace) &&
  -                header.getName().equals(localPart))
  +                header.getName().equals(localPart)) {
  +
  +                if (!accessAllHeaders) {
  +                    if (firstTime) {
  +                        // Do one-time setup
  +                        MessageContext mc = MessageContext.getCurrentContext();
  +                        if (mc != null)
  +                            actors = mc.getAxisEngine().getActorURIs();
  +                            
  +                        firstTime = false;
  +                    }
  +
  +                    String actor = header.getActor();
  +                    if ((actor != null) &&
  +                            !Constants.ACTOR_NEXT.equals(actor) &&
  +                            (actors == null || !actors.contains(actor))) {
  +                        continue;
  +                    }
  +                }
  +
                   v.addElement(header);
  +            }
           }
           
           return v.elements();
  
  
  
  1.1                  xml-axis/java/test/soap/PackageTests.java
  
  Index: PackageTests.java
  ===================================================================
  package test.soap;
  
  import junit.framework.Test;
  import junit.framework.TestSuite;
  import test.utils.TestAxisClassLoader;
  import test.utils.TestQName;
  import test.utils.TestQFault;
  import test.utils.TestXMLUtils;
  import test.utils.TestMessages;
  
  /**
   */
  public class PackageTests 
  {
      public static void main (String[] args) {
              junit.textui.TestRunner.run (suite());
      }
  
      public static Test suite()
      {
          TestSuite suite = new TestSuite("All axis.soap tests");
  
          suite.addTest(TestHeaderAttrs.suite());
  
          return suite;
      }
  }
  
  
  
  1.1                  xml-axis/java/test/soap/TestHandler.java
  
  Index: TestHandler.java
  ===================================================================
  /*
   * Created by IntelliJ IDEA.
   * User: gdaniels
   * Date: Jan 14, 2002
   * Time: 2:13:08 PM
   * To change template for new class use 
   * Code Style | Class Templates options (Tools | IDE Options).
   */
  package test.soap;
  
  import org.apache.axis.handlers.BasicHandler;
  import org.apache.axis.MessageContext;
  import org.apache.axis.AxisFault;
  import org.apache.axis.message.SOAPEnvelope;
  
  /**
   * This is a test Handler which interacts with the TestService below in
   * order to test header processing.  If a particular header appears in
   * the message, we mark the MessageContext so the TestService knows to
   * double its results (which is a detectable way of confirming header
   * processing on the client side).
   */ 
  public class TestHandler extends BasicHandler {
      public void invoke(MessageContext msgContext) throws AxisFault {
          SOAPEnvelope env = msgContext.getRequestMessage().getSOAPEnvelope();
          if (env.getHeaderByName(TestHeaderAttrs.GOOD_HEADER_NS, 
                                  TestHeaderAttrs.GOOD_HEADER_NAME) != null) {
              // Just the header's presence is enough - mark the property
              // so it can be picked up by the service (see below)
              msgContext.setProperty(TestHeaderAttrs.PROP_DOUBLEIT, Boolean.TRUE);
          }
      }
  }
  
  
  
  1.1                  xml-axis/java/test/soap/TestHeaderAttrs.java
  
  Index: TestHeaderAttrs.java
  ===================================================================
  package test.soap;
  
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.framework.Test;
  import org.apache.axis.AxisFault;
  import org.apache.axis.Constants;
  import org.apache.axis.Handler;
  import org.apache.axis.Message;
  import org.apache.axis.MessageContext;
  import org.apache.axis.transport.local.LocalTransport;
  import org.apache.axis.client.Call;
  import org.apache.axis.handlers.soap.SOAPService;
  import org.apache.axis.handlers.EchoHandler;
  import org.apache.axis.handlers.BasicHandler;
  import org.apache.axis.message.RPCElement;
  import org.apache.axis.message.RPCParam;
  import org.apache.axis.message.SOAPEnvelope;
  import org.apache.axis.message.SOAPHeader;
  import org.apache.axis.server.AxisServer;
  
  import org.xml.sax.SAXException;
  
  import org.w3c.dom.Element;
  import org.w3c.dom.Text;
  
  import java.util.Vector;
  import java.util.Random;
  
  import test.RPCDispatch.Data;
  
  import org.apache.axis.client.Service;
  
  /**
   * A fairly comprehensive test of MustUnderstand/Actor combinations.
   *
   * @author Glen Daniels (gdaniels@macromedia.com)
   */
  public class TestHeaderAttrs extends TestCase {
      static final String PROP_DOUBLEIT = "double_result";
      
      static final String GOOD_HEADER_NS = "http://testMU/";
      static final String GOOD_HEADER_NAME = "doubleIt";
      
      static final String BAD_HEADER_NS = "http://incorrect-ns/";
      static final String BAD_HEADER_NAME = "startThermonuclearWar";
      
      static final String ACTOR = "http://some.actor/";
      
      static SOAPHeader goodHeader = new SOAPHeader(GOOD_HEADER_NS, 
                                                    GOOD_HEADER_NAME);
      static SOAPHeader badHeader = new SOAPHeader(BAD_HEADER_NS, 
                                                   BAD_HEADER_NAME);
  
      private AxisServer engine = new AxisServer();
      private LocalTransport localTransport = new LocalTransport(engine);
      private Handler RPCDispatcher;
  
      static final String localURL = "local:///testService";
  
      public static Test suite() {
          return new TestSuite(TestHeaderAttrs.class);
      }
      
      public TestHeaderAttrs(String name) {
          super(name);
      }
      
      /**
       * Prep work.  Make a server, tie a LocalTransport to it, and deploy
       * our little test service therein.
       */ 
      public void setUp() throws Exception {
          engine.init();
          localTransport.setUrl(localURL);
          
          Handler dispatcher = engine.getHandler("RPCDispatcher");
          SOAPService service = new SOAPService(new TestHandler(),
                                                dispatcher, 
                                                null);
          
          service.setOption("className", TestService.class.getName());
          service.setOption("methodName", "*");
          
          engine.deployService("testService", service);
      }
      
      /**
       * Test an unrecognized header with MustUnderstand="true"
       */ 
      public void testMUBadHeader() throws Exception
      {
          // 1. MU header to unrecognized actor -> should work fine
          badHeader.setActor(ACTOR);
          badHeader.setMustUnderstand(true);
          
          assertTrue("Bad result from test", runTest(badHeader, false));
          
          // 2. MU header to NEXT -> should fail
          badHeader.setActor(Constants.ACTOR_NEXT);
          badHeader.setMustUnderstand(true);
          
          // Test (should produce MU failure)
          try {
              runTest(badHeader, false);
          } catch (Exception e) {
              assertTrue("Non AxisFault Exception : " + e, 
                         e instanceof AxisFault);
              AxisFault fault = (AxisFault)e;
              assertEquals("Bad fault code!", Constants.FAULT_MUSTUNDERSTAND,
                           fault.getFaultCode());
              return;
          }
          
          fail("Should have gotten mustUnderstand fault!");
      }
      
      /**
       * Test an unrecognized header with MustUnderstand="false"
       */ 
      public void testNonMUBadHeader() throws Exception
      {
          badHeader.setActor(Constants.ACTOR_NEXT);
          badHeader.setMustUnderstand(false);
  
          assertTrue("Non-MU bad header to next actor returned bad result!",
                     runTest(badHeader, false));
  
          badHeader.setActor(ACTOR);
          
          assertTrue("Non-MU bad header to unrecognized actor returned bad result!", 
                     runTest(badHeader, false));
      }
      
      /**
       * Test a recognized header (make sure it has the desired result)
       */ 
      public void testGoodHeader() throws Exception
      {
          goodHeader.setActor(Constants.ACTOR_NEXT);
          assertTrue("Good header with next actor returned bad result!",
                     runTest(goodHeader, true));
      }
      
      /**
       * Test a recognized header with a particular actor attribute
       */ 
      public void testGoodHeaderWithActors() throws Exception
      {
          // 1. Good header to unrecognized actor -> should be ignored, and
          //    we should get a non-doubled result
          goodHeader.setActor(ACTOR);
          assertTrue("Good header with unrecognized actor returned bad result!",
                     runTest(goodHeader, false));
          
          // Now tell the engine to recognize the ACTOR value
          engine.addActorURI(ACTOR);
          
          // 2. Good header should now be processed and return doubled result
          assertTrue("Good header with recognized actor returned bad result!",
                     runTest(goodHeader, true));
          
          engine.removeActorURI(ACTOR);
      }
      
      /**
       * Call the service with a random string.  Returns true if the result
       * is the length of the string (doubled if the doubled arg is true).
       */ 
      public boolean runTest(SOAPHeader header, boolean doubled) throws Exception
      {
          Call call = new Call(new Service());
          call.setTransport(localTransport);
          
          call.addHeader(header);
          
          String str = "a";
          int maxChars = new Random().nextInt(50);
          for (int i = 0; i < maxChars; i++) {
              str += "a";
          }
  
          Integer i = (Integer)call.invoke("countChars", new Object [] { str });
          
          int desiredResult = str.length();
          if (doubled) desiredResult = desiredResult * 2;
          
          return (i.intValue() == desiredResult);
      }
      
      public static void main(String[] args) throws Exception {
          TestHeaderAttrs tester = new TestHeaderAttrs("test");
          tester.setUp();
          tester.testMUBadHeader();
          tester.testNonMUBadHeader();
          tester.testGoodHeader();
          tester.testGoodHeaderWithActors();
      }
  }
  
  
  
  1.1                  xml-axis/java/test/soap/TestService.java
  
  Index: TestService.java
  ===================================================================
  /*
   * Created by IntelliJ IDEA.
   * User: gdaniels
   * Date: Jan 14, 2002
   * Time: 2:12:43 PM
   * To change template for new class use 
   * Code Style | Class Templates options (Tools | IDE Options).
   */
  package test.soap;
  
  import org.apache.axis.MessageContext;
  
  /**
   * Trivial test service.
   */ 
  public class TestService {
      /**
       * Calculate and return the length of the passed String.  If a
       * MessageContext property indicates that we've received a particular
       * header, then double the result before returning it.
       */ 
      public int countChars(String str)
      {
          int ret = str.length();
          MessageContext mc = MessageContext.getCurrentContext();
          if (mc.isPropertyTrue(TestHeaderAttrs.PROP_DOUBLEIT)) {
              ret = ret * 2;
          }
          return ret;
      }
  }