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 na...@apache.org on 2009/03/10 21:38:51 UTC

svn commit: r752251 - in /webservices/axis2/trunk/java/modules: jaxws-integration/test/org/apache/axis2/jaxws/provider/ jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsgmu/ jaxws-integration/test/org/apache/axis2/jaxws/sample/ jaxws/src/or...

Author: nagy
Date: Tue Mar 10 20:38:51 2009
New Revision: 752251

URL: http://svn.apache.org/viewvc?rev=752251&view=rev
Log:
Contributor: Jeff Barrett
Add logic so that client-side application handlers (e.g. JAX-WS application handlers) can participate in mustUnderstand processing for responses received by the client.  The handlers register themselves via a property located on the MessageContext.


Modified:
    webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/AttachmentUtil.java
    webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageMUProviderTests.java
    webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsgmu/SoapMessageMUProvider.java
    webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/engine/AxisEngine.java

Modified: webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/AttachmentUtil.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/AttachmentUtil.java?rev=752251&r1=752250&r2=752251&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/AttachmentUtil.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/AttachmentUtil.java Tue Mar 10 20:38:51 2009
@@ -49,6 +49,7 @@
     public static final String SOAP12_NAMESPACE = "http://www.w3.org/2003/05/soap-envelope";
 
     public static final String MU_TEXT = "soap message mustUnderstand header request";
+    public static final String MU_TEXT2 = "soap message mustUnderstand header request 2"; 
     public static final String UNDERSTOOD_MU_TEXT = "understood headers soap message mustUnderstand header request";
     public static final String TEXT = "soap message request";
     public static final String VALUE = "value";
@@ -57,6 +58,8 @@
     public static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
     public static final String MUHEADER_CLIENT = "ns1:muclient";
     public static final String MUHEADER_SERVER = "ns1:muserver";
+    public static final String MUHEADER_CLIENT2 = "ns1:muclient2";
+    public static final String MUHEADER_SERVER2 = "ns1:muserver2";
     public static final String MUHEADER_CLIENT_UNDERSTOOD = "ns1:muclientunderstood";
     public static final String MUHEADER_SERVER_UNDERSTOOD = "ns1:muserverunderstood";
     public static final String msgEnvMU = 
@@ -72,6 +75,21 @@
                 "</ns1:invoke>" +
             "</soapenv:Body>" +
         "</soapenv:Envelope>";
+
+    // Similar to msgEnvMU but has two Header elements marked as mustUnderstand
+    public static final String msgEnvMU2 = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
+                                              "<soapenv:Header>" +
+                                                 "<"+MUHEADER_CLIENT+" xmlns:ns1=\"http://ws.apache.org/axis2\" soapenv:mustUnderstand=\"1\">MUinfo</"+MUHEADER_CLIENT+">" +
+                                                 "<"+MUHEADER_CLIENT2+" xmlns:ns1=\"http://ws.apache.org/axis2\" soapenv:mustUnderstand=\"1\">MUinfo2</"+MUHEADER_CLIENT2+">" +
+                                              "</soapenv:Header>" +    
+                                              "<soapenv:Body>" +
+                                                 "<ns1:invoke xmlns:ns1=\"http://ws.apache.org/axis2\">" +
+                                                    VALUE_NODE +
+                                                       MU_TEXT2 +
+                                                    VALUE_NODE_SLASH +
+                                                 "</ns1:invoke>" +
+                                              "</soapenv:Body>" +
+                                           "</soapenv:Envelope>";
     
     public static final String msgEnv = 
         "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
@@ -83,6 +101,16 @@
                 "</ns1:invoke>" +
             "</soapenv:Body>" +
         "</soapenv:Envelope>";
+
+    public static final String msgEnv2 = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
+                                            "<soapenv:Body>" +
+                                               "<ns1:invoke xmlns:ns1=\"http://ws.apache.org/axis2\">" +
+                                                  VALUE_NODE +
+                                                     MU_TEXT2 +
+                                                  VALUE_NODE_SLASH +
+                                               "</ns1:invoke>" +
+                                            "</soapenv:Body>" +
+                                         "</soapenv:Envelope>";    
     
     public static final String msgEnvPlain = 
         "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +

