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 sc...@apache.org on 2009/09/21 23:40:54 UTC

svn commit: r817419 - in /webservices/axis2/trunk/java/modules: jaxws-integration/test/org/apache/axis2/jaxws/sample/ jaxws/src/org/apache/axis2/datasource/jaxb/ jaxws/src/org/apache/axis2/jaxws/ jaxws/src/org/apache/axis2/jaxws/handler/ jaxws/test/org...

Author: scheu
Date: Mon Sep 21 21:40:52 2009
New Revision: 817419

URL: http://svn.apache.org/viewvc?rev=817419&view=rev
Log:
AXIS-4502
Contributor:Rich Scheuerle
Added "jaxws.payload.highFidelity" property and configuration parameter.
An administrator can set this on the Axis2Configuration.
A programmer can set this on a JAX-WS BindingProvider RequestContext.
(I am not aware of a programatic way in JAX-WS to set this on a inbound context on the server...the @WebServiceContext is 
a mechanism to pass the MessageContext to the @WebMethod, but there is no way to set a property to affect behavior
on the chain...so for now we are limited to a ConfigurationParameter.)

Modified:
    webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/WrapTests.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBCustomBuilder.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerUtils.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/datasource/jaxb/JAXBCustomBuilderDisableStreamingTests.java

Modified: webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/WrapTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/WrapTests.java?rev=817419&r1=817418&r2=817419&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/WrapTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/WrapTests.java Mon Sep 21 21:40:52 2009
@@ -432,6 +432,49 @@
         }
         
         /**
+         * Test to validate whether a JAXBCustomBuilder is plugged and used
+         * on the client
+         */
+        public void testJAXBCB_Client_withHighFidelity(){
+            TestLogger.logger.debug("------------------------------");
+            TestLogger.logger.debug("Test  : " + getName());
+            try{
+                String reqString = "JAXBCustomBuilderClient";
+                DocLitWrap proxy = getProxy();
+                
+                BindingProvider p = (BindingProvider) proxy;
+                p.getRequestContext().put(org.apache.axis2.jaxws.Constants.JAXWS_PAYLOAD_HIGH_FIDELITY, Boolean.TRUE);
+                
+                // Start Monitoring
+                JAXBCustomBuilderMonitor.setMonitoring(true);
+                JAXBCustomBuilderMonitor.clear();
+                
+                // Invoke the web services
+                proxy.twoWay(reqString);
+                
+                // The second invoke should trigger the fast
+                // unmarshalling of the response
+                proxy.twoWay(reqString);
+                
+                
+                // The returned response unmarshalling should try
+                // the JAXBCustomBuilder
+                int totalBuilders = JAXBCustomBuilderMonitor.getTotalBuilders();
+                assertTrue(totalBuilders >= 1);
+                int totalCreates = JAXBCustomBuilderMonitor.getTotalCreates();
+                assertTrue("Expected 0, but received " + totalCreates, totalCreates == 0);
+                
+                TestLogger.logger.debug("------------------------------");
+                
+            }catch(Exception e){
+                e.printStackTrace();
+                fail();
+            } finally {
+                JAXBCustomBuilderMonitor.setMonitoring(false);
+            }
+        }
+        
+        /**
          * Test to validate whether a JAXBCustomBuilder is plugged in
          * on the client.  Also makes sure that the JAXBCustomBuilder
          * falls back to normal processing when faults are thrown.

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBCustomBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBCustomBuilder.java?rev=817419&r1=817418&r2=817419&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBCustomBuilder.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBCustomBuilder.java Mon Sep 21 21:40:52 2009
@@ -29,6 +29,7 @@
 import org.apache.axiom.om.impl.builder.CustomBuilder;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.jaxws.Constants;
+import org.apache.axis2.jaxws.handler.HandlerUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -105,21 +106,14 @@
      * @return true if this ns and local part is acceptable for unmarshalling
      */
     private boolean shouldUnmarshal(String namespace, String localPart) {
-        Object value = null;
-        MessageContext msgCtx = jdsContext.getMessageContext();
-        if (msgCtx != null) {
-            value = msgCtx.getProperty(Constants.JAXWS_ENABLE_JAXB_PAYLOAD_STREAMING);
-        }
-        if (value != null && value instanceof Boolean) {
-            boolean streamingEnabled = ((Boolean) value).booleanValue();
-            if (!streamingEnabled) {
-                if (log.isDebugEnabled()) {
-                    log.debug("JAXB payload streaming disabled by messageContext property "
-                              + Constants.JAXWS_ENABLE_JAXB_PAYLOAD_STREAMING
-                              + " set to " + streamingEnabled);
-                }
-                return false;
+        boolean isHighFidelity = HandlerUtils.isHighFidelity(jdsContext.getMessageContext());
+
+        if (isHighFidelity) {
+            if (log.isDebugEnabled()) {
+                log.debug("JAXB payload streaming disabled because high fidelity messages are requested.");
             }
+            return false;
+
         }
         
         // Don't unmarshall SOAPFaults or anything else in the SOAP 

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java?rev=817419&r1=817418&r2=817419&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java Mon Sep 21 21:40:52 2009
@@ -44,9 +44,40 @@
      * objects.
      * 
      * The default value is Boolean(true) if this property is not set.  
+     * @deprecated see JAXWS_PAYLOAD_HIGH_FIDELITY
      */
     public static final String JAXWS_ENABLE_JAXB_PAYLOAD_STREAMING = 
         "org.apache.axis2.jaxws.enableJAXBPayloadStreaming";
+    
+    /**
+     * Context Property:
+     * Name: jaxws.payload.highFidelity
+     * Value: Boolean.TRUE or Boolean.FALSE
+     * Default: null, which is interpreted as FALSE....engine may set this to TRUE in some cases.
+     * 
+     * Configuration Parameter
+     * Name: jaxws.payload.highFidelity
+     * Value: String or Boolean representing true or false
+     * Default: null, which is interpreted as FALSE
+     * 
+     * Description:
+     * If the value is false, the jax-ws engine will transform the message in the most
+     * performant manner.  In some cases these transformations will cause the loss of some information.
+     * For example, JAX-B transformations are lossy.  
+     * 
+     * If the value is true, the jax-ws engine will transform the message in the most loss-less manner.
+     * In some cases this will result in slower performance.  The message in such cases is "high fidelity",
+     * which means that it is a close replica of the original message.
+     * 
+     * Customers should accept the default behavior (false), and only set the value to true if it is
+     * necessary for a SOAP Handler or other code requires a high fidelity message.
+     * 
+     * The engine will first examine the Context property.  If not set, the value of the Configuration
+     * property is used.
+     */
+    public static final String JAXWS_PAYLOAD_HIGH_FIDELITY =
+        "jaxws.payload.highFidelity";
+    
     public static final String MEP_CONTEXT = 
         "org.apache.axis2.jaxws.handler.MEPContext";
     

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerUtils.java?rev=817419&r1=817418&r2=817419&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerUtils.java Mon Sep 21 21:40:52 2009
@@ -28,11 +28,14 @@
 import org.apache.axis2.AxisFault;
 import org.apache.axis2.Constants;
 import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.context.OperationContext;
 import org.apache.axis2.description.AxisService;
 import org.apache.axis2.description.Parameter;
 import org.apache.axis2.i18n.Messages;
 import org.apache.axis2.jaxws.description.EndpointDescription;
+import org.apache.axis2.util.JavaUtils;
 import org.apache.axis2.util.LoggingControl;
+import org.apache.axis2.wsdl.WSDLConstants;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -223,7 +226,131 @@
         }
 
     }
+
+    /**
+     * isHighFidelity
+     * 
+     * The JAX-WS engine attempts to stream data as fast as possible.
+     * For example, the message payload may be transformed into a JAXB object early in the processing.
+     * Unfortunately such transformations are lossy, some information is lost.
+     * An installed SOAP handler will see different namespaces (etc) then the original message.
+     * 
+     * If the a customer enables the "jaxws.payload.highFidelity" flag, then lossy transformations are
+     * avoided until necessary.  
+     * 
+     * @see Constants.JAXWS_HIGH_FIDELITY
+     * 
+     * @param mc
+     * @return true if high fidelity is requested
+     */
+    public static boolean isHighFidelity(MessageContext mc) {
+        boolean rc = _isHighFidelity(mc);
+        
+        // If not true, check the OUT MessageContext.
+        // On the client, we need this setting when we receive (inbound)
+        // the message; however the customer set it on the outbound context.
+        if (!rc) {
+            rc = _isHighFidelity(getRelatedMessageContext(mc));
+        }
+        return rc;
+    }
+    
+    /**
+     * @param mc
+     * @return
+     */
+    private static MessageContext getRelatedMessageContext(MessageContext mc) {
+        if (log.isDebugEnabled()) {
+            log.debug("Enter getRelatedMessageContext for:" + mc);
+        }
+        MessageContext relatedMC = null;
+        if (mc != null) {
+            OperationContext oc = mc.getOperationContext();
+            if (oc != null) {
+                try {
+                    relatedMC = oc.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+                    if (relatedMC == mc) {
+                        relatedMC = oc.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
+                    }
+                } catch (AxisFault e) {
+                    // TODO This should never occur in this scenario, swallow and continue
+                }
+            }
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Exit getRelatedMessageContext related messageContext is" + relatedMC);
+        }
+        return relatedMC;
+    }
+
+    /**
+     * isHighFidelity
+     * 
+     * The JAX-WS engine attempts to stream data as fast as possible.
+     * For example, the message payload may be transformed into a JAXB object early in the processing.
+     * Unfortunately such transformations are lossy, some information is lost.
+     * An installed SOAP handler will see different namespaces (etc) then the original message.
+     * 
+     * If the a customer enables the "jaxws.payload.highFidelity" flag, then lossy transformations are
+     * avoided until necessary.  
+     * 
+     * @see Constants.JAXWS_HIGH_FIDELITY
+     * 
+     * @param mc
+     * @return true if high fidelity is requested
+     */
+    private static boolean _isHighFidelity(MessageContext mc) {
+        
+        boolean value = false;
+        if (mc == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("_isHighFidelity returns false due to missing MessageContext");
+            }
+            return false;
+        }
+        
+        // First examine the high fidelity flag on the context hierarchy
+        Boolean highFidelity = (Boolean) mc.getProperty(
+                org.apache.axis2.jaxws.Constants.JAXWS_PAYLOAD_HIGH_FIDELITY);
+        if (highFidelity != null) {
+            value = highFidelity.booleanValue();
+            if (log.isDebugEnabled()) {
+                log.debug("_isHighFidelity returns " + value + " per Context property " + 
+                        org.apache.axis2.jaxws.Constants.JAXWS_PAYLOAD_HIGH_FIDELITY);
+            }
+            return value;
+        }
+        
+        // Second examine the deprecated jaxb streaming flag
+        Boolean jaxbStreaming = (Boolean) mc.getProperty(
+                org.apache.axis2.jaxws.Constants.JAXWS_ENABLE_JAXB_PAYLOAD_STREAMING);
+        if (jaxbStreaming != null) {
+            value = !jaxbStreaming.booleanValue();
+            if (log.isDebugEnabled()) {
+                log.debug("_isHighFidelity returns " + value + " per inspection of Context property " + 
+                        org.apache.axis2.jaxws.Constants.JAXWS_ENABLE_JAXB_PAYLOAD_STREAMING);
+            }
+            return value;
+        }
+        
+        // Now look at the high fidelity parameter
+        Parameter p = mc.getParameter(org.apache.axis2.jaxws.Constants.JAXWS_PAYLOAD_HIGH_FIDELITY);
+        if (p != null) {
+            value = JavaUtils.isTrue(p.getValue());
+            if (log.isDebugEnabled()) {
+                log.debug("_isHighFidelity returns " + value + " per inspection of Configuration property " + 
+                        org.apache.axis2.jaxws.Constants.JAXWS_PAYLOAD_HIGH_FIDELITY);
+            }
+            return value;
+        }
+        
+        if (log.isDebugEnabled()) {
+            log.debug("_isHighFidelity returns the default: false");
+        }
+        return false;
+    }
 }