Modified: webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageMUProviderTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageMUProviderTests.java?rev=752251&r1=752250&r2=752251&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageMUProviderTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageMUProviderTests.java Tue Mar 10 20:38:51 2009
@@ -27,8 +27,19 @@
 import javax.xml.namespace.QName;
 import javax.xml.soap.SOAPMessage;
 import javax.xml.ws.BindingProvider;
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Binding;
+import javax.xml.ws.Response; 
 import javax.xml.ws.Service;
 import javax.xml.ws.soap.SOAPBinding;
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
 
 /**
  * Tests Dispatch<SOAPMessage> client and a Provider<SOAPMessage> service
@@ -213,4 +224,331 @@
         // Try a second time
         dispatch.invoke(message);
     }
+    /**
+     * Test the mustUnderstand soap header attribute on the server's
+     * outbound soap message using multiple handlers.  The response contains a header that 
+     * should be understood by the JAX-WS application handler, so there should be no exception.
+     * Tests that multiple handlers do not cause a collision when registering headers they 
+     * understand.
+     */
+    public void testClientResponseHandlerUnderstoodHeaders2() {
+        System.out.println("testClientResponseTwoHandlerUnderstoodHeaders2");
+
+        // create a service
+        Service svc = Service.create(serviceName);
+        svc.addPort(portName, bindingID, endpointUrl);
+
+        javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
+        dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
+
+        //force SOAPAction to match with wsdl action                        
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
+        // set handler chain for binding provider to add the handler that will
+        // understand the mU header
+        Binding binding = ((BindingProvider) dispatch).getBinding();
+
+        // create a new list or use the existing one
+        List<Handler> handlers = binding.getHandlerChain();
+    
+        if (handlers == null) {
+            handlers = new ArrayList<Handler>();
+        }
+        handlers.add(new MustUnderstandClientHandler2());
+        handlers.add(new MustUnderstandClientHandler());
+        binding.setHandlerChain(handlers);
+
+        SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv2);
+        
+        try {
+            SOAPMessage response = dispatch.invoke(message);
+            assertNotNull("No response received", response);
+            String responseString = AttachmentUtil.toString(response);
+            assertNotNull(responseString);
+        } catch (Exception e) {
+            fail("Should not have caught an exception: " + e.toString());
+        }
+        
+    }
+    
+    /**
+     * Test that not-understood mustUnderstand headers cause an exception in the async polling
+     * case.
+     */
+    public void testClientResponseNotUnderstoodHeadersAsyncPolling() {
+        System.out.println("testClientResponseNotUnderstoodHeadersAsyncPolling");
+
+        // create a service
+        Service svc = Service.create(serviceName);
+        svc.addPort(portName, bindingID, endpointUrl);
+
+        javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
+        dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
+
+        //force SOAPAction to match with wsdl action                        
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
+
+        SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
+        
+        Response<SOAPMessage> asyncResponse = null;
+        try {
+            asyncResponse = dispatch.invokeAsync(message);
+            assertNotNull("No response received", asyncResponse);
+        } catch (Exception e) {
+            fail("Should not have caught an exception on the async invocation: " + e.toString());
+        }
+        
+        try {
+            while (!asyncResponse.isDone()) {
+                System.out.println(">> Async invocation still not complete");
+                Thread.sleep(1000);
+            }
+            SOAPMessage response = asyncResponse.get();
+            fail("Should have caught a mustUnderstand exception");
+        } catch (Exception e) {
+            // Expected path
+            assertTrue("Did not received expected exception", 
+                    e.getCause().toString().contains("Must Understand check failed for header http://ws.apache.org/axis2 : muserver"));
+        }
+        
+    }
+    
+    /**
+     * Test that JAX-WS handlers can register they processes certain mustUnderstand headers in the 
+     * async polling case.
+     */
+    public void testClientResponseHandlerUnderstoodHeadersAsyncPolling() {
+        System.out.println("testClientResponseHandlerUnderstoodHeadersAsyncPolling");
+
+        // create a service
+        Service svc = Service.create(serviceName);
+        svc.addPort(portName, bindingID, endpointUrl);
+
+        javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
+        dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
+
+        //force SOAPAction to match with wsdl action                        
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
+        // set handler chain for binding provider to add the handler that will
+        // understand the mU header
+        Binding binding = ((BindingProvider) dispatch).getBinding();
+
+        // create a new list or use the existing one
+        List<Handler> handlers = binding.getHandlerChain();
+        if (handlers == null) {
+            handlers = new ArrayList<Handler>();
+        }
+        handlers.add(new MustUnderstandClientHandler());
+        binding.setHandlerChain(handlers);
+
+        SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
+        
+        try {
+            Response<SOAPMessage> asyncResponse = dispatch.invokeAsync(message);
+            assertNotNull("No response received", asyncResponse);
+            while (!asyncResponse.isDone()) {
+                System.out.println(">> Async invocation still not complete");
+                Thread.sleep(1000);
+            }
+            SOAPMessage response = asyncResponse.get();
+            assertNotNull("Response was nulL", response);
+            String responseString = AttachmentUtil.toString(response);
+            assertNotNull(responseString);
+        } catch (Exception e) {
+            fail("Should not have caught an exception: " + e.toString());
+        }
+        
+    }
+    
+    /**
+     * Test that not-understood mustUnderstand headers cause an exception in the async callback
+     * case.
+     */
+    public void testClientResponseNotUnderstoodHeadersAsyncCallback() {
+        System.out.println("testClientResponseNotUnderstoodHeadersAsyncCallback");
+
+        // create a service
+        Service svc = Service.create(serviceName);
+        svc.addPort(portName, bindingID, endpointUrl);
+
+        javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
+        dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
+
+        //force SOAPAction to match with wsdl action                        
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
+
+        SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
+        
+        Future<?> asyncResponse = null;
+        AsyncCallback<SOAPMessage> callback = new AsyncCallback<SOAPMessage>();
+        try {
+            asyncResponse = dispatch.invokeAsync(message, callback);
+            assertNotNull("No response received", asyncResponse);
+        } catch (Exception e) {
+            fail("Should not have caught an exception on the async invocation: " + e.toString());
+        }
+        
+        try {
+            while (!asyncResponse.isDone()) {
+                System.out.println(">> Async invocation still not complete");
+                Thread.sleep(1000);
+            }
+            assertTrue("Did not receive exception", callback.hasError());
+            assertTrue("Did not received expected exception", 
+                    callback.getError().toString().contains("Must Understand check failed for header http://ws.apache.org/axis2 : muserver"));
+        } catch (Exception e) {
+            fail("Received unexpected exception: " + e.toString()); 
+        }
+        
+    }
+
+    /**
+     * Test that JAX-WS handlers can register they processes certain mustUnderstand headers in the 
+     * async callback case.
+     */
+    public void testClientResponseUnderstoodHeadersAsyncCallback() {
+        System.out.println("testClientResponseUnderstoodHeadersAsyncCallback");
+
+        // create a service
+        Service svc = Service.create(serviceName);
+        svc.addPort(portName, bindingID, endpointUrl);
+
+        javax.xml.ws.Dispatch<SOAPMessage> dispatch = null;
+        dispatch = svc.createDispatch(portName, SOAPMessage.class, mode);
+
+        //force SOAPAction to match with wsdl action                        
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
+        ((BindingProvider) dispatch).getRequestContext()
+                                    .put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoString");
+
+        // set handler chain for binding provider to add the handler that will
+        // understand the mU header
+        Binding binding = ((BindingProvider) dispatch).getBinding();
+
+        // create a new list or use the existing one
+        List<Handler> handlers = binding.getHandlerChain();
+        if (handlers == null) {
+            handlers = new ArrayList<Handler>();
+        }
+        handlers.add(new MustUnderstandClientHandler());
+        binding.setHandlerChain(handlers);
+        
+        SOAPMessage message = AttachmentUtil.toSOAPMessage(AttachmentUtil.msgEnv);
+        
+        Future<?> asyncResponse = null;
+        AsyncCallback<SOAPMessage> callback = new AsyncCallback<SOAPMessage>();
+        try {
+            asyncResponse = dispatch.invokeAsync(message, callback);
+            assertNotNull("No response received", asyncResponse);
+        } catch (Exception e) {
+            fail("Should not have caught an exception on the async invocation: " + e.toString());
+        }
+        
+        try {
+            while (!asyncResponse.isDone()) {
+                System.out.println(">> Async invocation still not complete");
+                Thread.sleep(1000);
+            }
+            assertFalse("Receive unexpected exception", callback.hasError());
+            SOAPMessage response = callback.getValue();
+            assertNotNull(response);
+        } catch (Exception e) {
+            fail("Received unexpected exception" + e.toString());
+        }
+        
+    }
+    // ============================================================================================
+    // Test handlers and test classes
+    // ============================================================================================
+
+    class MustUnderstandClientHandler implements
+    javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext> {
+
+        public Set<QName> getHeaders() {
+            // Understand the header {http://ws.apache.org/axis2}muserver that will be sent back
+            // by the server; the other headers are just to test multiple entries in the Set
+            Set<QName> result = new HashSet<QName>();
+            result.add(new QName("http://ws.apache.org/axis2", "muserverAnother"));
+            result.add(new QName("http://ws.apache.org/axis2", "muserver"));
+            result.add(new QName("http://ws.apache.org/axis2", "muserverYetAnother"));
+            return result;
+        }
+
+        public void close(MessageContext context) {
+        }
+
+        public boolean handleFault(SOAPMessageContext context) {
+            return true;
+        }
+
+        public boolean handleMessage(SOAPMessageContext context) {
+            return true;
+        }
+        
+    }
+    
+    class MustUnderstandClientHandler2 implements
+    javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext> {
+
+        public Set<QName> getHeaders() {
+            // Understand the header {http://ws.apache.org/axis2}muserver2 that will be sent back
+            // by the server; the other headers are just to test multiple entries in the Set
+            Set<QName> result = new HashSet<QName>();
+            // The first header is a collision with one understood by the other handler
+            result.add(new QName("http://ws.apache.org/axis2", "muserverAnother"));
+            result.add(new QName("http://ws.apache.org/axis2", "muserver2"));
+            result.add(new QName("http://ws.apache.org/axis2", "muserverYetAnother2"));
+            return result;
+        }
+
+        public void close(MessageContext context) {
+        }
+
+        public boolean handleFault(SOAPMessageContext context) {
+            return true;
+        }
+
+        public boolean handleMessage(SOAPMessageContext context) {
+            return true;
+        }
+    }
+    
+    class AsyncCallback<T> implements AsyncHandler<T> {
+
+        private T value;
+        private Throwable exception;
+
+        public void handleResponse(Response<T> response) {
+            try {
+                value = response.get();
+            } catch (Throwable t) {
+                exception = t;
+            }
+        }
+
+        public boolean hasError() {
+            return (exception != null);
+        }
+
+        public Throwable getError() {
+            return exception;
+        }
+
+        public T getValue() {
+            return value;
+        }
+    }
+    
 }