+
 class HandlerRolePlayer implements RolePlayer {
     List<String> roles = new ArrayList<String>();
 

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java?rev=817419&r1=817418&r2=817419&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java Mon Sep 21 21:40:52 2009
@@ -129,8 +129,6 @@
 
     // These @Override annotations break JDK 1.5 compilation... AFAIK we have not discussed
     // forcing Axis2 devs to JDK 1.6, so commenting them out for now... --gdaniels
-
-    // @Override
     public void clear() {
         // Throw unsupported operation exception per Map javadoc
         // for any method that is not supported.
@@ -141,13 +139,11 @@
         throw new UnsupportedOperationException();
     }
     
-    // @Override
     public boolean containsKey(Object key) {
         Set<QName> keys = this.keySet();
         return keys.contains(key);
     }
     
-    // @Override
     public boolean containsValue(Object value) {
         Set<QName> keys = this.keySet();
         for(QName key: keys) {
@@ -162,7 +158,6 @@
     }
     
 
-    // @Override
     public Set<Entry<QName, List<String>>> entrySet() {
         // Previous implementation of this method called tempMap.putAll(this), which resulted
         // in an infinite loop due to Map calling back into this entrySet() method.  So, don't do that!
@@ -183,7 +178,6 @@
      * headers on the message.
      * @param _key Object -- QName key of header XML strings you intend to retrieve
      */
-    // @Override
     public List<String> get(Object _key) {
         // notify the HandlerChainProcessor that a transformation has occurred possibly due to a handler method call into here
         HandlerChainProcessor.trackInternalCall(mc, HandlerChainProcessor.TRACKER.SOAP_HEADERS_ADAPTER_CALLED);
@@ -216,12 +210,10 @@
         }
     }
     
-    // @Override
     public boolean isEmpty() {
         return this.keySet().isEmpty();
     }
     
-    // @Override
     public Set<QName> keySet() {
         // notify the HandlerChainProcessor that a transformation has occurred possibly due to a handler method call into here
         HandlerChainProcessor.trackInternalCall(mc, HandlerChainProcessor.TRACKER.SOAP_HEADERS_ADAPTER_CALLED);
@@ -234,7 +226,6 @@
      * @param key Object -- QName key of header XML strings you wish to be put on the SOAP header
      * @param values List<String> -- list of XML strings that have the same namespace as the QName key
      */
-    // @Override
     public List<String> put(QName key, List<String> values) {
         // notify the HandlerChainProcessor that a transformation has occurred possibly due to a handler method call into here
         HandlerChainProcessor.trackInternalCall(mc, HandlerChainProcessor.TRACKER.SOAP_HEADERS_ADAPTER_CALLED);
@@ -265,7 +256,6 @@
     /**
      * putAll will inject the headers into the SOAP message immediately
      */
-    // @Override
     public void putAll(Map<? extends QName, ? extends List<String>> t) {
         for(Entry<? extends QName, ? extends List<String>> entry: t.entrySet()) {
             QName key = entry.getKey();
@@ -279,7 +269,6 @@
      * remove will immediately remove the headers from the SOAP message that match the QName key
      * @param _key Object -- QName key of header XML strings you wish to remove from the SOAP header
      */
-    // @Override
     public List<String> remove(Object _key) {
         // notify the HandlerChainProcessor that a transformation has occurred possibly due to a handler method call into here
         HandlerChainProcessor.trackInternalCall(mc, HandlerChainProcessor.TRACKER.SOAP_HEADERS_ADAPTER_CALLED);
@@ -326,12 +315,10 @@
     	
     }
     
-    // @Override
     public int size() {
         return this.keySet().size();
     }
     
-    // @Override
     public Collection<List<String>> values() {
     	/*
     	 * Previous implementation of this method called tempMap.putAll(this), which resulted

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/datasource/jaxb/JAXBCustomBuilderDisableStreamingTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/datasource/jaxb/JAXBCustomBuilderDisableStreamingTests.java?rev=817419&r1=817418&r2=817419&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/datasource/jaxb/JAXBCustomBuilderDisableStreamingTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/datasource/jaxb/JAXBCustomBuilderDisableStreamingTests.java Mon Sep 21 21:40:52 2009
@@ -19,6 +19,7 @@
 package org.apache.axis2.datasource.jaxb;
 
 import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisService;
 import org.apache.axis2.jaxws.Constants;
 
 import javax.xml.namespace.NamespaceContext;
@@ -50,6 +51,42 @@
         }
     }
     
+    public void testDisableJAXBPayloadStreamingWithHighFidelity() {
+        
+        JAXBDSContext jaxbDSC = new JAXBDSContext(null, null);
+        JAXBCustomBuilder jaxbCB = new JAXBCustomBuilder(jaxbDSC);
+        MessageContext msgCtx = new MessageContext();
+        // Disable the JAXB Payload streaming
+        msgCtx.setProperty(Constants.JAXWS_PAYLOAD_HIGH_FIDELITY, new Boolean(true));
+        jaxbDSC.setMessageContext(msgCtx);
+        try {
+            assertNull(jaxbCB.create("ns", "lp", null, new MockXMLStreamReader(), null));
+        } catch (Exception e) {
+            // Since we didn't set up the JAXBDSContext fully, if the disabling of it didn't
+            // work, then we'll get some sort of exception.
+            fail("JAXB Payload streaming was not disabled");
+        }
+    }
+    
+    public void testDisableJAXBPayloadStreamingWithHighFidelityParameter() throws Exception {
+        
+        JAXBDSContext jaxbDSC = new JAXBDSContext(null, null);
+        JAXBCustomBuilder jaxbCB = new JAXBCustomBuilder(jaxbDSC);
+        MessageContext msgCtx = new MessageContext();
+        AxisService service = new AxisService();
+        msgCtx.setAxisService(service);
+        service.addParameter(Constants.JAXWS_PAYLOAD_HIGH_FIDELITY, "true");
+        
+        jaxbDSC.setMessageContext(msgCtx);
+        try {
+            assertNull(jaxbCB.create("ns", "lp", null, new MockXMLStreamReader(), null));
+        } catch (Exception e) {
+            // Since we didn't set up the JAXBDSContext fully, if the disabling of it didn't
+            // work, then we'll get some sort of exception.
+            fail("JAXB Payload streaming was not disabled");
+        }
+    }
+    
     public void testDefaultJAXBPayloadStreaming() {
         
         JAXBDSContext jaxbDSC = new JAXBDSContext(null, null);