Modified: webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsgmu/SoapMessageMUProvider.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsgmu/SoapMessageMUProvider.java?rev=752251&r1=752250&r2=752251&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsgmu/SoapMessageMUProvider.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsgmu/SoapMessageMUProvider.java Tue Mar 10 20:38:51 2009
@@ -68,6 +68,14 @@
                     response = AttachmentUtil.toSOAPMessage(responseStr);
                     System.out.println("invoke: ---Response message= "
                             + AttachmentUtil.toString(response));
+                } else if (string.contains(new StringBuffer(AttachmentUtil.MU_TEXT2))){
+                    // There are two headers and both need to be fixed-up
+                    String responseStr = AttachmentUtil.msgEnvMU2.replaceAll(
+                            AttachmentUtil.MUHEADER_CLIENT2,AttachmentUtil.MUHEADER_SERVER2);
+                    responseStr = responseStr.replaceAll(
+                            AttachmentUtil.MUHEADER_CLIENT,AttachmentUtil.MUHEADER_SERVER);
+                    response = AttachmentUtil.toSOAPMessage(responseStr);
+                    System.out.println("invoke: ---Response message= " + AttachmentUtil.toString(response));
                 } else if (string.contains(new StringBuffer(AttachmentUtil.MU_TEXT))) {
                     String responseStr =
                             AttachmentUtil.msgEnvMU.replaceAll(AttachmentUtil.MUHEADER_CLIENT,

Modified: webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java?rev=752251&r1=752250&r2=752251&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java Tue Mar 10 20:38:51 2009
@@ -366,6 +366,7 @@
             String log = readLogFile();
             String expected_calls = "AddNumbersClientLogicalHandler HANDLE_MESSAGE_OUTBOUND\n"
                     + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_OUTBOUND\n"
+                    + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                     + "AddNumbersLogicalHandler2 POST_CONSTRUCT\n"
                     + "AddNumbersProtocolHandler2 GET_HEADERS\n"
                     + "AddNumbersProtocolHandler GET_HEADERS\n"
@@ -382,7 +383,6 @@
                     + "AddNumbersProtocolHandler2 CLOSE\n"
                     + "AddNumbersProtocolHandler CLOSE\n"
                     + "AddNumbersProtocolHandler PRE_DESTROY\n"
-                    + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                     + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_INBOUND\n"
                     + "AddNumbersClientLogicalHandler HANDLE_MESSAGE_INBOUND\n"
                     + "AddNumbersClientProtocolHandler CLOSE\n"
@@ -422,6 +422,7 @@
             String log = readLogFile();
             String expected_calls = "AddNumbersClientLogicalHandler HANDLE_MESSAGE_OUTBOUND\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_OUTBOUND\n"
+                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersLogicalHandler2 POST_CONSTRUCT\n"
                 + "AddNumbersProtocolHandler2 GET_HEADERS\n"
                 + "AddNumbersProtocolHandler GET_HEADERS\n"
@@ -438,7 +439,6 @@
                 + "AddNumbersProtocolHandler2 CLOSE\n"
                 + "AddNumbersProtocolHandler CLOSE\n"
                 + "AddNumbersProtocolHandler PRE_DESTROY\n"
-                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_INBOUND\n"
                 + "AddNumbersClientLogicalHandler HANDLE_MESSAGE_INBOUND\n"
                 + "AddNumbersClientProtocolHandler CLOSE\n"
@@ -579,6 +579,7 @@
             String log = readLogFile();
             String expected_calls = "AddNumbersClientLogicalHandler HANDLE_MESSAGE_OUTBOUND\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_OUTBOUND\n"
+                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersLogicalHandler2 POST_CONSTRUCT\n"
                 + "AddNumbersProtocolHandler2 GET_HEADERS\n"
                 + "AddNumbersProtocolHandler GET_HEADERS\n"
@@ -595,7 +596,6 @@
                 + "AddNumbersProtocolHandler2 CLOSE\n"
                 + "AddNumbersProtocolHandler CLOSE\n"
                 + "AddNumbersProtocolHandler PRE_DESTROY\n"
-                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_INBOUND\n"
                 + "AddNumbersClientLogicalHandler HANDLE_MESSAGE_INBOUND\n"
                 + "AddNumbersClientProtocolHandler CLOSE\n"
@@ -639,6 +639,7 @@
             String log = readLogFile();
             String expected_calls = "AddNumbersClientLogicalHandler HANDLE_MESSAGE_OUTBOUND\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_OUTBOUND\n"
+                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersLogicalHandler2 POST_CONSTRUCT\n"
                 + "AddNumbersProtocolHandler2 GET_HEADERS\n"
                 + "AddNumbersProtocolHandler GET_HEADERS\n"
@@ -655,7 +656,6 @@
                 + "AddNumbersProtocolHandler2 CLOSE\n"
                 + "AddNumbersProtocolHandler CLOSE\n"
                 + "AddNumbersProtocolHandler PRE_DESTROY\n"
-                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_INBOUND\n"
                 + "AddNumbersClientLogicalHandler HANDLE_MESSAGE_INBOUND\n"
                 + "AddNumbersClientProtocolHandler CLOSE\n"
@@ -705,6 +705,7 @@
             String log = readLogFile();
             String expected_calls = "AddNumbersClientLogicalHandler HANDLE_MESSAGE_OUTBOUND\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_OUTBOUND\n"
+                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersLogicalHandler2 POST_CONSTRUCT\n"
                 + "AddNumbersProtocolHandler2 GET_HEADERS\n"
                 + "AddNumbersProtocolHandler GET_HEADERS\n"
@@ -721,7 +722,6 @@
                 + "AddNumbersProtocolHandler2 CLOSE\n"
                 + "AddNumbersProtocolHandler CLOSE\n"
                 + "AddNumbersProtocolHandler PRE_DESTROY\n"
-                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersClientProtocolHandler HANDLE_FAULT_INBOUND\n"
                 + "AddNumbersClientLogicalHandler HANDLE_FAULT_INBOUND\n"
                 + "AddNumbersClientProtocolHandler CLOSE\n"
@@ -821,6 +821,7 @@
             String expected_calls = "AddNumbersClientLogicalHandler HANDLE_MESSAGE_OUTBOUND\n"
                 + "AddNumbersClientLogicalHandler2 HANDLE_MESSAGE_OUTBOUND\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_OUTBOUND\n"
+                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersLogicalHandler2 POST_CONSTRUCT\n"
                 + "AddNumbersProtocolHandler2 GET_HEADERS\n"
                 + "AddNumbersProtocolHandler GET_HEADERS\n"
@@ -837,7 +838,6 @@
                 + "AddNumbersProtocolHandler2 CLOSE\n"
                 + "AddNumbersProtocolHandler CLOSE\n"
                 + "AddNumbersProtocolHandler PRE_DESTROY\n"
-                + "AddNumbersClientProtocolHandler GET_HEADERS\n"
                 + "AddNumbersClientProtocolHandler HANDLE_MESSAGE_INBOUND\n"
                 + "AddNumbersClientLogicalHandler2 HANDLE_MESSAGE_INBOUND\n"
                 + "AddNumbersClientLogicalHandler HANDLE_MESSAGE_INBOUND\n"

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java?rev=752251&r1=752250&r2=752251&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java Tue Mar 10 20:38:51 2009
@@ -35,8 +35,15 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import javax.xml.namespace.QName;
 import javax.xml.ws.AsyncHandler;
 import javax.xml.ws.Response;
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.soap.SOAPHandler;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set; 
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
@@ -78,6 +85,10 @@
                                                            false);
 
         if (success) {
+            // If there are any headers understood by handlers, then set a property
+            // on the message context so the response mustUnderstand processing takes those
+            // understood headers into consideration.
+            registerUnderstoodHeaders(request, ic.getHandlers()); 
             prepareRequest(request);
             response = doInvoke(request);
             prepareResponse(response);
@@ -199,6 +210,10 @@
                                                            HandlerChainProcessor.MEP.REQUEST,
                                                            false);
         if (success) {
+            // If there are any headers understood by handlers, then set a property
+            // on the message context so the response mustUnderstand processing takes those
+            // understood headers into consideration.
+            registerUnderstoodHeaders(request, ic.getHandlers()); 
             prepareRequest(request);
             resp = doInvokeAsync(request);
         } else
@@ -256,6 +271,10 @@
                                                            HandlerChainProcessor.MEP.REQUEST,
                                                            false);
         if (success) {
+            // If there are any headers understood by handlers, then set a property
+            // on the message context so the response mustUnderstand processing takes those
+            // understood headers into consideration.
+            registerUnderstoodHeaders(request, ic.getHandlers()); 
             prepareRequest(request);
             future = doInvokeAsync(request, asyncHandler);
         } else { // the outbound handler chain must have had a problem, and
@@ -299,4 +318,30 @@
      */
     protected abstract void prepareResponse(MessageContext mc);
 
+    private void registerUnderstoodHeaders(MessageContext request,
+                                           List<Handler> handlerList) {
+      if (handlerList != null && handlerList.size() > 0) {
+        Set<QName> understoodHeaders = new HashSet<QName>();
+        
+        // Add the headers from each of the SOAP handlers to the collection
+        for (Handler handler : handlerList) {
+          if(handler instanceof SOAPHandler){
+            SOAPHandler soapHandler = (SOAPHandler)handler;
+            Set<QName> headers = soapHandler.getHeaders();
+            if (headers != null && headers.size() > 0) {
+              understoodHeaders.addAll(headers);
+            }
+          }
+        }
+        
+        // Put the understood header qnames on the request context where it can
+        // be found during response processing.
+        if (understoodHeaders != null & understoodHeaders.size() > 0) {
+          if (log.isDebugEnabled()) {
+            log.debug("Adding understood header QName collection to message context " + understoodHeaders);
+          }
+          request.setProperty("client.UnderstoodHeaders", understoodHeaders);
+        }
+      }
+    }
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java?rev=752251&r1=752250&r2=752251&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java Tue Mar 10 20:38:51 2009
@@ -51,35 +51,6 @@
         else {
             // inbound response; must be on the client
             bindingProto = mepMessageCtx.getEndpointDesc().getClientBindingID();
-            // The getHeader processing is done on the server by the EndpointController.
-            // For messages inbound to the client (i.e. responses), we do it here since all three
-            // client JAX-WS APIs (i.e. sync, async, and async callback) use this method to 
-            // invoke the handlers.
-            List<QName> understood = new ArrayList<QName>();
-            for(Handler handler:handlers){
-                if(handler instanceof SOAPHandler){
-                    SOAPHandler soapHandler = (SOAPHandler)handler;
-                    //Invoking getHeaders.
-                    if(log.isDebugEnabled()){
-                        log.debug("Client side: Invoking getHeader() on SOAPHandler: " + soapHandler);
-                    }
-                    Set<QName> headers = soapHandler.getHeaders();
-                    if(headers!=null){
-                        for(QName header:headers){
-                            if(!understood.contains(header)){
-                                if(log.isDebugEnabled()){
-                                    log.debug("Adding Header QName" + header + " to uderstoodHeaderQName List");
-                                }
-                                //Adding this to understood header list.
-                                // FIXME: This list of headers undestood by the client inbound
-                                // JAX-WS handlers should be used in client-side inbound 
-                                // mustUnderstand header processing.
-                                understood.add(header);
-                            }
-                        }
-                    }
-                }
-            }
         }
         Protocol proto = Protocol.getProtocolForBinding(bindingProto);
         

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/engine/AxisEngine.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/engine/AxisEngine.java?rev=752251&r1=752250&r2=752251&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/engine/AxisEngine.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/engine/AxisEngine.java Tue Mar 10 20:38:51 2009
@@ -23,6 +23,7 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import javax.xml.namespace.QName;
 
@@ -80,6 +81,10 @@
                 continue;
             }
 
+            if (clientHandlerUnderstandsHeader(headerBlock, msgContext)) {
+                continue;
+            }
+            
             if(LoggingControl.debugLoggingAllowed && log.isDebugEnabled()){
                 log.debug("MustUnderstand header not processed or registered as understood"+headerName);
             }
@@ -649,4 +654,56 @@
             }
         }
     }
+    
+    /**
+     * Answer if an application handler (such as a JAXWS application handler) has registered that 
+     * it understands this header. Note that the handlers do this registration only on the 
+     * service-requester side.  That is because on the service-provider side the handlers have
+     * not been instantiated at this point so can not be queried yet. 
+     * @param headerBlock Contains the SOAP header to check
+     * @param messageContext Contains the inbound message context
+     * @return true if this header QName is registered as being understood or false otherwise.
+     */
+    private static boolean clientHandlerUnderstandsHeader(SOAPHeaderBlock headerBlock, 
+            MessageContext messageContext) {
+        boolean headerUnderstood = false;
+        // Get the property off the outbound context, if it exists and contains this header
+        // then it is understood
+        QName headerQName = headerBlock.getQName();
+        Set understoodHeaders = getUnderstoodClientHeaders(messageContext);
+        if (understoodHeaders != null && understoodHeaders.size() > 0) {
+            headerUnderstood = understoodHeaders.contains(headerQName);
+        }
+        return headerUnderstood;
+    }
+    
+    /**
+     * Get the collection of Header QNames that are registered as being understood.
+     * This assumes that a Set of QNames which indicates what headers are "understood" by
+     * this particular client through the client's programming model (i.e. application
+     * handlers) has been defined and stored on the outbound MessageContext under the
+     * client.UnderstoodHeaders property. 
+     * @param msgContext The inbound message context
+     * @return a Set of Header QNames that have been registered as understood, or null if
+     * none have been registered.
+     */
+    private static Set getUnderstoodClientHeaders(MessageContext msgContext) {
+        Set returnQN = null;
+        // The client sets the property on the JAX-WS Request Message Context, which will be copied
+        // to the Axis2 outbound message context.
+        OperationContext opCtx = msgContext.getOperationContext();
+        MessageContext outboundMC = null;
+        try {
+            outboundMC = opCtx.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
+        }
+        catch (AxisFault af) {
+            // Ignore this; it means that there wasn't an outbound message for this operation.
+        }
+        if (outboundMC != null) {
+            returnQN = 
+                (Set) outboundMC.getProperty("client.UnderstoodHeaders");
+        }
+        return returnQN;
+    }
+
 }