You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Daniel Kulp <dk...@apache.org> on 2014/11/29 00:04:28 UTC

Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

I’m -1 on the part of this that changes the IN to an OUT on the client side.   The IN and OUT are specifically named that way as they apply to the messages that come IN to the client or IN to the server.   The “IN” validation should definitely not be applying to the messages going OUT.  Plus, that would be a huge behavioral change that would break many peoples existing applications.

Dan




> On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
> 
> Repository: cxf
> Updated Branches:
>  refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
> 
> 
> CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level
> 
> 
> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
> 
> Branch: refs/heads/2.7.x-fixes
> Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
> Parents: e172a3e
> Author: Jason Pell <jp...@apache.org>
> Authored: Thu Nov 27 16:54:01 2014 +1100
> Committer: Jason Pell <jp...@apache.org>
> Committed: Fri Nov 28 15:52:36 2014 +1100
> 
> ----------------------------------------------------------------------
> .../validation/SchemaValidationFeature.java     |   2 +-
> .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
> .../AbstractInDatabindingInterceptor.java       |  23 +-
> .../AbstractOutDatabindingInterceptor.java      |  22 +-
> .../java/org/apache/cxf/message/Message.java    |   9 +
> .../soap/interceptor/RPCInInterceptor.java      |   2 +-
> .../factory/AnnotationsFactoryBeanListener.java |   9 +-
> .../JavaFirstSchemaValidationTest.java          | 256 ++++++++++++++-----
> .../jaxws/schemavalidation/PersonService.java   |  13 +-
> .../PersonServiceAnnotated.java                 |  13 +-
> .../PersonServiceAnnotatedImpl.java             |  15 +-
> .../schemavalidation/PersonServiceImpl.java     |  12 +-
> .../MTOMProviderSchemaValidationTest.bak        |  69 -----
> 13 files changed, 342 insertions(+), 201 deletions(-)
> ----------------------------------------------------------------------
> 
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> ----------------------------------------------------------------------
> diff --git a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> index 5eda79c..c314eaf 100644
> --- a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> +++ b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends AbstractFeature {
>         for (BindingOperationInfo bop : endpoint.getEndpointInfo().getBinding().getOperations()) {
>             SchemaValidationType type = provider.getSchemaValidationType(bop.getOperationInfo());
>             if (type != null) {
> -                bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED, type);
> +                bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE, type);
>             }
>         }
>     }
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> ----------------------------------------------------------------------
> diff --git a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> index 85d77d0..28c7ba2 100644
> --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
> import javax.xml.namespace.QName;
> 
> import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> +import org.apache.cxf.endpoint.Endpoint;
> +import org.apache.cxf.message.Exchange;
> import org.apache.cxf.message.Message;
> +import org.apache.cxf.message.MessageUtils;
> +import org.apache.cxf.service.model.AbstractPropertiesHolder;
> +import org.apache.cxf.service.model.BindingOperationInfo;
> +import org.apache.cxf.service.model.EndpointInfo;
> +import org.apache.cxf.service.model.OperationInfo;
> 
> public final class ServiceUtils {
> -    
>     private ServiceUtils() {
>     }
> 
> @@ -42,24 +48,94 @@ public final class ServiceUtils {
>      * @param type
>      */
>     public static boolean isSchemaValidationEnabled(SchemaValidationType type, Message message) {
> -        SchemaValidationType messageType = getSchemaValidationType(message);
> +        SchemaValidationType validationType = getSchemaValidationType(message);
> 
> -        return messageType.equals(type) 
> +        return validationType.equals(type) 
>             || ((SchemaValidationType.IN.equals(type) || SchemaValidationType.OUT.equals(type))
> -                && SchemaValidationType.BOTH.equals(messageType));
> +                && SchemaValidationType.BOTH.equals(validationType));
>     }
> -    
> +
>     /**
> -     * Determines the appropriate SchemaValidationType to return based on either
> -     * a Boolean (for backwards compatibility) or the selected Schema Validation Type.
> -     * 
> -     * Package private as the isSchemaValidationEnabled method should be used instead.  Only
> -     * visible for easier testing
> +     * A convenience method to check for schema validation config in the message context, and then in the service model.
> +     * Does not modify the Message context (other than what is done in the getContextualProperty itself)
>      * 
>      * @param message
> +     * @param type
>      */
> -    static SchemaValidationType getSchemaValidationType(Message message) {
> +    public static SchemaValidationType getSchemaValidationType(Message message) {
> +        SchemaValidationType validationType = getOverrideSchemaValidationType(message);
> +        if (validationType == null) {
> +            validationType = getSchemaValidationTypeFromModel(message);
> +        } 
> +        
> +        if (validationType == null) {
> +            validationType = SchemaValidationType.NONE;
> +        }
> +        
> +        return validationType;
> +    }
> +    
> +    private static SchemaValidationType getOverrideSchemaValidationType(Message message) {
>         Object obj = message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
> +        if (obj != null) {
> +            // this method will transform the legacy enabled as well
> +            return getSchemaValidationType(obj);
> +        } else {
> +            return null;
> +        }
> +    }
> +    
> +    private static SchemaValidationType getSchemaValidationTypeFromModel(Message message) {
> +        boolean isRequestor = MessageUtils.isRequestor(message);
> +        Exchange exchange = message.getExchange();
> +        
> +        if (exchange != null) {
> +            BindingOperationInfo boi = exchange.getBindingOperationInfo();
> +            Endpoint endpoint = exchange.getEndpoint();
> +            
> +            if (boi != null && endpoint != null) {
> +                SchemaValidationType validationType = null;
> +                OperationInfo opInfo = boi.getOperationInfo();
> +                EndpointInfo ep = endpoint.getEndpointInfo();
> +                
> +                if (validationType == null && opInfo != null) {
> +                    validationType = getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
> +                    
> +                    if (validationType == null && ep != null) {
> +                        validationType = getSchemaValidationTypeFromModel(message, ep, isRequestor);
> +                    }
> +                }
> +                
> +                return validationType;
> +            }
> +        }
> +        
> +        // else
> +        return null;
> +    }
> +    
> +    private static SchemaValidationType getSchemaValidationTypeFromModel(
> +            Message message, AbstractPropertiesHolder properties, boolean isRequestor) {
> +        Object obj = properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
> +        if (obj != null) {
> +            SchemaValidationType validationType = getSchemaValidationType(obj);
> +            
> +            // Reverse the direction of any IN / OUT for requestor (client)
> +            if (isRequestor) {
> +                if (SchemaValidationType.IN.equals(validationType)) {
> +                    return SchemaValidationType.OUT;
> +                } else if (SchemaValidationType.OUT.equals(validationType)) {
> +                    return SchemaValidationType.IN;
> +                }
> +            }
> +
> +            return validationType;
> +        } else {
> +            return null;
> +        }
> +    }
> +    
> +    public static SchemaValidationType getSchemaValidationType(Object obj) {
>         if (obj instanceof SchemaValidationType) {
>             return (SchemaValidationType)obj;
>         } else if (obj != null) { 
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> ----------------------------------------------------------------------
> diff --git a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> index c47417a..ec8cf71 100644
> --- a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> +++ b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> @@ -125,24 +125,9 @@ public abstract class AbstractInDatabindingInterceptor extends AbstractPhaseInte
>         }
>     }
> 
> -    /**
> -     * Where an operation level validation type has been set, copy it to the message, so it can be interrogated
> -     * by all downstream interceptors.  It is expected that sub classes will call setDataReaderValidation subsequent
> -     * to this to ensure the DataReader schema reference is updated as appropriate.
> -     * 
> -     * @param bop
> -     * @param message
> -     * @param reader
> -     * @see #setDataReaderValidation(Service, Message, DataReader)
> -     */
> -    protected void setOperationSchemaValidation(OperationInfo opInfo, Message message) {
> -        if (opInfo != null) {
> -            SchemaValidationType validationType = 
> -                (SchemaValidationType) opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> -            if (validationType != null) {
> -                message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
> -            }
> -        }
> +    protected void setOperationSchemaValidation(Message message) {
> +        SchemaValidationType validationType = ServiceUtils.getSchemaValidationType(message);
> +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
>     }
> 
>     protected DepthXMLStreamReader getXMLStreamReader(Message message) {
> @@ -247,7 +232,7 @@ public abstract class AbstractInDatabindingInterceptor extends AbstractPhaseInte
>         }
> 
>         // configure endpoint and operation level schema validation
> -        setOperationSchemaValidation(operation.getOperationInfo(), message);
> +        setOperationSchemaValidation(message);
> 
>         QName serviceQName = si.getName();
>         message.put(Message.WSDL_SERVICE, serviceQName);
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> ----------------------------------------------------------------------
> diff --git a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> index db3ba6c..52d1cb1 100644
> --- a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> +++ b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
> import org.apache.cxf.service.model.BindingInfo;
> import org.apache.cxf.service.model.BindingOperationInfo;
> import org.apache.cxf.service.model.MessagePartInfo;
> -import org.apache.cxf.service.model.OperationInfo;
> import org.apache.cxf.staxutils.CachingXmlEventWriter;
> import org.apache.cxf.staxutils.StaxUtils;
> import org.apache.cxf.wsdl.EndpointReferenceUtils;
> @@ -85,7 +84,7 @@ public abstract class AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>         CachingXmlEventWriter cache = null;
> 
>         // configure endpoint and operation level schema validation
> -        setOperationSchemaValidation(operation.getOperationInfo(), message);
> +        setOperationSchemaValidation(message);
> 
>         // need to cache the events in case validation fails or buffering is enabled
>         if (shouldBuffer(message)) {
> @@ -159,22 +158,9 @@ public abstract class AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>         }
>     }
> 
> -    /**
> -     * Where an operation level validation type has been set, copy it to the message, so it can be interrogated
> -     * by all downstream interceptors
> -     * 
> -     * @param bop
> -     * @param message
> -     * @param reader
> -     */
> -    private void setOperationSchemaValidation(OperationInfo opInfo, Message message) {
> -        if (opInfo != null) {
> -            SchemaValidationType validationType = 
> -                (SchemaValidationType) opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> -            if (validationType != null) {
> -                message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
> -            }
> -        }
> +    protected void setOperationSchemaValidation(Message message) {
> +        SchemaValidationType validationType = ServiceUtils.getSchemaValidationType(message);
> +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
>     }
> 
>     protected boolean shouldValidate(Message m) {
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
> ----------------------------------------------------------------------
> diff --git a/api/src/main/java/org/apache/cxf/message/Message.java b/api/src/main/java/org/apache/cxf/message/Message.java
> index 35e94af..5854a18 100644
> --- a/api/src/main/java/org/apache/cxf/message/Message.java
> +++ b/api/src/main/java/org/apache/cxf/message/Message.java
> @@ -105,7 +105,16 @@ public interface Message extends StringMap {
>      */
>     String MTOM_ENABLED = "mtom-enabled";
>     String MTOM_THRESHOLD = "mtom-threshold";
> +    
> +    /**
> +     * Runtime schema validation property
> +     */
>     String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
> +    
> +    /**
> +     * The default values for schema validation will be set in the service model using this property
> +     */
> +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
> 
>     /**
>      * Boolean property specifying if the Java stack trace is returned as a  
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> ----------------------------------------------------------------------
> diff --git a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> index fafd0a9..d49f090 100644
> --- a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> +++ b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> @@ -226,6 +226,6 @@ public class RPCInInterceptor extends AbstractInDatabindingInterceptor {
>         message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
> 
>         // configure endpoint and operation level schema validation
> -        setOperationSchemaValidation(operation.getOperationInfo(), message);        
> +        setOperationSchemaValidation(message);
>     }    
> }
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> ----------------------------------------------------------------------
> diff --git a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> index 7100f2c..9a7cbc8 100644
> --- a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> +++ b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener implements FactoryBeanListener {
>             // if someone has gone to the effort of specifying enabled=false, then we need to
>             // handle that, otherwise we use the new SchemaValidationType type only
>             if (!annotation.enabled()) {
> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED, SchemaValidationType.NONE);
> +                endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE, SchemaValidationType.NONE);
>             } else {
> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED, annotation.type());
> +                endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE, annotation.type());
>             }
>         }
>     }
> @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener implements FactoryBeanListener {
>     }
> 
>     private void addSchemaValidationSupport(OperationInfo inf, SchemaValidation annotation) {
> -        // Notice no support for deprecated enabled property here!
> -        // TODO - should we check for the use of this property and at least log the fact we are
> -        // ignoring it
>         if (annotation != null) {
> -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED, annotation.type());
> +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE, annotation.type());
>         }
>     }
> 
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> index 888e5a8..9f08839 100644
> --- a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> @@ -20,12 +20,15 @@
> package org.apache.cxf.systest.jaxws.schemavalidation;
> 
> import java.io.IOException;
> +import java.io.PrintWriter;
> +import java.io.StringWriter;
> import java.util.ArrayList;
> import java.util.Arrays;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> 
> +import javax.xml.ws.WebServiceException;
> import javax.xml.ws.soap.SOAPFaultException;
> 
> import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
> import org.apache.cxf.message.Message;
> -import org.apache.cxf.service.model.BindingOperationInfo;
> import org.apache.cxf.testutil.common.TestUtil;
> +import org.apache.cxf.transport.http.HTTPConduit;
> +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
> import org.junit.AfterClass;
> import org.junit.Assert;
> import org.junit.BeforeClass;
> import org.junit.Test;
> 
> -/**
> - * TODO - test where the default is NONE at the service level test where the default is IN or OUT, and then
> - * override at operation levels
> - */
> public class JavaFirstSchemaValidationTest extends Assert {
> -    static final String PORT = TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
> +    static final String PORT = TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> +    static final String PORT_UNUSED = TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> 
>     private static List<Server> serverList = new ArrayList<Server>();
>     private static PersonServiceAnnotated annotatedClient;
> +    private static PersonServiceAnnotated annotatedValidatingClient;
>     private static PersonService client;
>     private static PersonServiceRPC rpcClient;
> +    
> +    private static PersonService disconnectedClient;
> 
>     @BeforeClass
>     public static void startServers() throws Exception {
> @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends Assert {
> 
>         createServer(PersonServiceRPC.class, new PersonServiceRPCImpl(), feature, new LoggingFeature());
> 
> -        annotatedClient = createClient(PersonServiceAnnotated.class);
> -        client = createClient(PersonService.class);
> -        rpcClient = createClient(PersonServiceRPC.class);
> +        annotatedClient = createClient(PORT, PersonServiceAnnotated.class, SchemaValidationType.NONE);
> +        annotatedValidatingClient = createClient(PORT, PersonServiceAnnotated.class, null);
> +        client = createClient(PORT, PersonService.class, SchemaValidationType.NONE);
> +        disconnectedClient = createClient(PORT_UNUSED, PersonService.class, SchemaValidationType.OUT);
> +        rpcClient = createClient(PORT, PersonServiceRPC.class, SchemaValidationType.NONE);
>     }
> 
>     @AfterClass
> @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends Assert {
>         }
>     }
> 
> -    static String getAddress(Class<?> sei) {
> -        return "http://localhost:" + PORT + "/" + sei.getSimpleName();
> +    static String getAddress(String port, Class<?> sei) {
> +        return "http://localhost:" + port + "/" + sei.getSimpleName();
>     }
> -    
> 
>     @Test
>     public void testRPCLit() throws Exception { 
> @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest extends Assert {
>         try {
>             person.setFirstName(null);
>             rpcClient.saveValidateOut(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
>             assertTrue(sfe.getMessage().contains("Marshalling Error"));
>             assertTrue(sfe.getMessage().contains("lastName"));
>         }            
> @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest extends Assert {
> 
>         try {
>             annotatedClient.saveInheritEndpoint(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
> -            assertTrue(sfe.getMessage().contains("Unmarshalling Error"));
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>         }
> 
>         try {
>             person.setFirstName(""); // empty string is valid
>             annotatedClient.saveInheritEndpoint(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
> -            assertTrue(sfe.getMessage().contains("Unmarshalling Error"));
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>         }
> 
>         person.setLastName(""); // empty string is valid
>         annotatedClient.saveInheritEndpoint(person);
>     }
> -
> +    
>     @Test
>     public void testSaveValidateInAnnotated() {
>         Person person = new Person();
> 
>         try {
>             annotatedClient.saveValidateIn(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
> -            assertTrue(sfe.getMessage().contains("Unmarshalling Error"));
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>         }
> 
>         try {
>             person.setFirstName(""); // empty string is valid
>             annotatedClient.saveValidateIn(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
> -            assertTrue(sfe.getMessage().contains("Unmarshalling Error"));
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>         }
> 
>         person.setLastName(""); // empty string is valid
> @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest extends Assert {
>         annotatedClient.saveNoValidation(person);
>     }
> 
> -    // no validation is required for incoming
>     @Test
> -    public void testSaveValidationOutAnnotated() {
> +    public void testSaveValidationOutAnnotatedWithClientValidationDisabled() {
>         Person person = new Person();
> 
> -        annotatedClient.saveValidateOut(person);
> +        try {
> +            annotatedClient.saveValidateOut(person);
> +        } catch (SOAPFaultException sfe) {
> +            // verify its server side and a schema validation
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            
> +            // it's still a server side fault, because server side validation coming in failed
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
> +        
> +        person.setFirstName(""); // empty string is valid
> +        try {
> +            annotatedClient.saveValidateOut(person);
> +        } catch (SOAPFaultException sfe) {
> +            // verify its server side and a schema validation
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            
> +            // it's still a server side fault, because server side validation coming in failed
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
> 
> +        person.setLastName(""); // empty string is valid
> +        annotatedClient.saveValidateIn(person);
> +    }
> +    
> +    // this will still all be server side, as the OUT validation is turned into an IN validation for
> +    // the client, but by then the server has already thrown the exception for the OUT
> +    @Test
> +    public void testSaveValidationOutAnnotatedWithClientValidationEnabled() {
> +        Person person = new Person();
> +
> +        try {
> +            annotatedValidatingClient.saveValidateIn(person);
> +        } catch (SOAPFaultException sfe) {
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
> +        
>         person.setFirstName(""); // empty string is valid
> -        annotatedClient.saveValidateOut(person);
> +        try {
> +            annotatedValidatingClient.saveValidateIn(person);
> +        } catch (SOAPFaultException sfe) {
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
> 
>         person.setLastName(""); // empty string is valid
> -        annotatedClient.saveValidateOut(person);
> +        annotatedValidatingClient.saveValidateIn(person);
> +    }
> +    
> +    @Test
> +    public void testSaveValidationInAnnotatedWithClientValidationEnabled() {
> +        Person person = new Person();
> +
> +        try {
> +            person.setFirstName("InvalidResponse");
> +            person.setLastName("WhoCares");
> +            annotatedValidatingClient.saveValidateOut(person);
> +        } catch (SOAPFaultException sfe) {
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
>     }
> 
> -    // so this is the default, we are inheriting from the service level SchemaValidation annotation
> -    // which is set to BOTH
>     @Test
>     public void testEndpointSchemaValidationProvider() {
>         Person person = new Person();
> 
>         try {
>             client.saveInheritEndpoint(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
> -            assertTrue(sfe.getMessage().contains("Unmarshalling Error"));
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>         }
> -
> +       
>         try {
>             person.setFirstName(""); // empty string is valid
>             client.saveInheritEndpoint(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
> -            assertTrue(sfe.getMessage().contains("Unmarshalling Error"));
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>         }
> 
>         person.setLastName(""); // empty string is valid
> @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest extends Assert {
> 
>         try {
>             client.saveValidateIn(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
> -            assertTrue(sfe.getMessage().contains("Unmarshalling Error"));
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>         }
> 
>         try {
>             person.setFirstName(""); // empty string is valid
>             client.saveValidateIn(person);
> +            fail("Expected exception");
>         } catch (SOAPFaultException sfe) {
> -            // verify its server side and a schema validation
> -            assertTrue(sfe.getMessage().contains("Unmarshalling Error"));
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>         }
> 
>         person.setLastName(""); // empty string is valid
>         client.saveValidateIn(person);
>     }
> 
> -    // no validation at all is required
>     @Test
>     public void testSaveNoValidationProvider() {
>         Person person = new Person();
> @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest extends Assert {
>         client.saveNoValidation(person);
>     }
> 
> -    // no validation is required for incoming
>     @Test
> -    public void testSaveValidationOutProvider() {
> +    public void testSaveValidationOutProviderClientOnly() {
>         Person person = new Person();
> 
> -        client.saveValidateOut(person);
> +        try {
> +            disconnectedClient.saveValidateOut(person);
> +            fail("Expected exception");
> +        } catch (SOAPFaultException sfe) {
> +            // verify its client side outgoing
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
> +        
> +        person.setFirstName(""); // empty string is valid
> +        try {
> +            disconnectedClient.saveValidateOut(person);
> +            fail("Expected exception");
> +        } catch (SOAPFaultException sfe) {
> +            // verify its client side outgoing
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
> +
> +        person.setLastName(""); // empty string is valid
> +        
> +        // this confirms that we passed client validation as we then got the connectivity error
> +        try {
> +            disconnectedClient.saveValidateOut(person);
> +            fail("Expected exception");
> +        } catch (WebServiceException e) {
> +            assertTrue(e.getMessage().contains("Could not send Message"));
> +        }
> +    }
> 
> +    
> +    @Test
> +    public void testSaveValidationOutProvider() {
> +        Person person = new Person();
> +
> +        try {
> +            client.saveValidateOut(person);
> +        } catch (SOAPFaultException sfe) {
> +            // verify its server side outgoing
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
> +        
>         person.setFirstName(""); // empty string is valid
> -        client.saveValidateOut(person);
> +        try {
> +            client.saveValidateOut(person);
> +        } catch (SOAPFaultException sfe) {
> +            // verify its server side outgoing
> +            String stackTrace = getStackTrace(sfe);
> +            assertTrue(stackTrace.contains("Marshalling Error"));
> +            assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> +        }
> 
>         person.setLastName(""); // empty string is valid
>         client.saveValidateOut(person);
>     }
> 
> -    private static <T> T createClient(Class<T> serviceClass) {
> +    private static <T> T createClient(String port, Class<T> serviceClass, SchemaValidationType type) {
>         JaxWsProxyFactoryBean clientFactory = new JaxWsProxyFactoryBean();
>         clientFactory.setServiceClass(serviceClass);
> -
> -        // ensure all client schema validation is disabled
> -        Map<String, Object> properties = new HashMap<String, Object>();
> -        properties.put(Message.SCHEMA_VALIDATION_ENABLED, SchemaValidationType.NONE);
> -        clientFactory.setProperties(properties);
> -
> -        clientFactory.setAddress(getAddress(serviceClass));
> -
> +        
> +        
> +        clientFactory.setAddress(getAddress(port, serviceClass));
> +        
> +        
>         @SuppressWarnings("unchecked")
>         T newClient = (T)clientFactory.create();
> 
> -        Client clientProxy = ClientProxy.getClient(newClient);
> -
> -        // ensure all client schema validation is disabled
> -        for (BindingOperationInfo bop : clientProxy.getEndpoint().getEndpointInfo().getBinding()
> -            .getOperations()) {
> -            bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED, SchemaValidationType.NONE);
> +        Client proxy = ClientProxy.getClient(newClient);
> +        
> +        if (type != null) {
> +            proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED, type);
>         }
> -
> +        
> +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
> +        // give me longer debug times
> +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
> +        clientPolicy.setConnectionTimeout(1000000);
> +        clientPolicy.setReceiveTimeout(1000000);
> +        conduit.setClient(clientPolicy);
> +        
>         return newClient;
>     }
> 
> @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest extends Assert {
>         if (features != null) {
>             svrFactory.getFeatures().addAll(Arrays.asList(features));
>         }
> -        svrFactory.setAddress(getAddress(serviceInterface));
> +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
>         svrFactory.setServiceBean(serviceImpl);
>         Server server = svrFactory.create();
>         serverList.add(server);
>         return server;
>     }
> +    
> +    private String getStackTrace(Exception e) {
> +        StringWriter sWriter = new StringWriter();
> +        PrintWriter writer = new PrintWriter(sWriter, true);
> +        e.printStackTrace(writer);
> +        return sWriter.toString();
> +    }
> }
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> index e3ee10c..d594e4e 100644
> --- a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
> 
> import javax.jws.WebMethod;
> import javax.jws.WebParam;
> +import javax.jws.WebResult;
> import javax.jws.WebService;
> 
> import org.apache.cxf.annotations.SchemaValidation;
> @@ -30,14 +31,18 @@ import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> @SchemaValidation(type = SchemaValidationType.BOTH)
> public interface PersonService {
>     @WebMethod(operationName = "saveInheritEndpoint")
> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
> +    @WebResult(name = "Person")
> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
> 
>     @WebMethod(operationName = "saveNoValidation")
> -    void saveNoValidation(@WebParam(name = "Person") Person data);
> +    @WebResult(name = "Person")
> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> 
>     @WebMethod(operationName = "saveValidateIn")
> -    void saveValidateIn(@WebParam(name = "Person") Person data);
> +    @WebResult(name = "Person")
> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> 
>     @WebMethod(operationName = "saveValidateOut")
> -    void saveValidateOut(@WebParam(name = "Person") Person data);
> +    @WebResult(name = "Person")
> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> }
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> index 3e06576..a760f27 100644
> --- a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
> 
> import javax.jws.WebMethod;
> import javax.jws.WebParam;
> +import javax.jws.WebResult;
> import javax.jws.WebService;
> 
> import org.apache.cxf.annotations.SchemaValidation;
> @@ -30,17 +31,21 @@ import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> @SchemaValidation(type = SchemaValidationType.BOTH)
> public interface PersonServiceAnnotated {
>     @WebMethod(operationName = "saveInheritEndpoint")
> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
> +    @WebResult(name = "Person")
> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
> 
>     @SchemaValidation(type = SchemaValidationType.NONE)
>     @WebMethod(operationName = "saveNoValidation")
> -    void saveNoValidation(@WebParam(name = "Person") Person data);
> +    @WebResult(name = "Person")
> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> 
>     @SchemaValidation(type = SchemaValidationType.IN)
>     @WebMethod(operationName = "saveValidateIn")
> -    void saveValidateIn(@WebParam(name = "Person") Person data);
> +    @WebResult(name = "Person")
> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> 
>     @SchemaValidation(type = SchemaValidationType.OUT)
>     @WebMethod(operationName = "saveValidateOut")
> -    void saveValidateOut(@WebParam(name = "Person") Person data);
> +    @WebResult(name = "Person")
> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> }
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> index c7b8038..78973c9 100644
> --- a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> @@ -26,18 +26,25 @@ import javax.jws.WebService;
>     targetNamespace = "http://org.apache.cxf/service/PersonServiceAnnotated")
> public class PersonServiceAnnotatedImpl implements PersonServiceAnnotated {
>     @Override
> -    public void saveNoValidation(Person data) {
> +    public Person saveNoValidation(Person data) {
> +        return data;
>     }
> 
>     @Override
> -    public void saveInheritEndpoint(Person data) {
> +    public Person saveInheritEndpoint(Person data) {
> +        return data;
>     }
> 
>     @Override
> -    public void saveValidateIn(Person data) {
> +    public Person saveValidateIn(Person data) {
> +        if ("InvalidResponse".equals(data.getFirstName())) {
> +            return new Person();
> +        }
> +        return data;
>     }
> 
>     @Override
> -    public void saveValidateOut(Person data) {
> +    public Person saveValidateOut(Person data) {
> +        return data;
>     }
> }
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> index fe1d656..9edec45 100644
> --- a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> @@ -26,18 +26,22 @@ import javax.jws.WebService;
>     targetNamespace = "http://org.apache.cxf/service/PersonService")
> public class PersonServiceImpl implements PersonService {
>     @Override
> -    public void saveNoValidation(Person data) {
> +    public Person saveNoValidation(Person data) {
> +        return data;
>     }
> 
>     @Override
> -    public void saveInheritEndpoint(Person data) {
> +    public Person saveInheritEndpoint(Person data) {
> +        return data;
>     }
> 
>     @Override
> -    public void saveValidateIn(Person data) {
> +    public Person saveValidateIn(Person data) {
> +        return data;
>     }
> 
>     @Override
> -    public void saveValidateOut(Person data) {
> +    public Person saveValidateOut(Person data) {
> +        return data;
>     }
> }
> 
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> ----------------------------------------------------------------------
> diff --git a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> deleted file mode 100644
> index 18e66ae..0000000
> --- a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> +++ /dev/null
> @@ -1,69 +0,0 @@
> -/**
> - * Licensed to the Apache Software Foundation (ASF) under one
> - * or more contributor license agreements. See the NOTICE file
> - * distributed with this work for additional information
> - * regarding copyright ownership. The ASF licenses this file
> - * to you 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.cxf.systest.mtom_schema_validation;
> -
> -import java.io.File;
> -import java.net.URL;
> -
> -import javax.activation.DataHandler;
> -import javax.activation.FileDataSource;
> -import javax.xml.namespace.QName;
> -import javax.xml.ws.soap.MTOMFeature;
> -
> -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> -
> -import org.junit.BeforeClass;
> -import org.junit.Test;
> -
> -public final class MTOMProviderSchemaValidationTest extends AbstractBusClientServerTestBase {
> -    public static final String PORT = "9001";
> -        //Server.PORT;
> -
> -    private final QName serviceName = new QName("http://cxf.apache.org/", "HelloWS");
> -
> -    @BeforeClass
> -    public static void startservers() throws Exception {
> -        //assertTrue("server did not launch correctly", launchServer(Server.class, true));
> -    }
> -    @Test
> -    public void testSchemaValidation() throws Exception {
> -        HelloWS port = createService();
> -        Hello request = new Hello();
> -        request.setArg0("value");
> -        URL wsdl = getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> -        File attachment = new File(wsdl.getFile());
> -        request.setFile(new DataHandler(new FileDataSource(attachment)));
> -        HelloResponse response = port.hello(request);
> -        assertEquals("Hello CXF", response.getReturn());
> -    }
> -
> -    private HelloWS createService() throws Exception {
> -        URL wsdl = getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> -        assertNotNull(wsdl);
> -
> -        HelloWSClient service = new HelloWSClient(wsdl, serviceName);
> -        assertNotNull(service);
> -
> -        HelloWS port = service.getHello(new MTOMFeature());
> -
> -        updateAddressPort(port, PORT);
> -
> -        return port;
> -    }
> -}
> 

-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com


Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Jason Pell <ja...@pellcorp.com>.
Done I will apply the final 6118 to 3.0 and trunk today
On 29/11/2014 9:21 PM, "Jason Pell" <ja...@pellcorp.com> wrote:

> Took me a while but I finally got where you are coming from. Thanks for
> the detailed and informative replies.
> On 29/11/2014 8:46 PM, "Daniel Kulp" <dk...@apache.org> wrote:
>
>>
>> > On Nov 29, 2014, at 1:44 AM, Jason Pell <ja...@pellcorp.com> wrote:
>> >
>> > If the same SEI is used for both service endpoint and client. The use
>> of IN
>> > would result in request being validated on server and response on
>> client.
>>
>> Correct.
>>
>> As a point of note: from a performance standpoint, this is the best way
>> to set things up if you want both messages validated at some point and have
>> some level of control both the client and the server.  Validating messages
>> during the reading is much easier and quicker.  During the out phases,
>> validation is a bit trickier, particularly with the way CXF streams
>> messages.   For outgoing messages, if you stream while validating, the
>> validation exception would result in a  partial message being written out
>> on the wire which would result in strange stack traces and such in the logs
>> or strange exceptions on the other side.   The alternative is to buffer the
>> full message during validation and only send if validation succeeds.   That
>> has even larger performance (and memory) implications.
>>
>>
>> > This is two different jaxb structures. In my theoretical case the
>> service
>> > designer only wants to validate the request because the service response
>> > could be incomplete.
>>
>> Personally, I think if the service designer is explicitly sending invalid
>> data, that’s a serious problem that needs to be re-thought.  They should
>> get their schema updated to support the partial structures or whatever it
>> is they are sending.   A client could be using a different toolkit
>> (Metro/.NET/etc..) that has it’s own settings and such for schema
>> validation and might have other problems with it.
>>
>> > In the current situation jaxws client would throw schema violation for
>> the
>> > response even though service designer did not ever envision validation
>> the
>> > response.
>> >
>> > This is where I struggle to see why that is acceptable.
>>
>> I’m struggling to see why sending invalid data is acceptable.  :-)
>>  There is a point to having well defined contracts like WSDL’s that have
>> schemas.
>>
>> Dan
>>
>>
>>
>>
>> > Of course we can now just turn off validation on client so not really
>> too
>> > much of an issue.
>> > On 29/11/2014 3:18 PM, "Daniel Kulp" <dk...@apache.org> wrote:
>> >
>> >>
>> >>> On Nov 28, 2014, at 10:11 PM, Jason Pell <jp...@apache.org> wrote:
>> >>>
>> >>> Its only reversing what's coming from the model. If you define IN in
>> the
>> >>> jaxws properties on the client it will continue to validate IN on the
>> >>> client as before.
>> >>>
>> >>> If I have IN defined for a operation using an annotation the old code
>> >> would
>> >>> actually validate the response coming back to the client.
>> >>
>> >> That’s exactly what IN is supposed to mean.
>> >>
>> >>> This does seem
>> >>> counter intuitive especially as IN might have been specified because
>> the
>> >>> response may be incomplete and so can't be validated.
>> >>
>> >> It would be way more counter intuitive to me for IN to apply to
>> messages
>> >> that are going OUT.    That’s completely back wards.
>> >>
>> >>
>> >>> An IN for service is the OUT for client.
>> >>>
>> >>> The previous code was just plain wrong for client side - my code by
>> the
>> >> way
>> >>> :-)
>> >>
>> >> Why do you think it’s wrong?
>> >>
>> >> Basically, we have services that specify validation for IN as that is
>> the
>> >> only direction that we don’t control and we need to validate that.  For
>> >> messages that we produce (out on client, out on server), we know the
>> >> messages are valid as we populate the data correctly.   However, we
>> >> need/want to validate any incoming data to make sure that is correct.
>> That
>> >> is exactly what IN is supposed to mean.  Validate any data coming IN.
>> By
>> >> putting the annotation on the SEI specified with IN, we would get what
>> I
>> >> would regard as the correct behavior.  Validation of the stuff we
>> cannot
>> >> control and no validation for the stuff we already know is correct.
>> >>
>> >>
>> >>> This particular piece is only a few lines in ServiceUtils so I am
>> happy
>> >> to
>> >>> remove it if you are still -1
>> >>
>> >> That part, yes.  It’s wrong.
>> >>
>> >> Dan
>> >>
>> >>
>> >>> The alternative is I will add a property to enable it but only if the
>> >>> property is used.
>> >>>
>> >>> Would that be OK?
>> >>> On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:
>> >>>
>> >>>>
>> >>>> I’m -1 on the part of this that changes the IN to an OUT on the
>> client
>> >>>> side.   The IN and OUT are specifically named that way as they apply
>> to
>> >> the
>> >>>> messages that come IN to the client or IN to the server.   The “IN”
>> >>>> validation should definitely not be applying to the messages going
>> OUT.
>> >>>> Plus, that would be a huge behavioral change that would break many
>> >> peoples
>> >>>> existing applications.
>> >>>>
>> >>>> Dan
>> >>>>
>> >>>>
>> >>>>
>> >>>>
>> >>>>> On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
>> >>>>>
>> >>>>> Repository: cxf
>> >>>>> Updated Branches:
>> >>>>> refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
>> >>>>>
>> >>>>>
>> >>>>> CXF-6118 support overriding schema validation at jaxws endpoint and
>> >>>> client level and applying the correct validation direction at client
>> >> level
>> >>>>>
>> >>>>>
>> >>>>> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
>> >>>>> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
>> >>>>> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
>> >>>>> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
>> >>>>>
>> >>>>> Branch: refs/heads/2.7.x-fixes
>> >>>>> Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
>> >>>>> Parents: e172a3e
>> >>>>> Author: Jason Pell <jp...@apache.org>
>> >>>>> Authored: Thu Nov 27 16:54:01 2014 +1100
>> >>>>> Committer: Jason Pell <jp...@apache.org>
>> >>>>> Committed: Fri Nov 28 15:52:36 2014 +1100
>> >>>>>
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> .../validation/SchemaValidationFeature.java     |   2 +-
>> >>>>> .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
>> >>>>> .../AbstractInDatabindingInterceptor.java       |  23 +-
>> >>>>> .../AbstractOutDatabindingInterceptor.java      |  22 +-
>> >>>>> .../java/org/apache/cxf/message/Message.java    |   9 +
>> >>>>> .../soap/interceptor/RPCInInterceptor.java      |   2 +-
>> >>>>> .../factory/AnnotationsFactoryBeanListener.java |   9 +-
>> >>>>> .../JavaFirstSchemaValidationTest.java          | 256
>> >> ++++++++++++++-----
>> >>>>> .../jaxws/schemavalidation/PersonService.java   |  13 +-
>> >>>>> .../PersonServiceAnnotated.java                 |  13 +-
>> >>>>> .../PersonServiceAnnotatedImpl.java             |  15 +-
>> >>>>> .../schemavalidation/PersonServiceImpl.java     |  12 +-
>> >>>>> .../MTOMProviderSchemaValidationTest.bak        |  69 -----
>> >>>>> 13 files changed, 342 insertions(+), 201 deletions(-)
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>>
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> >>>>
>> >>
>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> >>>>> index 5eda79c..c314eaf 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> >>>>> +++
>> >>>>
>> >>
>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> >>>>> @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
>> >>>> AbstractFeature {
>> >>>>>       for (BindingOperationInfo bop :
>> >>>> endpoint.getEndpointInfo().getBinding().getOperations()) {
>> >>>>>           SchemaValidationType type =
>> >>>> provider.getSchemaValidationType(bop.getOperationInfo());
>> >>>>>           if (type != null) {
>> >>>>> -
>> >>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>> >> type);
>> >>>>> +
>> >>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> >> type);
>> >>>>>           }
>> >>>>>       }
>> >>>>>   }
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> >>>> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> >>>>> index 85d77d0..28c7ba2 100644
>> >>>>> --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> >>>>> +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> >>>>> @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
>> >>>>> import javax.xml.namespace.QName;
>> >>>>>
>> >>>>> import
>> >> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>> >>>>> +import org.apache.cxf.endpoint.Endpoint;
>> >>>>> +import org.apache.cxf.message.Exchange;
>> >>>>> import org.apache.cxf.message.Message;
>> >>>>> +import org.apache.cxf.message.MessageUtils;
>> >>>>> +import org.apache.cxf.service.model.AbstractPropertiesHolder;
>> >>>>> +import org.apache.cxf.service.model.BindingOperationInfo;
>> >>>>> +import org.apache.cxf.service.model.EndpointInfo;
>> >>>>> +import org.apache.cxf.service.model.OperationInfo;
>> >>>>>
>> >>>>> public final class ServiceUtils {
>> >>>>> -
>> >>>>>   private ServiceUtils() {
>> >>>>>   }
>> >>>>>
>> >>>>> @@ -42,24 +48,94 @@ public final class ServiceUtils {
>> >>>>>    * @param type
>> >>>>>    */
>> >>>>>   public static boolean
>> isSchemaValidationEnabled(SchemaValidationType
>> >>>> type, Message message) {
>> >>>>> -        SchemaValidationType messageType =
>> >>>> getSchemaValidationType(message);
>> >>>>> +        SchemaValidationType validationType =
>> >>>> getSchemaValidationType(message);
>> >>>>>
>> >>>>> -        return messageType.equals(type)
>> >>>>> +        return validationType.equals(type)
>> >>>>>           || ((SchemaValidationType.IN.equals(type) ||
>> >>>> SchemaValidationType.OUT.equals(type))
>> >>>>> -                && SchemaValidationType.BOTH.equals(messageType));
>> >>>>> +                &&
>> SchemaValidationType.BOTH.equals(validationType));
>> >>>>>   }
>> >>>>> -
>> >>>>> +
>> >>>>>   /**
>> >>>>> -     * Determines the appropriate SchemaValidationType to return
>> based
>> >>>> on either
>> >>>>> -     * a Boolean (for backwards compatibility) or the selected
>> Schema
>> >>>> Validation Type.
>> >>>>> -     *
>> >>>>> -     * Package private as the isSchemaValidationEnabled method
>> should
>> >>>> be used instead.  Only
>> >>>>> -     * visible for easier testing
>> >>>>> +     * A convenience method to check for schema validation config
>> in
>> >>>> the message context, and then in the service model.
>> >>>>> +     * Does not modify the Message context (other than what is
>> done in
>> >>>> the getContextualProperty itself)
>> >>>>>    *
>> >>>>>    * @param message
>> >>>>> +     * @param type
>> >>>>>    */
>> >>>>> -    static SchemaValidationType getSchemaValidationType(Message
>> >>>> message) {
>> >>>>> +    public static SchemaValidationType
>> getSchemaValidationType(Message
>> >>>> message) {
>> >>>>> +        SchemaValidationType validationType =
>> >>>> getOverrideSchemaValidationType(message);
>> >>>>> +        if (validationType == null) {
>> >>>>> +            validationType =
>> >> getSchemaValidationTypeFromModel(message);
>> >>>>> +        }
>> >>>>> +
>> >>>>> +        if (validationType == null) {
>> >>>>> +            validationType = SchemaValidationType.NONE;
>> >>>>> +        }
>> >>>>> +
>> >>>>> +        return validationType;
>> >>>>> +    }
>> >>>>> +
>> >>>>> +    private static SchemaValidationType
>> >>>> getOverrideSchemaValidationType(Message message) {
>> >>>>>       Object obj =
>> >>>> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
>> >>>>> +        if (obj != null) {
>> >>>>> +            // this method will transform the legacy enabled as
>> well
>> >>>>> +            return getSchemaValidationType(obj);
>> >>>>> +        } else {
>> >>>>> +            return null;
>> >>>>> +        }
>> >>>>> +    }
>> >>>>> +
>> >>>>> +    private static SchemaValidationType
>> >>>> getSchemaValidationTypeFromModel(Message message) {
>> >>>>> +        boolean isRequestor = MessageUtils.isRequestor(message);
>> >>>>> +        Exchange exchange = message.getExchange();
>> >>>>> +
>> >>>>> +        if (exchange != null) {
>> >>>>> +            BindingOperationInfo boi =
>> >>>> exchange.getBindingOperationInfo();
>> >>>>> +            Endpoint endpoint = exchange.getEndpoint();
>> >>>>> +
>> >>>>> +            if (boi != null && endpoint != null) {
>> >>>>> +                SchemaValidationType validationType = null;
>> >>>>> +                OperationInfo opInfo = boi.getOperationInfo();
>> >>>>> +                EndpointInfo ep = endpoint.getEndpointInfo();
>> >>>>> +
>> >>>>> +                if (validationType == null && opInfo != null) {
>> >>>>> +                    validationType =
>> >>>> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
>> >>>>> +
>> >>>>> +                    if (validationType == null && ep != null) {
>> >>>>> +                        validationType =
>> >>>> getSchemaValidationTypeFromModel(message, ep, isRequestor);
>> >>>>> +                    }
>> >>>>> +                }
>> >>>>> +
>> >>>>> +                return validationType;
>> >>>>> +            }
>> >>>>> +        }
>> >>>>> +
>> >>>>> +        // else
>> >>>>> +        return null;
>> >>>>> +    }
>> >>>>> +
>> >>>>> +    private static SchemaValidationType
>> >>>> getSchemaValidationTypeFromModel(
>> >>>>> +            Message message, AbstractPropertiesHolder properties,
>> >>>> boolean isRequestor) {
>> >>>>> +        Object obj =
>> >>>> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
>> >>>>> +        if (obj != null) {
>> >>>>> +            SchemaValidationType validationType =
>> >>>> getSchemaValidationType(obj);
>> >>>>> +
>> >>>>> +            // Reverse the direction of any IN / OUT for requestor
>> >>>> (client)
>> >>>>> +            if (isRequestor) {
>> >>>>> +                if
>> (SchemaValidationType.IN.equals(validationType)) {
>> >>>>> +                    return SchemaValidationType.OUT;
>> >>>>> +                } else if
>> >>>> (SchemaValidationType.OUT.equals(validationType)) {
>> >>>>> +                    return SchemaValidationType.IN;
>> >>>>> +                }
>> >>>>> +            }
>> >>>>> +
>> >>>>> +            return validationType;
>> >>>>> +        } else {
>> >>>>> +            return null;
>> >>>>> +        }
>> >>>>> +    }
>> >>>>> +
>> >>>>> +    public static SchemaValidationType
>> getSchemaValidationType(Object
>> >>>> obj) {
>> >>>>>       if (obj instanceof SchemaValidationType) {
>> >>>>>           return (SchemaValidationType)obj;
>> >>>>>       } else if (obj != null) {
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> >>>>
>> >>
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> >>>>> index c47417a..ec8cf71 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> >>>>> +++
>> >>>>
>> >>
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> >>>>> @@ -125,24 +125,9 @@ public abstract class
>> >>>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>> >>>>>       }
>> >>>>>   }
>> >>>>>
>> >>>>> -    /**
>> >>>>> -     * Where an operation level validation type has been set, copy
>> it
>> >>>> to the message, so it can be interrogated
>> >>>>> -     * by all downstream interceptors.  It is expected that sub
>> >> classes
>> >>>> will call setDataReaderValidation subsequent
>> >>>>> -     * to this to ensure the DataReader schema reference is
>> updated as
>> >>>> appropriate.
>> >>>>> -     *
>> >>>>> -     * @param bop
>> >>>>> -     * @param message
>> >>>>> -     * @param reader
>> >>>>> -     * @see #setDataReaderValidation(Service, Message, DataReader)
>> >>>>> -     */
>> >>>>> -    protected void setOperationSchemaValidation(OperationInfo
>> opInfo,
>> >>>> Message message) {
>> >>>>> -        if (opInfo != null) {
>> >>>>> -            SchemaValidationType validationType =
>> >>>>> -                (SchemaValidationType)
>> >>>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>> >>>>> -            if (validationType != null) {
>> >>>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> >>>> validationType);
>> >>>>> -            }
>> >>>>> -        }
>> >>>>> +    protected void setOperationSchemaValidation(Message message) {
>> >>>>> +        SchemaValidationType validationType =
>> >>>> ServiceUtils.getSchemaValidationType(message);
>> >>>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> >> validationType);
>> >>>>>   }
>> >>>>>
>> >>>>>   protected DepthXMLStreamReader getXMLStreamReader(Message
>> message) {
>> >>>>> @@ -247,7 +232,7 @@ public abstract class
>> >>>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>> >>>>>       }
>> >>>>>
>> >>>>>       // configure endpoint and operation level schema validation
>> >>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>> >>>> message);
>> >>>>> +        setOperationSchemaValidation(message);
>> >>>>>
>> >>>>>       QName serviceQName = si.getName();
>> >>>>>       message.put(Message.WSDL_SERVICE, serviceQName);
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> >>>>
>> >>
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> >>>>> index db3ba6c..52d1cb1 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> >>>>> +++
>> >>>>
>> >>
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> >>>>> @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
>> >>>>> import org.apache.cxf.service.model.BindingInfo;
>> >>>>> import org.apache.cxf.service.model.BindingOperationInfo;
>> >>>>> import org.apache.cxf.service.model.MessagePartInfo;
>> >>>>> -import org.apache.cxf.service.model.OperationInfo;
>> >>>>> import org.apache.cxf.staxutils.CachingXmlEventWriter;
>> >>>>> import org.apache.cxf.staxutils.StaxUtils;
>> >>>>> import org.apache.cxf.wsdl.EndpointReferenceUtils;
>> >>>>> @@ -85,7 +84,7 @@ public abstract class
>> >>>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>> >>>>>       CachingXmlEventWriter cache = null;
>> >>>>>
>> >>>>>       // configure endpoint and operation level schema validation
>> >>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>> >>>> message);
>> >>>>> +        setOperationSchemaValidation(message);
>> >>>>>
>> >>>>>       // need to cache the events in case validation fails or
>> >>>> buffering is enabled
>> >>>>>       if (shouldBuffer(message)) {
>> >>>>> @@ -159,22 +158,9 @@ public abstract class
>> >>>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>> >>>>>       }
>> >>>>>   }
>> >>>>>
>> >>>>> -    /**
>> >>>>> -     * Where an operation level validation type has been set, copy
>> it
>> >>>> to the message, so it can be interrogated
>> >>>>> -     * by all downstream interceptors
>> >>>>> -     *
>> >>>>> -     * @param bop
>> >>>>> -     * @param message
>> >>>>> -     * @param reader
>> >>>>> -     */
>> >>>>> -    private void setOperationSchemaValidation(OperationInfo opInfo,
>> >>>> Message message) {
>> >>>>> -        if (opInfo != null) {
>> >>>>> -            SchemaValidationType validationType =
>> >>>>> -                (SchemaValidationType)
>> >>>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>> >>>>> -            if (validationType != null) {
>> >>>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> >>>> validationType);
>> >>>>> -            }
>> >>>>> -        }
>> >>>>> +    protected void setOperationSchemaValidation(Message message) {
>> >>>>> +        SchemaValidationType validationType =
>> >>>> ServiceUtils.getSchemaValidationType(message);
>> >>>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> >> validationType);
>> >>>>>   }
>> >>>>>
>> >>>>>   protected boolean shouldValidate(Message m) {
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
>> >>>> b/api/src/main/java/org/apache/cxf/message/Message.java
>> >>>>> index 35e94af..5854a18 100644
>> >>>>> --- a/api/src/main/java/org/apache/cxf/message/Message.java
>> >>>>> +++ b/api/src/main/java/org/apache/cxf/message/Message.java
>> >>>>> @@ -105,7 +105,16 @@ public interface Message extends StringMap {
>> >>>>>    */
>> >>>>>   String MTOM_ENABLED = "mtom-enabled";
>> >>>>>   String MTOM_THRESHOLD = "mtom-threshold";
>> >>>>> +
>> >>>>> +    /**
>> >>>>> +     * Runtime schema validation property
>> >>>>> +     */
>> >>>>>   String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
>> >>>>> +
>> >>>>> +    /**
>> >>>>> +     * The default values for schema validation will be set in the
>> >>>> service model using this property
>> >>>>> +     */
>> >>>>> +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
>> >>>>>
>> >>>>>   /**
>> >>>>>    * Boolean property specifying if the Java stack trace is returned
>> >>>> as a
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> >>>>
>> >>
>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> >>>>> index fafd0a9..d49f090 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> >>>>> +++
>> >>>>
>> >>
>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> >>>>> @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
>> >>>> AbstractInDatabindingInterceptor {
>> >>>>>       message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
>> >>>>>
>> >>>>>       // configure endpoint and operation level schema validation
>> >>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>> >>>> message);
>> >>>>> +        setOperationSchemaValidation(message);
>> >>>>>   }
>> >>>>> }
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> >>>>
>> >>
>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> >>>>> index 7100f2c..9a7cbc8 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> >>>>> +++
>> >>>>
>> >>
>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> >>>>> @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
>> >>>> implements FactoryBeanListener {
>> >>>>>           // if someone has gone to the effort of specifying
>> >>>> enabled=false, then we need to
>> >>>>>           // handle that, otherwise we use the new
>> >>>> SchemaValidationType type only
>> >>>>>           if (!annotation.enabled()) {
>> >>>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>> >>>> SchemaValidationType.NONE);
>> >>>>> +
>> >>>>
>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> >>>> SchemaValidationType.NONE);
>> >>>>>           } else {
>> >>>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>> >>>> annotation.type());
>> >>>>> +
>> >>>>
>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> >>>> annotation.type());
>> >>>>>           }
>> >>>>>       }
>> >>>>>   }
>> >>>>> @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
>> >>>> implements FactoryBeanListener {
>> >>>>>   }
>> >>>>>
>> >>>>>   private void addSchemaValidationSupport(OperationInfo inf,
>> >>>> SchemaValidation annotation) {
>> >>>>> -        // Notice no support for deprecated enabled property here!
>> >>>>> -        // TODO - should we check for the use of this property and
>> at
>> >>>> least log the fact we are
>> >>>>> -        // ignoring it
>> >>>>>       if (annotation != null) {
>> >>>>> -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>> >>>> annotation.type());
>> >>>>> +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> >>>> annotation.type());
>> >>>>>       }
>> >>>>>   }
>> >>>>>
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> >>>>> index 888e5a8..9f08839 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> >>>>> +++
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> >>>>> @@ -20,12 +20,15 @@
>> >>>>> package org.apache.cxf.systest.jaxws.schemavalidation;
>> >>>>>
>> >>>>> import java.io.IOException;
>> >>>>> +import java.io.PrintWriter;
>> >>>>> +import java.io.StringWriter;
>> >>>>> import java.util.ArrayList;
>> >>>>> import java.util.Arrays;
>> >>>>> import java.util.HashMap;
>> >>>>> import java.util.List;
>> >>>>> import java.util.Map;
>> >>>>>
>> >>>>> +import javax.xml.ws.WebServiceException;
>> >>>>> import javax.xml.ws.soap.SOAPFaultException;
>> >>>>>
>> >>>>> import
>> >> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>> >>>>> @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
>> >>>>> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
>> >>>>> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
>> >>>>> import org.apache.cxf.message.Message;
>> >>>>> -import org.apache.cxf.service.model.BindingOperationInfo;
>> >>>>> import org.apache.cxf.testutil.common.TestUtil;
>> >>>>> +import org.apache.cxf.transport.http.HTTPConduit;
>> >>>>> +import
>> org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
>> >>>>> import org.junit.AfterClass;
>> >>>>> import org.junit.Assert;
>> >>>>> import org.junit.BeforeClass;
>> >>>>> import org.junit.Test;
>> >>>>>
>> >>>>> -/**
>> >>>>> - * TODO - test where the default is NONE at the service level test
>> >>>> where the default is IN or OUT, and then
>> >>>>> - * override at operation levels
>> >>>>> - */
>> >>>>> public class JavaFirstSchemaValidationTest extends Assert {
>> >>>>> -    static final String PORT =
>> >>>> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
>> >>>>> +    static final String PORT =
>> >>>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>> >>>>> +    static final String PORT_UNUSED =
>> >>>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>> >>>>>
>> >>>>>   private static List<Server> serverList = new ArrayList<Server>();
>> >>>>>   private static PersonServiceAnnotated annotatedClient;
>> >>>>> +    private static PersonServiceAnnotated
>> annotatedValidatingClient;
>> >>>>>   private static PersonService client;
>> >>>>>   private static PersonServiceRPC rpcClient;
>> >>>>> +
>> >>>>> +    private static PersonService disconnectedClient;
>> >>>>>
>> >>>>>   @BeforeClass
>> >>>>>   public static void startServers() throws Exception {
>> >>>>> @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest
>> extends
>> >>>> Assert {
>> >>>>>
>> >>>>>       createServer(PersonServiceRPC.class, new
>> PersonServiceRPCImpl(),
>> >>>> feature, new LoggingFeature());
>> >>>>>
>> >>>>> -        annotatedClient =
>> createClient(PersonServiceAnnotated.class);
>> >>>>> -        client = createClient(PersonService.class);
>> >>>>> -        rpcClient = createClient(PersonServiceRPC.class);
>> >>>>> +        annotatedClient = createClient(PORT,
>> >>>> PersonServiceAnnotated.class, SchemaValidationType.NONE);
>> >>>>> +        annotatedValidatingClient = createClient(PORT,
>> >>>> PersonServiceAnnotated.class, null);
>> >>>>> +        client = createClient(PORT, PersonService.class,
>> >>>> SchemaValidationType.NONE);
>> >>>>> +        disconnectedClient = createClient(PORT_UNUSED,
>> >>>> PersonService.class, SchemaValidationType.OUT);
>> >>>>> +        rpcClient = createClient(PORT, PersonServiceRPC.class,
>> >>>> SchemaValidationType.NONE);
>> >>>>>   }
>> >>>>>
>> >>>>>   @AfterClass
>> >>>>> @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest
>> extends
>> >>>> Assert {
>> >>>>>       }
>> >>>>>   }
>> >>>>>
>> >>>>> -    static String getAddress(Class<?> sei) {
>> >>>>> -        return "http://localhost:" + PORT + "/" +
>> >> sei.getSimpleName();
>> >>>>> +    static String getAddress(String port, Class<?> sei) {
>> >>>>> +        return "http://localhost:" + port + "/" +
>> >> sei.getSimpleName();
>> >>>>>   }
>> >>>>> -
>> >>>>>
>> >>>>>   @Test
>> >>>>>   public void testRPCLit() throws Exception {
>> >>>>> @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest
>> extends
>> >>>> Assert {
>> >>>>>       try {
>> >>>>>           person.setFirstName(null);
>> >>>>>           rpcClient.saveValidateOut(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>>           assertTrue(sfe.getMessage().contains("Marshalling
>> Error"));
>> >>>>>           assertTrue(sfe.getMessage().contains("lastName"));
>> >>>>>       }
>> >>>>> @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest
>> >> extends
>> >>>> Assert {
>> >>>>>
>> >>>>>       try {
>> >>>>>           annotatedClient.saveInheritEndpoint(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> >>>> Error"));
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>>       }
>> >>>>>
>> >>>>>       try {
>> >>>>>           person.setFirstName(""); // empty string is valid
>> >>>>>           annotatedClient.saveInheritEndpoint(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> >>>> Error"));
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>>       }
>> >>>>>
>> >>>>>       person.setLastName(""); // empty string is valid
>> >>>>>       annotatedClient.saveInheritEndpoint(person);
>> >>>>>   }
>> >>>>> -
>> >>>>> +
>> >>>>>   @Test
>> >>>>>   public void testSaveValidateInAnnotated() {
>> >>>>>       Person person = new Person();
>> >>>>>
>> >>>>>       try {
>> >>>>>           annotatedClient.saveValidateIn(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> >>>> Error"));
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>>       }
>> >>>>>
>> >>>>>       try {
>> >>>>>           person.setFirstName(""); // empty string is valid
>> >>>>>           annotatedClient.saveValidateIn(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> >>>> Error"));
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>>       }
>> >>>>>
>> >>>>>       person.setLastName(""); // empty string is valid
>> >>>>> @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
>> >>>> extends Assert {
>> >>>>>       annotatedClient.saveNoValidation(person);
>> >>>>>   }
>> >>>>>
>> >>>>> -    // no validation is required for incoming
>> >>>>>   @Test
>> >>>>> -    public void testSaveValidationOutAnnotated() {
>> >>>>> +    public void
>> >>>> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
>> >>>>>       Person person = new Person();
>> >>>>>
>> >>>>> -        annotatedClient.saveValidateOut(person);
>> >>>>> +        try {
>> >>>>> +            annotatedClient.saveValidateOut(person);
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            // verify its server side and a schema validation
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>> +            // it's still a server side fault, because server side
>> >>>> validation coming in failed
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>> +
>> >>>>> +        person.setFirstName(""); // empty string is valid
>> >>>>> +        try {
>> >>>>> +            annotatedClient.saveValidateOut(person);
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            // verify its server side and a schema validation
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>> +            // it's still a server side fault, because server side
>> >>>> validation coming in failed
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>>
>> >>>>> +        person.setLastName(""); // empty string is valid
>> >>>>> +        annotatedClient.saveValidateIn(person);
>> >>>>> +    }
>> >>>>> +
>> >>>>> +    // this will still all be server side, as the OUT validation is
>> >>>> turned into an IN validation for
>> >>>>> +    // the client, but by then the server has already thrown the
>> >>>> exception for the OUT
>> >>>>> +    @Test
>> >>>>> +    public void
>> >>>> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
>> >>>>> +        Person person = new Person();
>> >>>>> +
>> >>>>> +        try {
>> >>>>> +            annotatedValidatingClient.saveValidateIn(person);
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>> +
>> >>>>>       person.setFirstName(""); // empty string is valid
>> >>>>> -        annotatedClient.saveValidateOut(person);
>> >>>>> +        try {
>> >>>>> +            annotatedValidatingClient.saveValidateIn(person);
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>>
>> >>>>>       person.setLastName(""); // empty string is valid
>> >>>>> -        annotatedClient.saveValidateOut(person);
>> >>>>> +        annotatedValidatingClient.saveValidateIn(person);
>> >>>>> +    }
>> >>>>> +
>> >>>>> +    @Test
>> >>>>> +    public void
>> >>>> testSaveValidationInAnnotatedWithClientValidationEnabled() {
>> >>>>> +        Person person = new Person();
>> >>>>> +
>> >>>>> +        try {
>> >>>>> +            person.setFirstName("InvalidResponse");
>> >>>>> +            person.setLastName("WhoCares");
>> >>>>> +            annotatedValidatingClient.saveValidateOut(person);
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>>   }
>> >>>>>
>> >>>>> -    // so this is the default, we are inheriting from the service
>> >> level
>> >>>> SchemaValidation annotation
>> >>>>> -    // which is set to BOTH
>> >>>>>   @Test
>> >>>>>   public void testEndpointSchemaValidationProvider() {
>> >>>>>       Person person = new Person();
>> >>>>>
>> >>>>>       try {
>> >>>>>           client.saveInheritEndpoint(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> >>>> Error"));
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>>       }
>> >>>>> -
>> >>>>> +
>> >>>>>       try {
>> >>>>>           person.setFirstName(""); // empty string is valid
>> >>>>>           client.saveInheritEndpoint(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> >>>> Error"));
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>>       }
>> >>>>>
>> >>>>>       person.setLastName(""); // empty string is valid
>> >>>>> @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest
>> >> extends
>> >>>> Assert {
>> >>>>>
>> >>>>>       try {
>> >>>>>           client.saveValidateIn(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> >>>> Error"));
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>>       }
>> >>>>>
>> >>>>>       try {
>> >>>>>           person.setFirstName(""); // empty string is valid
>> >>>>>           client.saveValidateIn(person);
>> >>>>> +            fail("Expected exception");
>> >>>>>       } catch (SOAPFaultException sfe) {
>> >>>>> -            // verify its server side and a schema validation
>> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> >>>> Error"));
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>>       }
>> >>>>>
>> >>>>>       person.setLastName(""); // empty string is valid
>> >>>>>       client.saveValidateIn(person);
>> >>>>>   }
>> >>>>>
>> >>>>> -    // no validation at all is required
>> >>>>>   @Test
>> >>>>>   public void testSaveNoValidationProvider() {
>> >>>>>       Person person = new Person();
>> >>>>> @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest
>> >> extends
>> >>>> Assert {
>> >>>>>       client.saveNoValidation(person);
>> >>>>>   }
>> >>>>>
>> >>>>> -    // no validation is required for incoming
>> >>>>>   @Test
>> >>>>> -    public void testSaveValidationOutProvider() {
>> >>>>> +    public void testSaveValidationOutProviderClientOnly() {
>> >>>>>       Person person = new Person();
>> >>>>>
>> >>>>> -        client.saveValidateOut(person);
>> >>>>> +        try {
>> >>>>> +            disconnectedClient.saveValidateOut(person);
>> >>>>> +            fail("Expected exception");
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            // verify its client side outgoing
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>> +
>> >>>>> +        person.setFirstName(""); // empty string is valid
>> >>>>> +        try {
>> >>>>> +            disconnectedClient.saveValidateOut(person);
>> >>>>> +            fail("Expected exception");
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            // verify its client side outgoing
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>> +
>> >>>>> +        person.setLastName(""); // empty string is valid
>> >>>>> +
>> >>>>> +        // this confirms that we passed client validation as we
>> then
>> >>>> got the connectivity error
>> >>>>> +        try {
>> >>>>> +            disconnectedClient.saveValidateOut(person);
>> >>>>> +            fail("Expected exception");
>> >>>>> +        } catch (WebServiceException e) {
>> >>>>> +            assertTrue(e.getMessage().contains("Could not send
>> >>>> Message"));
>> >>>>> +        }
>> >>>>> +    }
>> >>>>>
>> >>>>> +
>> >>>>> +    @Test
>> >>>>> +    public void testSaveValidationOutProvider() {
>> >>>>> +        Person person = new Person();
>> >>>>> +
>> >>>>> +        try {
>> >>>>> +            client.saveValidateOut(person);
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            // verify its server side outgoing
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>> +
>> >>>>>       person.setFirstName(""); // empty string is valid
>> >>>>> -        client.saveValidateOut(person);
>> >>>>> +        try {
>> >>>>> +            client.saveValidateOut(person);
>> >>>>> +        } catch (SOAPFaultException sfe) {
>> >>>>> +            // verify its server side outgoing
>> >>>>> +            String stackTrace = getStackTrace(sfe);
>> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>> >>>>> +
>> >>>>
>> >>
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >>>>> +        }
>> >>>>>
>> >>>>>       person.setLastName(""); // empty string is valid
>> >>>>>       client.saveValidateOut(person);
>> >>>>>   }
>> >>>>>
>> >>>>> -    private static <T> T createClient(Class<T> serviceClass) {
>> >>>>> +    private static <T> T createClient(String port, Class<T>
>> >>>> serviceClass, SchemaValidationType type) {
>> >>>>>       JaxWsProxyFactoryBean clientFactory = new
>> >>>> JaxWsProxyFactoryBean();
>> >>>>>       clientFactory.setServiceClass(serviceClass);
>> >>>>> -
>> >>>>> -        // ensure all client schema validation is disabled
>> >>>>> -        Map<String, Object> properties = new HashMap<String,
>> >> Object>();
>> >>>>> -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
>> >>>> SchemaValidationType.NONE);
>> >>>>> -        clientFactory.setProperties(properties);
>> >>>>> -
>> >>>>> -        clientFactory.setAddress(getAddress(serviceClass));
>> >>>>> -
>> >>>>> +
>> >>>>> +
>> >>>>> +        clientFactory.setAddress(getAddress(port, serviceClass));
>> >>>>> +
>> >>>>> +
>> >>>>>       @SuppressWarnings("unchecked")
>> >>>>>       T newClient = (T)clientFactory.create();
>> >>>>>
>> >>>>> -        Client clientProxy = ClientProxy.getClient(newClient);
>> >>>>> -
>> >>>>> -        // ensure all client schema validation is disabled
>> >>>>> -        for (BindingOperationInfo bop :
>> >>>> clientProxy.getEndpoint().getEndpointInfo().getBinding()
>> >>>>> -            .getOperations()) {
>> >>>>> -
>> >>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>> >>>> SchemaValidationType.NONE);
>> >>>>> +        Client proxy = ClientProxy.getClient(newClient);
>> >>>>> +
>> >>>>> +        if (type != null) {
>> >>>>> +
>> >>>> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED,
>> type);
>> >>>>>       }
>> >>>>> -
>> >>>>> +
>> >>>>> +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
>> >>>>> +        // give me longer debug times
>> >>>>> +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
>> >>>>> +        clientPolicy.setConnectionTimeout(1000000);
>> >>>>> +        clientPolicy.setReceiveTimeout(1000000);
>> >>>>> +        conduit.setClient(clientPolicy);
>> >>>>> +
>> >>>>>       return newClient;
>> >>>>>   }
>> >>>>>
>> >>>>> @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest
>> >> extends
>> >>>> Assert {
>> >>>>>       if (features != null) {
>> >>>>>           svrFactory.getFeatures().addAll(Arrays.asList(features));
>> >>>>>       }
>> >>>>> -        svrFactory.setAddress(getAddress(serviceInterface));
>> >>>>> +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
>> >>>>>       svrFactory.setServiceBean(serviceImpl);
>> >>>>>       Server server = svrFactory.create();
>> >>>>>       serverList.add(server);
>> >>>>>       return server;
>> >>>>>   }
>> >>>>> +
>> >>>>> +    private String getStackTrace(Exception e) {
>> >>>>> +        StringWriter sWriter = new StringWriter();
>> >>>>> +        PrintWriter writer = new PrintWriter(sWriter, true);
>> >>>>> +        e.printStackTrace(writer);
>> >>>>> +        return sWriter.toString();
>> >>>>> +    }
>> >>>>> }
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> >>>>> index e3ee10c..d594e4e 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> >>>>> +++
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> >>>>> @@ -21,6 +21,7 @@ package
>> >> org.apache.cxf.systest.jaxws.schemavalidation;
>> >>>>>
>> >>>>> import javax.jws.WebMethod;
>> >>>>> import javax.jws.WebParam;
>> >>>>> +import javax.jws.WebResult;
>> >>>>> import javax.jws.WebService;
>> >>>>>
>> >>>>> import org.apache.cxf.annotations.SchemaValidation;
>> >>>>> @@ -30,14 +31,18 @@ import
>> >>>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>> >>>>> @SchemaValidation(type = SchemaValidationType.BOTH)
>> >>>>> public interface PersonService {
>> >>>>>   @WebMethod(operationName = "saveInheritEndpoint")
>> >>>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person
>> data);
>> >>>>> +    @WebResult(name = "Person")
>> >>>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
>> >> data);
>> >>>>>
>> >>>>>   @WebMethod(operationName = "saveNoValidation")
>> >>>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
>> >>>>> +    @WebResult(name = "Person")
>> >>>>> +    Person saveNoValidation(@WebParam(name = "Person") Person
>> data);
>> >>>>>
>> >>>>>   @WebMethod(operationName = "saveValidateIn")
>> >>>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
>> >>>>> +    @WebResult(name = "Person")
>> >>>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>> >>>>>
>> >>>>>   @WebMethod(operationName = "saveValidateOut")
>> >>>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
>> >>>>> +    @WebResult(name = "Person")
>> >>>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>> >>>>> }
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> >>>>> index 3e06576..a760f27 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> >>>>> +++
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> >>>>> @@ -21,6 +21,7 @@ package
>> >> org.apache.cxf.systest.jaxws.schemavalidation;
>> >>>>>
>> >>>>> import javax.jws.WebMethod;
>> >>>>> import javax.jws.WebParam;
>> >>>>> +import javax.jws.WebResult;
>> >>>>> import javax.jws.WebService;
>> >>>>>
>> >>>>> import org.apache.cxf.annotations.SchemaValidation;
>> >>>>> @@ -30,17 +31,21 @@ import
>> >>>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>> >>>>> @SchemaValidation(type = SchemaValidationType.BOTH)
>> >>>>> public interface PersonServiceAnnotated {
>> >>>>>   @WebMethod(operationName = "saveInheritEndpoint")
>> >>>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person
>> data);
>> >>>>> +    @WebResult(name = "Person")
>> >>>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
>> >> data);
>> >>>>>
>> >>>>>   @SchemaValidation(type = SchemaValidationType.NONE)
>> >>>>>   @WebMethod(operationName = "saveNoValidation")
>> >>>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
>> >>>>> +    @WebResult(name = "Person")
>> >>>>> +    Person saveNoValidation(@WebParam(name = "Person") Person
>> data);
>> >>>>>
>> >>>>>   @SchemaValidation(type = SchemaValidationType.IN)
>> >>>>>   @WebMethod(operationName = "saveValidateIn")
>> >>>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
>> >>>>> +    @WebResult(name = "Person")
>> >>>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>> >>>>>
>> >>>>>   @SchemaValidation(type = SchemaValidationType.OUT)
>> >>>>>   @WebMethod(operationName = "saveValidateOut")
>> >>>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
>> >>>>> +    @WebResult(name = "Person")
>> >>>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>> >>>>> }
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> >>>>> index c7b8038..78973c9 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> >>>>> +++
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> >>>>> @@ -26,18 +26,25 @@ import javax.jws.WebService;
>> >>>>>   targetNamespace = "
>> >>>> http://org.apache.cxf/service/PersonServiceAnnotated")
>> >>>>> public class PersonServiceAnnotatedImpl implements
>> >>>> PersonServiceAnnotated {
>> >>>>>   @Override
>> >>>>> -    public void saveNoValidation(Person data) {
>> >>>>> +    public Person saveNoValidation(Person data) {
>> >>>>> +        return data;
>> >>>>>   }
>> >>>>>
>> >>>>>   @Override
>> >>>>> -    public void saveInheritEndpoint(Person data) {
>> >>>>> +    public Person saveInheritEndpoint(Person data) {
>> >>>>> +        return data;
>> >>>>>   }
>> >>>>>
>> >>>>>   @Override
>> >>>>> -    public void saveValidateIn(Person data) {
>> >>>>> +    public Person saveValidateIn(Person data) {
>> >>>>> +        if ("InvalidResponse".equals(data.getFirstName())) {
>> >>>>> +            return new Person();
>> >>>>> +        }
>> >>>>> +        return data;
>> >>>>>   }
>> >>>>>
>> >>>>>   @Override
>> >>>>> -    public void saveValidateOut(Person data) {
>> >>>>> +    public Person saveValidateOut(Person data) {
>> >>>>> +        return data;
>> >>>>>   }
>> >>>>> }
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> >>>>> index fe1d656..9edec45 100644
>> >>>>> ---
>> >>>>
>> >>
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> >>>>> +++
>> >>>>
>> >>
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> >>>>> @@ -26,18 +26,22 @@ import javax.jws.WebService;
>> >>>>>   targetNamespace = "http://org.apache.cxf/service/PersonService")
>> >>>>> public class PersonServiceImpl implements PersonService {
>> >>>>>   @Override
>> >>>>> -    public void saveNoValidation(Person data) {
>> >>>>> +    public Person saveNoValidation(Person data) {
>> >>>>> +        return data;
>> >>>>>   }
>> >>>>>
>> >>>>>   @Override
>> >>>>> -    public void saveInheritEndpoint(Person data) {
>> >>>>> +    public Person saveInheritEndpoint(Person data) {
>> >>>>> +        return data;
>> >>>>>   }
>> >>>>>
>> >>>>>   @Override
>> >>>>> -    public void saveValidateIn(Person data) {
>> >>>>> +    public Person saveValidateIn(Person data) {
>> >>>>> +        return data;
>> >>>>>   }
>> >>>>>
>> >>>>>   @Override
>> >>>>> -    public void saveValidateOut(Person data) {
>> >>>>> +    public Person saveValidateOut(Person data) {
>> >>>>> +        return data;
>> >>>>>   }
>> >>>>> }
>> >>>>>
>> >>>>>
>> >>>>
>> >>
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> >>>>>
>> ----------------------------------------------------------------------
>> >>>>> diff --git
>> >>>>
>> >>
>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> >>>>
>> >>
>> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> >>>>> deleted file mode 100644
>> >>>>> index 18e66ae..0000000
>> >>>>> ---
>> >>>>
>> >>
>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> >>>>> +++ /dev/null
>> >>>>> @@ -1,69 +0,0 @@
>> >>>>> -/**
>> >>>>> - * Licensed to the Apache Software Foundation (ASF) under one
>> >>>>> - * or more contributor license agreements. See the NOTICE file
>> >>>>> - * distributed with this work for additional information
>> >>>>> - * regarding copyright ownership. The ASF licenses this file
>> >>>>> - * to you 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.cxf.systest.mtom_schema_validation;
>> >>>>> -
>> >>>>> -import java.io.File;
>> >>>>> -import java.net.URL;
>> >>>>> -
>> >>>>> -import javax.activation.DataHandler;
>> >>>>> -import javax.activation.FileDataSource;
>> >>>>> -import javax.xml.namespace.QName;
>> >>>>> -import javax.xml.ws.soap.MTOMFeature;
>> >>>>> -
>> >>>>> -import
>> org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
>> >>>>> -
>> >>>>> -import org.junit.BeforeClass;
>> >>>>> -import org.junit.Test;
>> >>>>> -
>> >>>>> -public final class MTOMProviderSchemaValidationTest extends
>> >>>> AbstractBusClientServerTestBase {
>> >>>>> -    public static final String PORT = "9001";
>> >>>>> -        //Server.PORT;
>> >>>>> -
>> >>>>> -    private final QName serviceName = new QName("
>> >> http://cxf.apache.org/",
>> >>>> "HelloWS");
>> >>>>> -
>> >>>>> -    @BeforeClass
>> >>>>> -    public static void startservers() throws Exception {
>> >>>>> -        //assertTrue("server did not launch correctly",
>> >>>> launchServer(Server.class, true));
>> >>>>> -    }
>> >>>>> -    @Test
>> >>>>> -    public void testSchemaValidation() throws Exception {
>> >>>>> -        HelloWS port = createService();
>> >>>>> -        Hello request = new Hello();
>> >>>>> -        request.setArg0("value");
>> >>>>> -        URL wsdl =
>> >>>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>> >>>>> -        File attachment = new File(wsdl.getFile());
>> >>>>> -        request.setFile(new DataHandler(new
>> >>>> FileDataSource(attachment)));
>> >>>>> -        HelloResponse response = port.hello(request);
>> >>>>> -        assertEquals("Hello CXF", response.getReturn());
>> >>>>> -    }
>> >>>>> -
>> >>>>> -    private HelloWS createService() throws Exception {
>> >>>>> -        URL wsdl =
>> >>>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>> >>>>> -        assertNotNull(wsdl);
>> >>>>> -
>> >>>>> -        HelloWSClient service = new HelloWSClient(wsdl,
>> serviceName);
>> >>>>> -        assertNotNull(service);
>> >>>>> -
>> >>>>> -        HelloWS port = service.getHello(new MTOMFeature());
>> >>>>> -
>> >>>>> -        updateAddressPort(port, PORT);
>> >>>>> -
>> >>>>> -        return port;
>> >>>>> -    }
>> >>>>> -}
>> >>>>>
>> >>>>
>> >>>> --
>> >>>> Daniel Kulp
>> >>>> dkulp@apache.org - http://dankulp.com/blog
>> >>>> Talend Community Coder - http://coders.talend.com
>> >>>>
>> >>>>
>> >>
>> >> --
>> >> Daniel Kulp
>> >> dkulp@apache.org - http://dankulp.com/blog
>> >> Talend Community Coder - http://coders.talend.com
>> >>
>> >>
>>
>> --
>> Daniel Kulp
>> dkulp@apache.org - http://dankulp.com/blog
>> Talend Community Coder - http://coders.talend.com
>>
>>

Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Jason Pell <ja...@pellcorp.com>.
Took me a while but I finally got where you are coming from. Thanks for the
detailed and informative replies.
On 29/11/2014 8:46 PM, "Daniel Kulp" <dk...@apache.org> wrote:

>
> > On Nov 29, 2014, at 1:44 AM, Jason Pell <ja...@pellcorp.com> wrote:
> >
> > If the same SEI is used for both service endpoint and client. The use of
> IN
> > would result in request being validated on server and response on client.
>
> Correct.
>
> As a point of note: from a performance standpoint, this is the best way to
> set things up if you want both messages validated at some point and have
> some level of control both the client and the server.  Validating messages
> during the reading is much easier and quicker.  During the out phases,
> validation is a bit trickier, particularly with the way CXF streams
> messages.   For outgoing messages, if you stream while validating, the
> validation exception would result in a  partial message being written out
> on the wire which would result in strange stack traces and such in the logs
> or strange exceptions on the other side.   The alternative is to buffer the
> full message during validation and only send if validation succeeds.   That
> has even larger performance (and memory) implications.
>
>
> > This is two different jaxb structures. In my theoretical case the service
> > designer only wants to validate the request because the service response
> > could be incomplete.
>
> Personally, I think if the service designer is explicitly sending invalid
> data, that’s a serious problem that needs to be re-thought.  They should
> get their schema updated to support the partial structures or whatever it
> is they are sending.   A client could be using a different toolkit
> (Metro/.NET/etc..) that has it’s own settings and such for schema
> validation and might have other problems with it.
>
> > In the current situation jaxws client would throw schema violation for
> the
> > response even though service designer did not ever envision validation
> the
> > response.
> >
> > This is where I struggle to see why that is acceptable.
>
> I’m struggling to see why sending invalid data is acceptable.  :-)   There
> is a point to having well defined contracts like WSDL’s that have schemas.
>
> Dan
>
>
>
>
> > Of course we can now just turn off validation on client so not really too
> > much of an issue.
> > On 29/11/2014 3:18 PM, "Daniel Kulp" <dk...@apache.org> wrote:
> >
> >>
> >>> On Nov 28, 2014, at 10:11 PM, Jason Pell <jp...@apache.org> wrote:
> >>>
> >>> Its only reversing what's coming from the model. If you define IN in
> the
> >>> jaxws properties on the client it will continue to validate IN on the
> >>> client as before.
> >>>
> >>> If I have IN defined for a operation using an annotation the old code
> >> would
> >>> actually validate the response coming back to the client.
> >>
> >> That’s exactly what IN is supposed to mean.
> >>
> >>> This does seem
> >>> counter intuitive especially as IN might have been specified because
> the
> >>> response may be incomplete and so can't be validated.
> >>
> >> It would be way more counter intuitive to me for IN to apply to messages
> >> that are going OUT.    That’s completely back wards.
> >>
> >>
> >>> An IN for service is the OUT for client.
> >>>
> >>> The previous code was just plain wrong for client side - my code by the
> >> way
> >>> :-)
> >>
> >> Why do you think it’s wrong?
> >>
> >> Basically, we have services that specify validation for IN as that is
> the
> >> only direction that we don’t control and we need to validate that.  For
> >> messages that we produce (out on client, out on server), we know the
> >> messages are valid as we populate the data correctly.   However, we
> >> need/want to validate any incoming data to make sure that is correct.
> That
> >> is exactly what IN is supposed to mean.  Validate any data coming IN.
> By
> >> putting the annotation on the SEI specified with IN, we would get what I
> >> would regard as the correct behavior.  Validation of the stuff we cannot
> >> control and no validation for the stuff we already know is correct.
> >>
> >>
> >>> This particular piece is only a few lines in ServiceUtils so I am happy
> >> to
> >>> remove it if you are still -1
> >>
> >> That part, yes.  It’s wrong.
> >>
> >> Dan
> >>
> >>
> >>> The alternative is I will add a property to enable it but only if the
> >>> property is used.
> >>>
> >>> Would that be OK?
> >>> On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:
> >>>
> >>>>
> >>>> I’m -1 on the part of this that changes the IN to an OUT on the client
> >>>> side.   The IN and OUT are specifically named that way as they apply
> to
> >> the
> >>>> messages that come IN to the client or IN to the server.   The “IN”
> >>>> validation should definitely not be applying to the messages going
> OUT.
> >>>> Plus, that would be a huge behavioral change that would break many
> >> peoples
> >>>> existing applications.
> >>>>
> >>>> Dan
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>> On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
> >>>>>
> >>>>> Repository: cxf
> >>>>> Updated Branches:
> >>>>> refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
> >>>>>
> >>>>>
> >>>>> CXF-6118 support overriding schema validation at jaxws endpoint and
> >>>> client level and applying the correct validation direction at client
> >> level
> >>>>>
> >>>>>
> >>>>> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
> >>>>> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
> >>>>> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
> >>>>> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
> >>>>>
> >>>>> Branch: refs/heads/2.7.x-fixes
> >>>>> Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
> >>>>> Parents: e172a3e
> >>>>> Author: Jason Pell <jp...@apache.org>
> >>>>> Authored: Thu Nov 27 16:54:01 2014 +1100
> >>>>> Committer: Jason Pell <jp...@apache.org>
> >>>>> Committed: Fri Nov 28 15:52:36 2014 +1100
> >>>>>
> >>>>>
> ----------------------------------------------------------------------
> >>>>> .../validation/SchemaValidationFeature.java     |   2 +-
> >>>>> .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
> >>>>> .../AbstractInDatabindingInterceptor.java       |  23 +-
> >>>>> .../AbstractOutDatabindingInterceptor.java      |  22 +-
> >>>>> .../java/org/apache/cxf/message/Message.java    |   9 +
> >>>>> .../soap/interceptor/RPCInInterceptor.java      |   2 +-
> >>>>> .../factory/AnnotationsFactoryBeanListener.java |   9 +-
> >>>>> .../JavaFirstSchemaValidationTest.java          | 256
> >> ++++++++++++++-----
> >>>>> .../jaxws/schemavalidation/PersonService.java   |  13 +-
> >>>>> .../PersonServiceAnnotated.java                 |  13 +-
> >>>>> .../PersonServiceAnnotatedImpl.java             |  15 +-
> >>>>> .../schemavalidation/PersonServiceImpl.java     |  12 +-
> >>>>> .../MTOMProviderSchemaValidationTest.bak        |  69 -----
> >>>>> 13 files changed, 342 insertions(+), 201 deletions(-)
> >>>>>
> ----------------------------------------------------------------------
> >>>>>
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>>>
> >>
> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>>>> index 5eda79c..c314eaf 100644
> >>>>> ---
> >>>>
> >>
> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>>>> +++
> >>>>
> >>
> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>>>> @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
> >>>> AbstractFeature {
> >>>>>       for (BindingOperationInfo bop :
> >>>> endpoint.getEndpointInfo().getBinding().getOperations()) {
> >>>>>           SchemaValidationType type =
> >>>> provider.getSchemaValidationType(bop.getOperationInfo());
> >>>>>           if (type != null) {
> >>>>> -
> >>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> >> type);
> >>>>> +
> >>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >> type);
> >>>>>           }
> >>>>>       }
> >>>>>   }
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>>> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>>>> index 85d77d0..28c7ba2 100644
> >>>>> --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>>>> +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>>>> @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
> >>>>> import javax.xml.namespace.QName;
> >>>>>
> >>>>> import
> >> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>>>> +import org.apache.cxf.endpoint.Endpoint;
> >>>>> +import org.apache.cxf.message.Exchange;
> >>>>> import org.apache.cxf.message.Message;
> >>>>> +import org.apache.cxf.message.MessageUtils;
> >>>>> +import org.apache.cxf.service.model.AbstractPropertiesHolder;
> >>>>> +import org.apache.cxf.service.model.BindingOperationInfo;
> >>>>> +import org.apache.cxf.service.model.EndpointInfo;
> >>>>> +import org.apache.cxf.service.model.OperationInfo;
> >>>>>
> >>>>> public final class ServiceUtils {
> >>>>> -
> >>>>>   private ServiceUtils() {
> >>>>>   }
> >>>>>
> >>>>> @@ -42,24 +48,94 @@ public final class ServiceUtils {
> >>>>>    * @param type
> >>>>>    */
> >>>>>   public static boolean
> isSchemaValidationEnabled(SchemaValidationType
> >>>> type, Message message) {
> >>>>> -        SchemaValidationType messageType =
> >>>> getSchemaValidationType(message);
> >>>>> +        SchemaValidationType validationType =
> >>>> getSchemaValidationType(message);
> >>>>>
> >>>>> -        return messageType.equals(type)
> >>>>> +        return validationType.equals(type)
> >>>>>           || ((SchemaValidationType.IN.equals(type) ||
> >>>> SchemaValidationType.OUT.equals(type))
> >>>>> -                && SchemaValidationType.BOTH.equals(messageType));
> >>>>> +                &&
> SchemaValidationType.BOTH.equals(validationType));
> >>>>>   }
> >>>>> -
> >>>>> +
> >>>>>   /**
> >>>>> -     * Determines the appropriate SchemaValidationType to return
> based
> >>>> on either
> >>>>> -     * a Boolean (for backwards compatibility) or the selected
> Schema
> >>>> Validation Type.
> >>>>> -     *
> >>>>> -     * Package private as the isSchemaValidationEnabled method
> should
> >>>> be used instead.  Only
> >>>>> -     * visible for easier testing
> >>>>> +     * A convenience method to check for schema validation config in
> >>>> the message context, and then in the service model.
> >>>>> +     * Does not modify the Message context (other than what is done
> in
> >>>> the getContextualProperty itself)
> >>>>>    *
> >>>>>    * @param message
> >>>>> +     * @param type
> >>>>>    */
> >>>>> -    static SchemaValidationType getSchemaValidationType(Message
> >>>> message) {
> >>>>> +    public static SchemaValidationType
> getSchemaValidationType(Message
> >>>> message) {
> >>>>> +        SchemaValidationType validationType =
> >>>> getOverrideSchemaValidationType(message);
> >>>>> +        if (validationType == null) {
> >>>>> +            validationType =
> >> getSchemaValidationTypeFromModel(message);
> >>>>> +        }
> >>>>> +
> >>>>> +        if (validationType == null) {
> >>>>> +            validationType = SchemaValidationType.NONE;
> >>>>> +        }
> >>>>> +
> >>>>> +        return validationType;
> >>>>> +    }
> >>>>> +
> >>>>> +    private static SchemaValidationType
> >>>> getOverrideSchemaValidationType(Message message) {
> >>>>>       Object obj =
> >>>> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>>>> +        if (obj != null) {
> >>>>> +            // this method will transform the legacy enabled as well
> >>>>> +            return getSchemaValidationType(obj);
> >>>>> +        } else {
> >>>>> +            return null;
> >>>>> +        }
> >>>>> +    }
> >>>>> +
> >>>>> +    private static SchemaValidationType
> >>>> getSchemaValidationTypeFromModel(Message message) {
> >>>>> +        boolean isRequestor = MessageUtils.isRequestor(message);
> >>>>> +        Exchange exchange = message.getExchange();
> >>>>> +
> >>>>> +        if (exchange != null) {
> >>>>> +            BindingOperationInfo boi =
> >>>> exchange.getBindingOperationInfo();
> >>>>> +            Endpoint endpoint = exchange.getEndpoint();
> >>>>> +
> >>>>> +            if (boi != null && endpoint != null) {
> >>>>> +                SchemaValidationType validationType = null;
> >>>>> +                OperationInfo opInfo = boi.getOperationInfo();
> >>>>> +                EndpointInfo ep = endpoint.getEndpointInfo();
> >>>>> +
> >>>>> +                if (validationType == null && opInfo != null) {
> >>>>> +                    validationType =
> >>>> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
> >>>>> +
> >>>>> +                    if (validationType == null && ep != null) {
> >>>>> +                        validationType =
> >>>> getSchemaValidationTypeFromModel(message, ep, isRequestor);
> >>>>> +                    }
> >>>>> +                }
> >>>>> +
> >>>>> +                return validationType;
> >>>>> +            }
> >>>>> +        }
> >>>>> +
> >>>>> +        // else
> >>>>> +        return null;
> >>>>> +    }
> >>>>> +
> >>>>> +    private static SchemaValidationType
> >>>> getSchemaValidationTypeFromModel(
> >>>>> +            Message message, AbstractPropertiesHolder properties,
> >>>> boolean isRequestor) {
> >>>>> +        Object obj =
> >>>> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
> >>>>> +        if (obj != null) {
> >>>>> +            SchemaValidationType validationType =
> >>>> getSchemaValidationType(obj);
> >>>>> +
> >>>>> +            // Reverse the direction of any IN / OUT for requestor
> >>>> (client)
> >>>>> +            if (isRequestor) {
> >>>>> +                if (SchemaValidationType.IN.equals(validationType))
> {
> >>>>> +                    return SchemaValidationType.OUT;
> >>>>> +                } else if
> >>>> (SchemaValidationType.OUT.equals(validationType)) {
> >>>>> +                    return SchemaValidationType.IN;
> >>>>> +                }
> >>>>> +            }
> >>>>> +
> >>>>> +            return validationType;
> >>>>> +        } else {
> >>>>> +            return null;
> >>>>> +        }
> >>>>> +    }
> >>>>> +
> >>>>> +    public static SchemaValidationType
> getSchemaValidationType(Object
> >>>> obj) {
> >>>>>       if (obj instanceof SchemaValidationType) {
> >>>>>           return (SchemaValidationType)obj;
> >>>>>       } else if (obj != null) {
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>>>
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>>>> index c47417a..ec8cf71 100644
> >>>>> ---
> >>>>
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>>>> +++
> >>>>
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>>>> @@ -125,24 +125,9 @@ public abstract class
> >>>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
> >>>>>       }
> >>>>>   }
> >>>>>
> >>>>> -    /**
> >>>>> -     * Where an operation level validation type has been set, copy
> it
> >>>> to the message, so it can be interrogated
> >>>>> -     * by all downstream interceptors.  It is expected that sub
> >> classes
> >>>> will call setDataReaderValidation subsequent
> >>>>> -     * to this to ensure the DataReader schema reference is updated
> as
> >>>> appropriate.
> >>>>> -     *
> >>>>> -     * @param bop
> >>>>> -     * @param message
> >>>>> -     * @param reader
> >>>>> -     * @see #setDataReaderValidation(Service, Message, DataReader)
> >>>>> -     */
> >>>>> -    protected void setOperationSchemaValidation(OperationInfo
> opInfo,
> >>>> Message message) {
> >>>>> -        if (opInfo != null) {
> >>>>> -            SchemaValidationType validationType =
> >>>>> -                (SchemaValidationType)
> >>>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>>>> -            if (validationType != null) {
> >>>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
> >>>> validationType);
> >>>>> -            }
> >>>>> -        }
> >>>>> +    protected void setOperationSchemaValidation(Message message) {
> >>>>> +        SchemaValidationType validationType =
> >>>> ServiceUtils.getSchemaValidationType(message);
> >>>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> validationType);
> >>>>>   }
> >>>>>
> >>>>>   protected DepthXMLStreamReader getXMLStreamReader(Message message)
> {
> >>>>> @@ -247,7 +232,7 @@ public abstract class
> >>>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
> >>>>>       }
> >>>>>
> >>>>>       // configure endpoint and operation level schema validation
> >>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >>>> message);
> >>>>> +        setOperationSchemaValidation(message);
> >>>>>
> >>>>>       QName serviceQName = si.getName();
> >>>>>       message.put(Message.WSDL_SERVICE, serviceQName);
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>>>
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>>>> index db3ba6c..52d1cb1 100644
> >>>>> ---
> >>>>
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>>>> +++
> >>>>
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>>>> @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
> >>>>> import org.apache.cxf.service.model.BindingInfo;
> >>>>> import org.apache.cxf.service.model.BindingOperationInfo;
> >>>>> import org.apache.cxf.service.model.MessagePartInfo;
> >>>>> -import org.apache.cxf.service.model.OperationInfo;
> >>>>> import org.apache.cxf.staxutils.CachingXmlEventWriter;
> >>>>> import org.apache.cxf.staxutils.StaxUtils;
> >>>>> import org.apache.cxf.wsdl.EndpointReferenceUtils;
> >>>>> @@ -85,7 +84,7 @@ public abstract class
> >>>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
> >>>>>       CachingXmlEventWriter cache = null;
> >>>>>
> >>>>>       // configure endpoint and operation level schema validation
> >>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >>>> message);
> >>>>> +        setOperationSchemaValidation(message);
> >>>>>
> >>>>>       // need to cache the events in case validation fails or
> >>>> buffering is enabled
> >>>>>       if (shouldBuffer(message)) {
> >>>>> @@ -159,22 +158,9 @@ public abstract class
> >>>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
> >>>>>       }
> >>>>>   }
> >>>>>
> >>>>> -    /**
> >>>>> -     * Where an operation level validation type has been set, copy
> it
> >>>> to the message, so it can be interrogated
> >>>>> -     * by all downstream interceptors
> >>>>> -     *
> >>>>> -     * @param bop
> >>>>> -     * @param message
> >>>>> -     * @param reader
> >>>>> -     */
> >>>>> -    private void setOperationSchemaValidation(OperationInfo opInfo,
> >>>> Message message) {
> >>>>> -        if (opInfo != null) {
> >>>>> -            SchemaValidationType validationType =
> >>>>> -                (SchemaValidationType)
> >>>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>>>> -            if (validationType != null) {
> >>>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
> >>>> validationType);
> >>>>> -            }
> >>>>> -        }
> >>>>> +    protected void setOperationSchemaValidation(Message message) {
> >>>>> +        SchemaValidationType validationType =
> >>>> ServiceUtils.getSchemaValidationType(message);
> >>>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> validationType);
> >>>>>   }
> >>>>>
> >>>>>   protected boolean shouldValidate(Message m) {
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
> >>>> b/api/src/main/java/org/apache/cxf/message/Message.java
> >>>>> index 35e94af..5854a18 100644
> >>>>> --- a/api/src/main/java/org/apache/cxf/message/Message.java
> >>>>> +++ b/api/src/main/java/org/apache/cxf/message/Message.java
> >>>>> @@ -105,7 +105,16 @@ public interface Message extends StringMap {
> >>>>>    */
> >>>>>   String MTOM_ENABLED = "mtom-enabled";
> >>>>>   String MTOM_THRESHOLD = "mtom-threshold";
> >>>>> +
> >>>>> +    /**
> >>>>> +     * Runtime schema validation property
> >>>>> +     */
> >>>>>   String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
> >>>>> +
> >>>>> +    /**
> >>>>> +     * The default values for schema validation will be set in the
> >>>> service model using this property
> >>>>> +     */
> >>>>> +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
> >>>>>
> >>>>>   /**
> >>>>>    * Boolean property specifying if the Java stack trace is returned
> >>>> as a
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>>>
> >>
> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>>>> index fafd0a9..d49f090 100644
> >>>>> ---
> >>>>
> >>
> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>>>> +++
> >>>>
> >>
> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>>>> @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
> >>>> AbstractInDatabindingInterceptor {
> >>>>>       message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
> >>>>>
> >>>>>       // configure endpoint and operation level schema validation
> >>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >>>> message);
> >>>>> +        setOperationSchemaValidation(message);
> >>>>>   }
> >>>>> }
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>>>
> >>
> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>>>> index 7100f2c..9a7cbc8 100644
> >>>>> ---
> >>>>
> >>
> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>>>> +++
> >>>>
> >>
> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>>>> @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
> >>>> implements FactoryBeanListener {
> >>>>>           // if someone has gone to the effort of specifying
> >>>> enabled=false, then we need to
> >>>>>           // handle that, otherwise we use the new
> >>>> SchemaValidationType type only
> >>>>>           if (!annotation.enabled()) {
> >>>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
> >>>> SchemaValidationType.NONE);
> >>>>> +
> >>>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >>>> SchemaValidationType.NONE);
> >>>>>           } else {
> >>>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
> >>>> annotation.type());
> >>>>> +
> >>>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >>>> annotation.type());
> >>>>>           }
> >>>>>       }
> >>>>>   }
> >>>>> @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
> >>>> implements FactoryBeanListener {
> >>>>>   }
> >>>>>
> >>>>>   private void addSchemaValidationSupport(OperationInfo inf,
> >>>> SchemaValidation annotation) {
> >>>>> -        // Notice no support for deprecated enabled property here!
> >>>>> -        // TODO - should we check for the use of this property and
> at
> >>>> least log the fact we are
> >>>>> -        // ignoring it
> >>>>>       if (annotation != null) {
> >>>>> -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> >>>> annotation.type());
> >>>>> +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >>>> annotation.type());
> >>>>>       }
> >>>>>   }
> >>>>>
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>>>> index 888e5a8..9f08839 100644
> >>>>> ---
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>>>> +++
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>>>> @@ -20,12 +20,15 @@
> >>>>> package org.apache.cxf.systest.jaxws.schemavalidation;
> >>>>>
> >>>>> import java.io.IOException;
> >>>>> +import java.io.PrintWriter;
> >>>>> +import java.io.StringWriter;
> >>>>> import java.util.ArrayList;
> >>>>> import java.util.Arrays;
> >>>>> import java.util.HashMap;
> >>>>> import java.util.List;
> >>>>> import java.util.Map;
> >>>>>
> >>>>> +import javax.xml.ws.WebServiceException;
> >>>>> import javax.xml.ws.soap.SOAPFaultException;
> >>>>>
> >>>>> import
> >> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>>>> @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
> >>>>> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
> >>>>> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
> >>>>> import org.apache.cxf.message.Message;
> >>>>> -import org.apache.cxf.service.model.BindingOperationInfo;
> >>>>> import org.apache.cxf.testutil.common.TestUtil;
> >>>>> +import org.apache.cxf.transport.http.HTTPConduit;
> >>>>> +import
> org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
> >>>>> import org.junit.AfterClass;
> >>>>> import org.junit.Assert;
> >>>>> import org.junit.BeforeClass;
> >>>>> import org.junit.Test;
> >>>>>
> >>>>> -/**
> >>>>> - * TODO - test where the default is NONE at the service level test
> >>>> where the default is IN or OUT, and then
> >>>>> - * override at operation levels
> >>>>> - */
> >>>>> public class JavaFirstSchemaValidationTest extends Assert {
> >>>>> -    static final String PORT =
> >>>> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
> >>>>> +    static final String PORT =
> >>>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> >>>>> +    static final String PORT_UNUSED =
> >>>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> >>>>>
> >>>>>   private static List<Server> serverList = new ArrayList<Server>();
> >>>>>   private static PersonServiceAnnotated annotatedClient;
> >>>>> +    private static PersonServiceAnnotated annotatedValidatingClient;
> >>>>>   private static PersonService client;
> >>>>>   private static PersonServiceRPC rpcClient;
> >>>>> +
> >>>>> +    private static PersonService disconnectedClient;
> >>>>>
> >>>>>   @BeforeClass
> >>>>>   public static void startServers() throws Exception {
> >>>>> @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends
> >>>> Assert {
> >>>>>
> >>>>>       createServer(PersonServiceRPC.class, new
> PersonServiceRPCImpl(),
> >>>> feature, new LoggingFeature());
> >>>>>
> >>>>> -        annotatedClient =
> createClient(PersonServiceAnnotated.class);
> >>>>> -        client = createClient(PersonService.class);
> >>>>> -        rpcClient = createClient(PersonServiceRPC.class);
> >>>>> +        annotatedClient = createClient(PORT,
> >>>> PersonServiceAnnotated.class, SchemaValidationType.NONE);
> >>>>> +        annotatedValidatingClient = createClient(PORT,
> >>>> PersonServiceAnnotated.class, null);
> >>>>> +        client = createClient(PORT, PersonService.class,
> >>>> SchemaValidationType.NONE);
> >>>>> +        disconnectedClient = createClient(PORT_UNUSED,
> >>>> PersonService.class, SchemaValidationType.OUT);
> >>>>> +        rpcClient = createClient(PORT, PersonServiceRPC.class,
> >>>> SchemaValidationType.NONE);
> >>>>>   }
> >>>>>
> >>>>>   @AfterClass
> >>>>> @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends
> >>>> Assert {
> >>>>>       }
> >>>>>   }
> >>>>>
> >>>>> -    static String getAddress(Class<?> sei) {
> >>>>> -        return "http://localhost:" + PORT + "/" +
> >> sei.getSimpleName();
> >>>>> +    static String getAddress(String port, Class<?> sei) {
> >>>>> +        return "http://localhost:" + port + "/" +
> >> sei.getSimpleName();
> >>>>>   }
> >>>>> -
> >>>>>
> >>>>>   @Test
> >>>>>   public void testRPCLit() throws Exception {
> >>>>> @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest
> extends
> >>>> Assert {
> >>>>>       try {
> >>>>>           person.setFirstName(null);
> >>>>>           rpcClient.saveValidateOut(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>>           assertTrue(sfe.getMessage().contains("Marshalling Error"));
> >>>>>           assertTrue(sfe.getMessage().contains("lastName"));
> >>>>>       }
> >>>>> @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest
> >> extends
> >>>> Assert {
> >>>>>
> >>>>>       try {
> >>>>>           annotatedClient.saveInheritEndpoint(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >>>> Error"));
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>>       }
> >>>>>
> >>>>>       try {
> >>>>>           person.setFirstName(""); // empty string is valid
> >>>>>           annotatedClient.saveInheritEndpoint(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >>>> Error"));
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>>       }
> >>>>>
> >>>>>       person.setLastName(""); // empty string is valid
> >>>>>       annotatedClient.saveInheritEndpoint(person);
> >>>>>   }
> >>>>> -
> >>>>> +
> >>>>>   @Test
> >>>>>   public void testSaveValidateInAnnotated() {
> >>>>>       Person person = new Person();
> >>>>>
> >>>>>       try {
> >>>>>           annotatedClient.saveValidateIn(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >>>> Error"));
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>>       }
> >>>>>
> >>>>>       try {
> >>>>>           person.setFirstName(""); // empty string is valid
> >>>>>           annotatedClient.saveValidateIn(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >>>> Error"));
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>>       }
> >>>>>
> >>>>>       person.setLastName(""); // empty string is valid
> >>>>> @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
> >>>> extends Assert {
> >>>>>       annotatedClient.saveNoValidation(person);
> >>>>>   }
> >>>>>
> >>>>> -    // no validation is required for incoming
> >>>>>   @Test
> >>>>> -    public void testSaveValidationOutAnnotated() {
> >>>>> +    public void
> >>>> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
> >>>>>       Person person = new Person();
> >>>>>
> >>>>> -        annotatedClient.saveValidateOut(person);
> >>>>> +        try {
> >>>>> +            annotatedClient.saveValidateOut(person);
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            // verify its server side and a schema validation
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>> +            // it's still a server side fault, because server side
> >>>> validation coming in failed
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>> +
> >>>>> +        person.setFirstName(""); // empty string is valid
> >>>>> +        try {
> >>>>> +            annotatedClient.saveValidateOut(person);
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            // verify its server side and a schema validation
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>> +            // it's still a server side fault, because server side
> >>>> validation coming in failed
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>>
> >>>>> +        person.setLastName(""); // empty string is valid
> >>>>> +        annotatedClient.saveValidateIn(person);
> >>>>> +    }
> >>>>> +
> >>>>> +    // this will still all be server side, as the OUT validation is
> >>>> turned into an IN validation for
> >>>>> +    // the client, but by then the server has already thrown the
> >>>> exception for the OUT
> >>>>> +    @Test
> >>>>> +    public void
> >>>> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
> >>>>> +        Person person = new Person();
> >>>>> +
> >>>>> +        try {
> >>>>> +            annotatedValidatingClient.saveValidateIn(person);
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>> +
> >>>>>       person.setFirstName(""); // empty string is valid
> >>>>> -        annotatedClient.saveValidateOut(person);
> >>>>> +        try {
> >>>>> +            annotatedValidatingClient.saveValidateIn(person);
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>>
> >>>>>       person.setLastName(""); // empty string is valid
> >>>>> -        annotatedClient.saveValidateOut(person);
> >>>>> +        annotatedValidatingClient.saveValidateIn(person);
> >>>>> +    }
> >>>>> +
> >>>>> +    @Test
> >>>>> +    public void
> >>>> testSaveValidationInAnnotatedWithClientValidationEnabled() {
> >>>>> +        Person person = new Person();
> >>>>> +
> >>>>> +        try {
> >>>>> +            person.setFirstName("InvalidResponse");
> >>>>> +            person.setLastName("WhoCares");
> >>>>> +            annotatedValidatingClient.saveValidateOut(person);
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>>   }
> >>>>>
> >>>>> -    // so this is the default, we are inheriting from the service
> >> level
> >>>> SchemaValidation annotation
> >>>>> -    // which is set to BOTH
> >>>>>   @Test
> >>>>>   public void testEndpointSchemaValidationProvider() {
> >>>>>       Person person = new Person();
> >>>>>
> >>>>>       try {
> >>>>>           client.saveInheritEndpoint(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >>>> Error"));
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>>       }
> >>>>> -
> >>>>> +
> >>>>>       try {
> >>>>>           person.setFirstName(""); // empty string is valid
> >>>>>           client.saveInheritEndpoint(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >>>> Error"));
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>>       }
> >>>>>
> >>>>>       person.setLastName(""); // empty string is valid
> >>>>> @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest
> >> extends
> >>>> Assert {
> >>>>>
> >>>>>       try {
> >>>>>           client.saveValidateIn(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >>>> Error"));
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>>       }
> >>>>>
> >>>>>       try {
> >>>>>           person.setFirstName(""); // empty string is valid
> >>>>>           client.saveValidateIn(person);
> >>>>> +            fail("Expected exception");
> >>>>>       } catch (SOAPFaultException sfe) {
> >>>>> -            // verify its server side and a schema validation
> >>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >>>> Error"));
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>>       }
> >>>>>
> >>>>>       person.setLastName(""); // empty string is valid
> >>>>>       client.saveValidateIn(person);
> >>>>>   }
> >>>>>
> >>>>> -    // no validation at all is required
> >>>>>   @Test
> >>>>>   public void testSaveNoValidationProvider() {
> >>>>>       Person person = new Person();
> >>>>> @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest
> >> extends
> >>>> Assert {
> >>>>>       client.saveNoValidation(person);
> >>>>>   }
> >>>>>
> >>>>> -    // no validation is required for incoming
> >>>>>   @Test
> >>>>> -    public void testSaveValidationOutProvider() {
> >>>>> +    public void testSaveValidationOutProviderClientOnly() {
> >>>>>       Person person = new Person();
> >>>>>
> >>>>> -        client.saveValidateOut(person);
> >>>>> +        try {
> >>>>> +            disconnectedClient.saveValidateOut(person);
> >>>>> +            fail("Expected exception");
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            // verify its client side outgoing
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>> +
> >>>>> +        person.setFirstName(""); // empty string is valid
> >>>>> +        try {
> >>>>> +            disconnectedClient.saveValidateOut(person);
> >>>>> +            fail("Expected exception");
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            // verify its client side outgoing
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>> +
> >>>>> +        person.setLastName(""); // empty string is valid
> >>>>> +
> >>>>> +        // this confirms that we passed client validation as we then
> >>>> got the connectivity error
> >>>>> +        try {
> >>>>> +            disconnectedClient.saveValidateOut(person);
> >>>>> +            fail("Expected exception");
> >>>>> +        } catch (WebServiceException e) {
> >>>>> +            assertTrue(e.getMessage().contains("Could not send
> >>>> Message"));
> >>>>> +        }
> >>>>> +    }
> >>>>>
> >>>>> +
> >>>>> +    @Test
> >>>>> +    public void testSaveValidationOutProvider() {
> >>>>> +        Person person = new Person();
> >>>>> +
> >>>>> +        try {
> >>>>> +            client.saveValidateOut(person);
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            // verify its server side outgoing
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>> +
> >>>>>       person.setFirstName(""); // empty string is valid
> >>>>> -        client.saveValidateOut(person);
> >>>>> +        try {
> >>>>> +            client.saveValidateOut(person);
> >>>>> +        } catch (SOAPFaultException sfe) {
> >>>>> +            // verify its server side outgoing
> >>>>> +            String stackTrace = getStackTrace(sfe);
> >>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>>>> +
> >>>>
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>>> +        }
> >>>>>
> >>>>>       person.setLastName(""); // empty string is valid
> >>>>>       client.saveValidateOut(person);
> >>>>>   }
> >>>>>
> >>>>> -    private static <T> T createClient(Class<T> serviceClass) {
> >>>>> +    private static <T> T createClient(String port, Class<T>
> >>>> serviceClass, SchemaValidationType type) {
> >>>>>       JaxWsProxyFactoryBean clientFactory = new
> >>>> JaxWsProxyFactoryBean();
> >>>>>       clientFactory.setServiceClass(serviceClass);
> >>>>> -
> >>>>> -        // ensure all client schema validation is disabled
> >>>>> -        Map<String, Object> properties = new HashMap<String,
> >> Object>();
> >>>>> -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
> >>>> SchemaValidationType.NONE);
> >>>>> -        clientFactory.setProperties(properties);
> >>>>> -
> >>>>> -        clientFactory.setAddress(getAddress(serviceClass));
> >>>>> -
> >>>>> +
> >>>>> +
> >>>>> +        clientFactory.setAddress(getAddress(port, serviceClass));
> >>>>> +
> >>>>> +
> >>>>>       @SuppressWarnings("unchecked")
> >>>>>       T newClient = (T)clientFactory.create();
> >>>>>
> >>>>> -        Client clientProxy = ClientProxy.getClient(newClient);
> >>>>> -
> >>>>> -        // ensure all client schema validation is disabled
> >>>>> -        for (BindingOperationInfo bop :
> >>>> clientProxy.getEndpoint().getEndpointInfo().getBinding()
> >>>>> -            .getOperations()) {
> >>>>> -
> >>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> >>>> SchemaValidationType.NONE);
> >>>>> +        Client proxy = ClientProxy.getClient(newClient);
> >>>>> +
> >>>>> +        if (type != null) {
> >>>>> +
> >>>> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED,
> type);
> >>>>>       }
> >>>>> -
> >>>>> +
> >>>>> +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
> >>>>> +        // give me longer debug times
> >>>>> +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
> >>>>> +        clientPolicy.setConnectionTimeout(1000000);
> >>>>> +        clientPolicy.setReceiveTimeout(1000000);
> >>>>> +        conduit.setClient(clientPolicy);
> >>>>> +
> >>>>>       return newClient;
> >>>>>   }
> >>>>>
> >>>>> @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest
> >> extends
> >>>> Assert {
> >>>>>       if (features != null) {
> >>>>>           svrFactory.getFeatures().addAll(Arrays.asList(features));
> >>>>>       }
> >>>>> -        svrFactory.setAddress(getAddress(serviceInterface));
> >>>>> +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
> >>>>>       svrFactory.setServiceBean(serviceImpl);
> >>>>>       Server server = svrFactory.create();
> >>>>>       serverList.add(server);
> >>>>>       return server;
> >>>>>   }
> >>>>> +
> >>>>> +    private String getStackTrace(Exception e) {
> >>>>> +        StringWriter sWriter = new StringWriter();
> >>>>> +        PrintWriter writer = new PrintWriter(sWriter, true);
> >>>>> +        e.printStackTrace(writer);
> >>>>> +        return sWriter.toString();
> >>>>> +    }
> >>>>> }
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>>>> index e3ee10c..d594e4e 100644
> >>>>> ---
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>>>> +++
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>>>> @@ -21,6 +21,7 @@ package
> >> org.apache.cxf.systest.jaxws.schemavalidation;
> >>>>>
> >>>>> import javax.jws.WebMethod;
> >>>>> import javax.jws.WebParam;
> >>>>> +import javax.jws.WebResult;
> >>>>> import javax.jws.WebService;
> >>>>>
> >>>>> import org.apache.cxf.annotations.SchemaValidation;
> >>>>> @@ -30,14 +31,18 @@ import
> >>>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>>>> @SchemaValidation(type = SchemaValidationType.BOTH)
> >>>>> public interface PersonService {
> >>>>>   @WebMethod(operationName = "saveInheritEndpoint")
> >>>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person
> data);
> >>>>> +    @WebResult(name = "Person")
> >>>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
> >> data);
> >>>>>
> >>>>>   @WebMethod(operationName = "saveNoValidation")
> >>>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
> >>>>> +    @WebResult(name = "Person")
> >>>>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> >>>>>
> >>>>>   @WebMethod(operationName = "saveValidateIn")
> >>>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
> >>>>> +    @WebResult(name = "Person")
> >>>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> >>>>>
> >>>>>   @WebMethod(operationName = "saveValidateOut")
> >>>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
> >>>>> +    @WebResult(name = "Person")
> >>>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> >>>>> }
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>>>> index 3e06576..a760f27 100644
> >>>>> ---
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>>>> +++
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>>>> @@ -21,6 +21,7 @@ package
> >> org.apache.cxf.systest.jaxws.schemavalidation;
> >>>>>
> >>>>> import javax.jws.WebMethod;
> >>>>> import javax.jws.WebParam;
> >>>>> +import javax.jws.WebResult;
> >>>>> import javax.jws.WebService;
> >>>>>
> >>>>> import org.apache.cxf.annotations.SchemaValidation;
> >>>>> @@ -30,17 +31,21 @@ import
> >>>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>>>> @SchemaValidation(type = SchemaValidationType.BOTH)
> >>>>> public interface PersonServiceAnnotated {
> >>>>>   @WebMethod(operationName = "saveInheritEndpoint")
> >>>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person
> data);
> >>>>> +    @WebResult(name = "Person")
> >>>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
> >> data);
> >>>>>
> >>>>>   @SchemaValidation(type = SchemaValidationType.NONE)
> >>>>>   @WebMethod(operationName = "saveNoValidation")
> >>>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
> >>>>> +    @WebResult(name = "Person")
> >>>>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> >>>>>
> >>>>>   @SchemaValidation(type = SchemaValidationType.IN)
> >>>>>   @WebMethod(operationName = "saveValidateIn")
> >>>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
> >>>>> +    @WebResult(name = "Person")
> >>>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> >>>>>
> >>>>>   @SchemaValidation(type = SchemaValidationType.OUT)
> >>>>>   @WebMethod(operationName = "saveValidateOut")
> >>>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
> >>>>> +    @WebResult(name = "Person")
> >>>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> >>>>> }
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>>>> index c7b8038..78973c9 100644
> >>>>> ---
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>>>> +++
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>>>> @@ -26,18 +26,25 @@ import javax.jws.WebService;
> >>>>>   targetNamespace = "
> >>>> http://org.apache.cxf/service/PersonServiceAnnotated")
> >>>>> public class PersonServiceAnnotatedImpl implements
> >>>> PersonServiceAnnotated {
> >>>>>   @Override
> >>>>> -    public void saveNoValidation(Person data) {
> >>>>> +    public Person saveNoValidation(Person data) {
> >>>>> +        return data;
> >>>>>   }
> >>>>>
> >>>>>   @Override
> >>>>> -    public void saveInheritEndpoint(Person data) {
> >>>>> +    public Person saveInheritEndpoint(Person data) {
> >>>>> +        return data;
> >>>>>   }
> >>>>>
> >>>>>   @Override
> >>>>> -    public void saveValidateIn(Person data) {
> >>>>> +    public Person saveValidateIn(Person data) {
> >>>>> +        if ("InvalidResponse".equals(data.getFirstName())) {
> >>>>> +            return new Person();
> >>>>> +        }
> >>>>> +        return data;
> >>>>>   }
> >>>>>
> >>>>>   @Override
> >>>>> -    public void saveValidateOut(Person data) {
> >>>>> +    public Person saveValidateOut(Person data) {
> >>>>> +        return data;
> >>>>>   }
> >>>>> }
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>>>> index fe1d656..9edec45 100644
> >>>>> ---
> >>>>
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>>>> +++
> >>>>
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>>>> @@ -26,18 +26,22 @@ import javax.jws.WebService;
> >>>>>   targetNamespace = "http://org.apache.cxf/service/PersonService")
> >>>>> public class PersonServiceImpl implements PersonService {
> >>>>>   @Override
> >>>>> -    public void saveNoValidation(Person data) {
> >>>>> +    public Person saveNoValidation(Person data) {
> >>>>> +        return data;
> >>>>>   }
> >>>>>
> >>>>>   @Override
> >>>>> -    public void saveInheritEndpoint(Person data) {
> >>>>> +    public Person saveInheritEndpoint(Person data) {
> >>>>> +        return data;
> >>>>>   }
> >>>>>
> >>>>>   @Override
> >>>>> -    public void saveValidateIn(Person data) {
> >>>>> +    public Person saveValidateIn(Person data) {
> >>>>> +        return data;
> >>>>>   }
> >>>>>
> >>>>>   @Override
> >>>>> -    public void saveValidateOut(Person data) {
> >>>>> +    public Person saveValidateOut(Person data) {
> >>>>> +        return data;
> >>>>>   }
> >>>>> }
> >>>>>
> >>>>>
> >>>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>>>>
> ----------------------------------------------------------------------
> >>>>> diff --git
> >>>>
> >>
> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>>>
> >>
> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>>>> deleted file mode 100644
> >>>>> index 18e66ae..0000000
> >>>>> ---
> >>>>
> >>
> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>>>> +++ /dev/null
> >>>>> @@ -1,69 +0,0 @@
> >>>>> -/**
> >>>>> - * Licensed to the Apache Software Foundation (ASF) under one
> >>>>> - * or more contributor license agreements. See the NOTICE file
> >>>>> - * distributed with this work for additional information
> >>>>> - * regarding copyright ownership. The ASF licenses this file
> >>>>> - * to you 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.cxf.systest.mtom_schema_validation;
> >>>>> -
> >>>>> -import java.io.File;
> >>>>> -import java.net.URL;
> >>>>> -
> >>>>> -import javax.activation.DataHandler;
> >>>>> -import javax.activation.FileDataSource;
> >>>>> -import javax.xml.namespace.QName;
> >>>>> -import javax.xml.ws.soap.MTOMFeature;
> >>>>> -
> >>>>> -import
> org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> >>>>> -
> >>>>> -import org.junit.BeforeClass;
> >>>>> -import org.junit.Test;
> >>>>> -
> >>>>> -public final class MTOMProviderSchemaValidationTest extends
> >>>> AbstractBusClientServerTestBase {
> >>>>> -    public static final String PORT = "9001";
> >>>>> -        //Server.PORT;
> >>>>> -
> >>>>> -    private final QName serviceName = new QName("
> >> http://cxf.apache.org/",
> >>>> "HelloWS");
> >>>>> -
> >>>>> -    @BeforeClass
> >>>>> -    public static void startservers() throws Exception {
> >>>>> -        //assertTrue("server did not launch correctly",
> >>>> launchServer(Server.class, true));
> >>>>> -    }
> >>>>> -    @Test
> >>>>> -    public void testSchemaValidation() throws Exception {
> >>>>> -        HelloWS port = createService();
> >>>>> -        Hello request = new Hello();
> >>>>> -        request.setArg0("value");
> >>>>> -        URL wsdl =
> >>>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> >>>>> -        File attachment = new File(wsdl.getFile());
> >>>>> -        request.setFile(new DataHandler(new
> >>>> FileDataSource(attachment)));
> >>>>> -        HelloResponse response = port.hello(request);
> >>>>> -        assertEquals("Hello CXF", response.getReturn());
> >>>>> -    }
> >>>>> -
> >>>>> -    private HelloWS createService() throws Exception {
> >>>>> -        URL wsdl =
> >>>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> >>>>> -        assertNotNull(wsdl);
> >>>>> -
> >>>>> -        HelloWSClient service = new HelloWSClient(wsdl,
> serviceName);
> >>>>> -        assertNotNull(service);
> >>>>> -
> >>>>> -        HelloWS port = service.getHello(new MTOMFeature());
> >>>>> -
> >>>>> -        updateAddressPort(port, PORT);
> >>>>> -
> >>>>> -        return port;
> >>>>> -    }
> >>>>> -}
> >>>>>
> >>>>
> >>>> --
> >>>> Daniel Kulp
> >>>> dkulp@apache.org - http://dankulp.com/blog
> >>>> Talend Community Coder - http://coders.talend.com
> >>>>
> >>>>
> >>
> >> --
> >> Daniel Kulp
> >> dkulp@apache.org - http://dankulp.com/blog
> >> Talend Community Coder - http://coders.talend.com
> >>
> >>
>
> --
> Daniel Kulp
> dkulp@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
>
>

Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Daniel Kulp <dk...@apache.org>.
> On Nov 29, 2014, at 1:44 AM, Jason Pell <ja...@pellcorp.com> wrote:
> 
> If the same SEI is used for both service endpoint and client. The use of IN
> would result in request being validated on server and response on client.

Correct.   

As a point of note: from a performance standpoint, this is the best way to set things up if you want both messages validated at some point and have some level of control both the client and the server.  Validating messages during the reading is much easier and quicker.  During the out phases, validation is a bit trickier, particularly with the way CXF streams messages.   For outgoing messages, if you stream while validating, the validation exception would result in a  partial message being written out on the wire which would result in strange stack traces and such in the logs or strange exceptions on the other side.   The alternative is to buffer the full message during validation and only send if validation succeeds.   That has even larger performance (and memory) implications. 


> This is two different jaxb structures. In my theoretical case the service
> designer only wants to validate the request because the service response
> could be incomplete.

Personally, I think if the service designer is explicitly sending invalid data, that’s a serious problem that needs to be re-thought.  They should get their schema updated to support the partial structures or whatever it is they are sending.   A client could be using a different toolkit (Metro/.NET/etc..) that has it’s own settings and such for schema validation and might have other problems with it.

> In the current situation jaxws client would throw schema violation for the
> response even though service designer did not ever envision validation the
> response.
> 
> This is where I struggle to see why that is acceptable.

I’m struggling to see why sending invalid data is acceptable.  :-)   There is a point to having well defined contracts like WSDL’s that have schemas.  

Dan




> Of course we can now just turn off validation on client so not really too
> much of an issue.
> On 29/11/2014 3:18 PM, "Daniel Kulp" <dk...@apache.org> wrote:
> 
>> 
>>> On Nov 28, 2014, at 10:11 PM, Jason Pell <jp...@apache.org> wrote:
>>> 
>>> Its only reversing what's coming from the model. If you define IN in the
>>> jaxws properties on the client it will continue to validate IN on the
>>> client as before.
>>> 
>>> If I have IN defined for a operation using an annotation the old code
>> would
>>> actually validate the response coming back to the client.
>> 
>> That’s exactly what IN is supposed to mean.
>> 
>>> This does seem
>>> counter intuitive especially as IN might have been specified because the
>>> response may be incomplete and so can't be validated.
>> 
>> It would be way more counter intuitive to me for IN to apply to messages
>> that are going OUT.    That’s completely back wards.
>> 
>> 
>>> An IN for service is the OUT for client.
>>> 
>>> The previous code was just plain wrong for client side - my code by the
>> way
>>> :-)
>> 
>> Why do you think it’s wrong?
>> 
>> Basically, we have services that specify validation for IN as that is the
>> only direction that we don’t control and we need to validate that.  For
>> messages that we produce (out on client, out on server), we know the
>> messages are valid as we populate the data correctly.   However, we
>> need/want to validate any incoming data to make sure that is correct.  That
>> is exactly what IN is supposed to mean.  Validate any data coming IN.  By
>> putting the annotation on the SEI specified with IN, we would get what I
>> would regard as the correct behavior.  Validation of the stuff we cannot
>> control and no validation for the stuff we already know is correct.
>> 
>> 
>>> This particular piece is only a few lines in ServiceUtils so I am happy
>> to
>>> remove it if you are still -1
>> 
>> That part, yes.  It’s wrong.
>> 
>> Dan
>> 
>> 
>>> The alternative is I will add a property to enable it but only if the
>>> property is used.
>>> 
>>> Would that be OK?
>>> On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:
>>> 
>>>> 
>>>> I’m -1 on the part of this that changes the IN to an OUT on the client
>>>> side.   The IN and OUT are specifically named that way as they apply to
>> the
>>>> messages that come IN to the client or IN to the server.   The “IN”
>>>> validation should definitely not be applying to the messages going OUT.
>>>> Plus, that would be a huge behavioral change that would break many
>> peoples
>>>> existing applications.
>>>> 
>>>> Dan
>>>> 
>>>> 
>>>> 
>>>> 
>>>>> On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
>>>>> 
>>>>> Repository: cxf
>>>>> Updated Branches:
>>>>> refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
>>>>> 
>>>>> 
>>>>> CXF-6118 support overriding schema validation at jaxws endpoint and
>>>> client level and applying the correct validation direction at client
>> level
>>>>> 
>>>>> 
>>>>> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
>>>>> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
>>>>> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
>>>>> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
>>>>> 
>>>>> Branch: refs/heads/2.7.x-fixes
>>>>> Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
>>>>> Parents: e172a3e
>>>>> Author: Jason Pell <jp...@apache.org>
>>>>> Authored: Thu Nov 27 16:54:01 2014 +1100
>>>>> Committer: Jason Pell <jp...@apache.org>
>>>>> Committed: Fri Nov 28 15:52:36 2014 +1100
>>>>> 
>>>>> ----------------------------------------------------------------------
>>>>> .../validation/SchemaValidationFeature.java     |   2 +-
>>>>> .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
>>>>> .../AbstractInDatabindingInterceptor.java       |  23 +-
>>>>> .../AbstractOutDatabindingInterceptor.java      |  22 +-
>>>>> .../java/org/apache/cxf/message/Message.java    |   9 +
>>>>> .../soap/interceptor/RPCInInterceptor.java      |   2 +-
>>>>> .../factory/AnnotationsFactoryBeanListener.java |   9 +-
>>>>> .../JavaFirstSchemaValidationTest.java          | 256
>> ++++++++++++++-----
>>>>> .../jaxws/schemavalidation/PersonService.java   |  13 +-
>>>>> .../PersonServiceAnnotated.java                 |  13 +-
>>>>> .../PersonServiceAnnotatedImpl.java             |  15 +-
>>>>> .../schemavalidation/PersonServiceImpl.java     |  12 +-
>>>>> .../MTOMProviderSchemaValidationTest.bak        |  69 -----
>>>>> 13 files changed, 342 insertions(+), 201 deletions(-)
>>>>> ----------------------------------------------------------------------
>>>>> 
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>> 
>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>>> index 5eda79c..c314eaf 100644
>>>>> ---
>>>> 
>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>>> +++
>>>> 
>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>>> @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
>>>> AbstractFeature {
>>>>>       for (BindingOperationInfo bop :
>>>> endpoint.getEndpointInfo().getBinding().getOperations()) {
>>>>>           SchemaValidationType type =
>>>> provider.getSchemaValidationType(bop.getOperationInfo());
>>>>>           if (type != null) {
>>>>> -
>>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>> type);
>>>>> +
>>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> type);
>>>>>           }
>>>>>       }
>>>>>   }
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>>> index 85d77d0..28c7ba2 100644
>>>>> --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>>> +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>>> @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
>>>>> import javax.xml.namespace.QName;
>>>>> 
>>>>> import
>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>>>> +import org.apache.cxf.endpoint.Endpoint;
>>>>> +import org.apache.cxf.message.Exchange;
>>>>> import org.apache.cxf.message.Message;
>>>>> +import org.apache.cxf.message.MessageUtils;
>>>>> +import org.apache.cxf.service.model.AbstractPropertiesHolder;
>>>>> +import org.apache.cxf.service.model.BindingOperationInfo;
>>>>> +import org.apache.cxf.service.model.EndpointInfo;
>>>>> +import org.apache.cxf.service.model.OperationInfo;
>>>>> 
>>>>> public final class ServiceUtils {
>>>>> -
>>>>>   private ServiceUtils() {
>>>>>   }
>>>>> 
>>>>> @@ -42,24 +48,94 @@ public final class ServiceUtils {
>>>>>    * @param type
>>>>>    */
>>>>>   public static boolean isSchemaValidationEnabled(SchemaValidationType
>>>> type, Message message) {
>>>>> -        SchemaValidationType messageType =
>>>> getSchemaValidationType(message);
>>>>> +        SchemaValidationType validationType =
>>>> getSchemaValidationType(message);
>>>>> 
>>>>> -        return messageType.equals(type)
>>>>> +        return validationType.equals(type)
>>>>>           || ((SchemaValidationType.IN.equals(type) ||
>>>> SchemaValidationType.OUT.equals(type))
>>>>> -                && SchemaValidationType.BOTH.equals(messageType));
>>>>> +                && SchemaValidationType.BOTH.equals(validationType));
>>>>>   }
>>>>> -
>>>>> +
>>>>>   /**
>>>>> -     * Determines the appropriate SchemaValidationType to return based
>>>> on either
>>>>> -     * a Boolean (for backwards compatibility) or the selected Schema
>>>> Validation Type.
>>>>> -     *
>>>>> -     * Package private as the isSchemaValidationEnabled method should
>>>> be used instead.  Only
>>>>> -     * visible for easier testing
>>>>> +     * A convenience method to check for schema validation config in
>>>> the message context, and then in the service model.
>>>>> +     * Does not modify the Message context (other than what is done in
>>>> the getContextualProperty itself)
>>>>>    *
>>>>>    * @param message
>>>>> +     * @param type
>>>>>    */
>>>>> -    static SchemaValidationType getSchemaValidationType(Message
>>>> message) {
>>>>> +    public static SchemaValidationType getSchemaValidationType(Message
>>>> message) {
>>>>> +        SchemaValidationType validationType =
>>>> getOverrideSchemaValidationType(message);
>>>>> +        if (validationType == null) {
>>>>> +            validationType =
>> getSchemaValidationTypeFromModel(message);
>>>>> +        }
>>>>> +
>>>>> +        if (validationType == null) {
>>>>> +            validationType = SchemaValidationType.NONE;
>>>>> +        }
>>>>> +
>>>>> +        return validationType;
>>>>> +    }
>>>>> +
>>>>> +    private static SchemaValidationType
>>>> getOverrideSchemaValidationType(Message message) {
>>>>>       Object obj =
>>>> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>>>> +        if (obj != null) {
>>>>> +            // this method will transform the legacy enabled as well
>>>>> +            return getSchemaValidationType(obj);
>>>>> +        } else {
>>>>> +            return null;
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    private static SchemaValidationType
>>>> getSchemaValidationTypeFromModel(Message message) {
>>>>> +        boolean isRequestor = MessageUtils.isRequestor(message);
>>>>> +        Exchange exchange = message.getExchange();
>>>>> +
>>>>> +        if (exchange != null) {
>>>>> +            BindingOperationInfo boi =
>>>> exchange.getBindingOperationInfo();
>>>>> +            Endpoint endpoint = exchange.getEndpoint();
>>>>> +
>>>>> +            if (boi != null && endpoint != null) {
>>>>> +                SchemaValidationType validationType = null;
>>>>> +                OperationInfo opInfo = boi.getOperationInfo();
>>>>> +                EndpointInfo ep = endpoint.getEndpointInfo();
>>>>> +
>>>>> +                if (validationType == null && opInfo != null) {
>>>>> +                    validationType =
>>>> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
>>>>> +
>>>>> +                    if (validationType == null && ep != null) {
>>>>> +                        validationType =
>>>> getSchemaValidationTypeFromModel(message, ep, isRequestor);
>>>>> +                    }
>>>>> +                }
>>>>> +
>>>>> +                return validationType;
>>>>> +            }
>>>>> +        }
>>>>> +
>>>>> +        // else
>>>>> +        return null;
>>>>> +    }
>>>>> +
>>>>> +    private static SchemaValidationType
>>>> getSchemaValidationTypeFromModel(
>>>>> +            Message message, AbstractPropertiesHolder properties,
>>>> boolean isRequestor) {
>>>>> +        Object obj =
>>>> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
>>>>> +        if (obj != null) {
>>>>> +            SchemaValidationType validationType =
>>>> getSchemaValidationType(obj);
>>>>> +
>>>>> +            // Reverse the direction of any IN / OUT for requestor
>>>> (client)
>>>>> +            if (isRequestor) {
>>>>> +                if (SchemaValidationType.IN.equals(validationType)) {
>>>>> +                    return SchemaValidationType.OUT;
>>>>> +                } else if
>>>> (SchemaValidationType.OUT.equals(validationType)) {
>>>>> +                    return SchemaValidationType.IN;
>>>>> +                }
>>>>> +            }
>>>>> +
>>>>> +            return validationType;
>>>>> +        } else {
>>>>> +            return null;
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    public static SchemaValidationType getSchemaValidationType(Object
>>>> obj) {
>>>>>       if (obj instanceof SchemaValidationType) {
>>>>>           return (SchemaValidationType)obj;
>>>>>       } else if (obj != null) {
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>> 
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>>> index c47417a..ec8cf71 100644
>>>>> ---
>>>> 
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>>> +++
>>>> 
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>>> @@ -125,24 +125,9 @@ public abstract class
>>>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>>>>>       }
>>>>>   }
>>>>> 
>>>>> -    /**
>>>>> -     * Where an operation level validation type has been set, copy it
>>>> to the message, so it can be interrogated
>>>>> -     * by all downstream interceptors.  It is expected that sub
>> classes
>>>> will call setDataReaderValidation subsequent
>>>>> -     * to this to ensure the DataReader schema reference is updated as
>>>> appropriate.
>>>>> -     *
>>>>> -     * @param bop
>>>>> -     * @param message
>>>>> -     * @param reader
>>>>> -     * @see #setDataReaderValidation(Service, Message, DataReader)
>>>>> -     */
>>>>> -    protected void setOperationSchemaValidation(OperationInfo opInfo,
>>>> Message message) {
>>>>> -        if (opInfo != null) {
>>>>> -            SchemaValidationType validationType =
>>>>> -                (SchemaValidationType)
>>>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>>>> -            if (validationType != null) {
>>>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>>>> validationType);
>>>>> -            }
>>>>> -        }
>>>>> +    protected void setOperationSchemaValidation(Message message) {
>>>>> +        SchemaValidationType validationType =
>>>> ServiceUtils.getSchemaValidationType(message);
>>>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> validationType);
>>>>>   }
>>>>> 
>>>>>   protected DepthXMLStreamReader getXMLStreamReader(Message message) {
>>>>> @@ -247,7 +232,7 @@ public abstract class
>>>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>>>>>       }
>>>>> 
>>>>>       // configure endpoint and operation level schema validation
>>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>>>> message);
>>>>> +        setOperationSchemaValidation(message);
>>>>> 
>>>>>       QName serviceQName = si.getName();
>>>>>       message.put(Message.WSDL_SERVICE, serviceQName);
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>> 
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>>> index db3ba6c..52d1cb1 100644
>>>>> ---
>>>> 
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>>> +++
>>>> 
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>>> @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
>>>>> import org.apache.cxf.service.model.BindingInfo;
>>>>> import org.apache.cxf.service.model.BindingOperationInfo;
>>>>> import org.apache.cxf.service.model.MessagePartInfo;
>>>>> -import org.apache.cxf.service.model.OperationInfo;
>>>>> import org.apache.cxf.staxutils.CachingXmlEventWriter;
>>>>> import org.apache.cxf.staxutils.StaxUtils;
>>>>> import org.apache.cxf.wsdl.EndpointReferenceUtils;
>>>>> @@ -85,7 +84,7 @@ public abstract class
>>>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>>>>>       CachingXmlEventWriter cache = null;
>>>>> 
>>>>>       // configure endpoint and operation level schema validation
>>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>>>> message);
>>>>> +        setOperationSchemaValidation(message);
>>>>> 
>>>>>       // need to cache the events in case validation fails or
>>>> buffering is enabled
>>>>>       if (shouldBuffer(message)) {
>>>>> @@ -159,22 +158,9 @@ public abstract class
>>>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>>>>>       }
>>>>>   }
>>>>> 
>>>>> -    /**
>>>>> -     * Where an operation level validation type has been set, copy it
>>>> to the message, so it can be interrogated
>>>>> -     * by all downstream interceptors
>>>>> -     *
>>>>> -     * @param bop
>>>>> -     * @param message
>>>>> -     * @param reader
>>>>> -     */
>>>>> -    private void setOperationSchemaValidation(OperationInfo opInfo,
>>>> Message message) {
>>>>> -        if (opInfo != null) {
>>>>> -            SchemaValidationType validationType =
>>>>> -                (SchemaValidationType)
>>>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>>>> -            if (validationType != null) {
>>>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>>>> validationType);
>>>>> -            }
>>>>> -        }
>>>>> +    protected void setOperationSchemaValidation(Message message) {
>>>>> +        SchemaValidationType validationType =
>>>> ServiceUtils.getSchemaValidationType(message);
>>>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> validationType);
>>>>>   }
>>>>> 
>>>>>   protected boolean shouldValidate(Message m) {
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
>>>> b/api/src/main/java/org/apache/cxf/message/Message.java
>>>>> index 35e94af..5854a18 100644
>>>>> --- a/api/src/main/java/org/apache/cxf/message/Message.java
>>>>> +++ b/api/src/main/java/org/apache/cxf/message/Message.java
>>>>> @@ -105,7 +105,16 @@ public interface Message extends StringMap {
>>>>>    */
>>>>>   String MTOM_ENABLED = "mtom-enabled";
>>>>>   String MTOM_THRESHOLD = "mtom-threshold";
>>>>> +
>>>>> +    /**
>>>>> +     * Runtime schema validation property
>>>>> +     */
>>>>>   String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
>>>>> +
>>>>> +    /**
>>>>> +     * The default values for schema validation will be set in the
>>>> service model using this property
>>>>> +     */
>>>>> +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
>>>>> 
>>>>>   /**
>>>>>    * Boolean property specifying if the Java stack trace is returned
>>>> as a
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>> 
>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>>> index fafd0a9..d49f090 100644
>>>>> ---
>>>> 
>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>>> +++
>>>> 
>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>>> @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
>>>> AbstractInDatabindingInterceptor {
>>>>>       message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
>>>>> 
>>>>>       // configure endpoint and operation level schema validation
>>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>>>> message);
>>>>> +        setOperationSchemaValidation(message);
>>>>>   }
>>>>> }
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>> 
>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>>> index 7100f2c..9a7cbc8 100644
>>>>> ---
>>>> 
>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>>> +++
>>>> 
>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>>> @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
>>>> implements FactoryBeanListener {
>>>>>           // if someone has gone to the effort of specifying
>>>> enabled=false, then we need to
>>>>>           // handle that, otherwise we use the new
>>>> SchemaValidationType type only
>>>>>           if (!annotation.enabled()) {
>>>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>>>> SchemaValidationType.NONE);
>>>>> +
>>>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>>>> SchemaValidationType.NONE);
>>>>>           } else {
>>>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>>>> annotation.type());
>>>>> +
>>>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>>>> annotation.type());
>>>>>           }
>>>>>       }
>>>>>   }
>>>>> @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
>>>> implements FactoryBeanListener {
>>>>>   }
>>>>> 
>>>>>   private void addSchemaValidationSupport(OperationInfo inf,
>>>> SchemaValidation annotation) {
>>>>> -        // Notice no support for deprecated enabled property here!
>>>>> -        // TODO - should we check for the use of this property and at
>>>> least log the fact we are
>>>>> -        // ignoring it
>>>>>       if (annotation != null) {
>>>>> -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>>>> annotation.type());
>>>>> +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
>>>> annotation.type());
>>>>>       }
>>>>>   }
>>>>> 
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>>> index 888e5a8..9f08839 100644
>>>>> ---
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>>> +++
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>>> @@ -20,12 +20,15 @@
>>>>> package org.apache.cxf.systest.jaxws.schemavalidation;
>>>>> 
>>>>> import java.io.IOException;
>>>>> +import java.io.PrintWriter;
>>>>> +import java.io.StringWriter;
>>>>> import java.util.ArrayList;
>>>>> import java.util.Arrays;
>>>>> import java.util.HashMap;
>>>>> import java.util.List;
>>>>> import java.util.Map;
>>>>> 
>>>>> +import javax.xml.ws.WebServiceException;
>>>>> import javax.xml.ws.soap.SOAPFaultException;
>>>>> 
>>>>> import
>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>>>> @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
>>>>> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
>>>>> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
>>>>> import org.apache.cxf.message.Message;
>>>>> -import org.apache.cxf.service.model.BindingOperationInfo;
>>>>> import org.apache.cxf.testutil.common.TestUtil;
>>>>> +import org.apache.cxf.transport.http.HTTPConduit;
>>>>> +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
>>>>> import org.junit.AfterClass;
>>>>> import org.junit.Assert;
>>>>> import org.junit.BeforeClass;
>>>>> import org.junit.Test;
>>>>> 
>>>>> -/**
>>>>> - * TODO - test where the default is NONE at the service level test
>>>> where the default is IN or OUT, and then
>>>>> - * override at operation levels
>>>>> - */
>>>>> public class JavaFirstSchemaValidationTest extends Assert {
>>>>> -    static final String PORT =
>>>> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
>>>>> +    static final String PORT =
>>>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>>>>> +    static final String PORT_UNUSED =
>>>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>>>>> 
>>>>>   private static List<Server> serverList = new ArrayList<Server>();
>>>>>   private static PersonServiceAnnotated annotatedClient;
>>>>> +    private static PersonServiceAnnotated annotatedValidatingClient;
>>>>>   private static PersonService client;
>>>>>   private static PersonServiceRPC rpcClient;
>>>>> +
>>>>> +    private static PersonService disconnectedClient;
>>>>> 
>>>>>   @BeforeClass
>>>>>   public static void startServers() throws Exception {
>>>>> @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends
>>>> Assert {
>>>>> 
>>>>>       createServer(PersonServiceRPC.class, new PersonServiceRPCImpl(),
>>>> feature, new LoggingFeature());
>>>>> 
>>>>> -        annotatedClient = createClient(PersonServiceAnnotated.class);
>>>>> -        client = createClient(PersonService.class);
>>>>> -        rpcClient = createClient(PersonServiceRPC.class);
>>>>> +        annotatedClient = createClient(PORT,
>>>> PersonServiceAnnotated.class, SchemaValidationType.NONE);
>>>>> +        annotatedValidatingClient = createClient(PORT,
>>>> PersonServiceAnnotated.class, null);
>>>>> +        client = createClient(PORT, PersonService.class,
>>>> SchemaValidationType.NONE);
>>>>> +        disconnectedClient = createClient(PORT_UNUSED,
>>>> PersonService.class, SchemaValidationType.OUT);
>>>>> +        rpcClient = createClient(PORT, PersonServiceRPC.class,
>>>> SchemaValidationType.NONE);
>>>>>   }
>>>>> 
>>>>>   @AfterClass
>>>>> @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends
>>>> Assert {
>>>>>       }
>>>>>   }
>>>>> 
>>>>> -    static String getAddress(Class<?> sei) {
>>>>> -        return "http://localhost:" + PORT + "/" +
>> sei.getSimpleName();
>>>>> +    static String getAddress(String port, Class<?> sei) {
>>>>> +        return "http://localhost:" + port + "/" +
>> sei.getSimpleName();
>>>>>   }
>>>>> -
>>>>> 
>>>>>   @Test
>>>>>   public void testRPCLit() throws Exception {
>>>>> @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest extends
>>>> Assert {
>>>>>       try {
>>>>>           person.setFirstName(null);
>>>>>           rpcClient.saveValidateOut(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>>           assertTrue(sfe.getMessage().contains("Marshalling Error"));
>>>>>           assertTrue(sfe.getMessage().contains("lastName"));
>>>>>       }
>>>>> @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest
>> extends
>>>> Assert {
>>>>> 
>>>>>       try {
>>>>>           annotatedClient.saveInheritEndpoint(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>>> Error"));
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>>       }
>>>>> 
>>>>>       try {
>>>>>           person.setFirstName(""); // empty string is valid
>>>>>           annotatedClient.saveInheritEndpoint(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>>> Error"));
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>>       }
>>>>> 
>>>>>       person.setLastName(""); // empty string is valid
>>>>>       annotatedClient.saveInheritEndpoint(person);
>>>>>   }
>>>>> -
>>>>> +
>>>>>   @Test
>>>>>   public void testSaveValidateInAnnotated() {
>>>>>       Person person = new Person();
>>>>> 
>>>>>       try {
>>>>>           annotatedClient.saveValidateIn(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>>> Error"));
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>>       }
>>>>> 
>>>>>       try {
>>>>>           person.setFirstName(""); // empty string is valid
>>>>>           annotatedClient.saveValidateIn(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>>> Error"));
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>>       }
>>>>> 
>>>>>       person.setLastName(""); // empty string is valid
>>>>> @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
>>>> extends Assert {
>>>>>       annotatedClient.saveNoValidation(person);
>>>>>   }
>>>>> 
>>>>> -    // no validation is required for incoming
>>>>>   @Test
>>>>> -    public void testSaveValidationOutAnnotated() {
>>>>> +    public void
>>>> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
>>>>>       Person person = new Person();
>>>>> 
>>>>> -        annotatedClient.saveValidateOut(person);
>>>>> +        try {
>>>>> +            annotatedClient.saveValidateOut(person);
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            // verify its server side and a schema validation
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>>> +            // it's still a server side fault, because server side
>>>> validation coming in failed
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>> +
>>>>> +        person.setFirstName(""); // empty string is valid
>>>>> +        try {
>>>>> +            annotatedClient.saveValidateOut(person);
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            // verify its server side and a schema validation
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>>> +            // it's still a server side fault, because server side
>>>> validation coming in failed
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>> 
>>>>> +        person.setLastName(""); // empty string is valid
>>>>> +        annotatedClient.saveValidateIn(person);
>>>>> +    }
>>>>> +
>>>>> +    // this will still all be server side, as the OUT validation is
>>>> turned into an IN validation for
>>>>> +    // the client, but by then the server has already thrown the
>>>> exception for the OUT
>>>>> +    @Test
>>>>> +    public void
>>>> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
>>>>> +        Person person = new Person();
>>>>> +
>>>>> +        try {
>>>>> +            annotatedValidatingClient.saveValidateIn(person);
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>> 
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>> +
>>>>>       person.setFirstName(""); // empty string is valid
>>>>> -        annotatedClient.saveValidateOut(person);
>>>>> +        try {
>>>>> +            annotatedValidatingClient.saveValidateIn(person);
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>> 
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>> 
>>>>>       person.setLastName(""); // empty string is valid
>>>>> -        annotatedClient.saveValidateOut(person);
>>>>> +        annotatedValidatingClient.saveValidateIn(person);
>>>>> +    }
>>>>> +
>>>>> +    @Test
>>>>> +    public void
>>>> testSaveValidationInAnnotatedWithClientValidationEnabled() {
>>>>> +        Person person = new Person();
>>>>> +
>>>>> +        try {
>>>>> +            person.setFirstName("InvalidResponse");
>>>>> +            person.setLastName("WhoCares");
>>>>> +            annotatedValidatingClient.saveValidateOut(person);
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>> 
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>>   }
>>>>> 
>>>>> -    // so this is the default, we are inheriting from the service
>> level
>>>> SchemaValidation annotation
>>>>> -    // which is set to BOTH
>>>>>   @Test
>>>>>   public void testEndpointSchemaValidationProvider() {
>>>>>       Person person = new Person();
>>>>> 
>>>>>       try {
>>>>>           client.saveInheritEndpoint(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>>> Error"));
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>>       }
>>>>> -
>>>>> +
>>>>>       try {
>>>>>           person.setFirstName(""); // empty string is valid
>>>>>           client.saveInheritEndpoint(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>>> Error"));
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>>       }
>>>>> 
>>>>>       person.setLastName(""); // empty string is valid
>>>>> @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest
>> extends
>>>> Assert {
>>>>> 
>>>>>       try {
>>>>>           client.saveValidateIn(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>>> Error"));
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>>       }
>>>>> 
>>>>>       try {
>>>>>           person.setFirstName(""); // empty string is valid
>>>>>           client.saveValidateIn(person);
>>>>> +            fail("Expected exception");
>>>>>       } catch (SOAPFaultException sfe) {
>>>>> -            // verify its server side and a schema validation
>>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>>> Error"));
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>>       }
>>>>> 
>>>>>       person.setLastName(""); // empty string is valid
>>>>>       client.saveValidateIn(person);
>>>>>   }
>>>>> 
>>>>> -    // no validation at all is required
>>>>>   @Test
>>>>>   public void testSaveNoValidationProvider() {
>>>>>       Person person = new Person();
>>>>> @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest
>> extends
>>>> Assert {
>>>>>       client.saveNoValidation(person);
>>>>>   }
>>>>> 
>>>>> -    // no validation is required for incoming
>>>>>   @Test
>>>>> -    public void testSaveValidationOutProvider() {
>>>>> +    public void testSaveValidationOutProviderClientOnly() {
>>>>>       Person person = new Person();
>>>>> 
>>>>> -        client.saveValidateOut(person);
>>>>> +        try {
>>>>> +            disconnectedClient.saveValidateOut(person);
>>>>> +            fail("Expected exception");
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            // verify its client side outgoing
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>> 
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>> +
>>>>> +        person.setFirstName(""); // empty string is valid
>>>>> +        try {
>>>>> +            disconnectedClient.saveValidateOut(person);
>>>>> +            fail("Expected exception");
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            // verify its client side outgoing
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>> 
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>> +
>>>>> +        person.setLastName(""); // empty string is valid
>>>>> +
>>>>> +        // this confirms that we passed client validation as we then
>>>> got the connectivity error
>>>>> +        try {
>>>>> +            disconnectedClient.saveValidateOut(person);
>>>>> +            fail("Expected exception");
>>>>> +        } catch (WebServiceException e) {
>>>>> +            assertTrue(e.getMessage().contains("Could not send
>>>> Message"));
>>>>> +        }
>>>>> +    }
>>>>> 
>>>>> +
>>>>> +    @Test
>>>>> +    public void testSaveValidationOutProvider() {
>>>>> +        Person person = new Person();
>>>>> +
>>>>> +        try {
>>>>> +            client.saveValidateOut(person);
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            // verify its server side outgoing
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>> +
>>>>>       person.setFirstName(""); // empty string is valid
>>>>> -        client.saveValidateOut(person);
>>>>> +        try {
>>>>> +            client.saveValidateOut(person);
>>>>> +        } catch (SOAPFaultException sfe) {
>>>>> +            // verify its server side outgoing
>>>>> +            String stackTrace = getStackTrace(sfe);
>>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>>> +
>>>> 
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>> +        }
>>>>> 
>>>>>       person.setLastName(""); // empty string is valid
>>>>>       client.saveValidateOut(person);
>>>>>   }
>>>>> 
>>>>> -    private static <T> T createClient(Class<T> serviceClass) {
>>>>> +    private static <T> T createClient(String port, Class<T>
>>>> serviceClass, SchemaValidationType type) {
>>>>>       JaxWsProxyFactoryBean clientFactory = new
>>>> JaxWsProxyFactoryBean();
>>>>>       clientFactory.setServiceClass(serviceClass);
>>>>> -
>>>>> -        // ensure all client schema validation is disabled
>>>>> -        Map<String, Object> properties = new HashMap<String,
>> Object>();
>>>>> -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
>>>> SchemaValidationType.NONE);
>>>>> -        clientFactory.setProperties(properties);
>>>>> -
>>>>> -        clientFactory.setAddress(getAddress(serviceClass));
>>>>> -
>>>>> +
>>>>> +
>>>>> +        clientFactory.setAddress(getAddress(port, serviceClass));
>>>>> +
>>>>> +
>>>>>       @SuppressWarnings("unchecked")
>>>>>       T newClient = (T)clientFactory.create();
>>>>> 
>>>>> -        Client clientProxy = ClientProxy.getClient(newClient);
>>>>> -
>>>>> -        // ensure all client schema validation is disabled
>>>>> -        for (BindingOperationInfo bop :
>>>> clientProxy.getEndpoint().getEndpointInfo().getBinding()
>>>>> -            .getOperations()) {
>>>>> -
>>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>>>> SchemaValidationType.NONE);
>>>>> +        Client proxy = ClientProxy.getClient(newClient);
>>>>> +
>>>>> +        if (type != null) {
>>>>> +
>>>> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED, type);
>>>>>       }
>>>>> -
>>>>> +
>>>>> +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
>>>>> +        // give me longer debug times
>>>>> +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
>>>>> +        clientPolicy.setConnectionTimeout(1000000);
>>>>> +        clientPolicy.setReceiveTimeout(1000000);
>>>>> +        conduit.setClient(clientPolicy);
>>>>> +
>>>>>       return newClient;
>>>>>   }
>>>>> 
>>>>> @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest
>> extends
>>>> Assert {
>>>>>       if (features != null) {
>>>>>           svrFactory.getFeatures().addAll(Arrays.asList(features));
>>>>>       }
>>>>> -        svrFactory.setAddress(getAddress(serviceInterface));
>>>>> +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
>>>>>       svrFactory.setServiceBean(serviceImpl);
>>>>>       Server server = svrFactory.create();
>>>>>       serverList.add(server);
>>>>>       return server;
>>>>>   }
>>>>> +
>>>>> +    private String getStackTrace(Exception e) {
>>>>> +        StringWriter sWriter = new StringWriter();
>>>>> +        PrintWriter writer = new PrintWriter(sWriter, true);
>>>>> +        e.printStackTrace(writer);
>>>>> +        return sWriter.toString();
>>>>> +    }
>>>>> }
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>>> index e3ee10c..d594e4e 100644
>>>>> ---
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>>> +++
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>>> @@ -21,6 +21,7 @@ package
>> org.apache.cxf.systest.jaxws.schemavalidation;
>>>>> 
>>>>> import javax.jws.WebMethod;
>>>>> import javax.jws.WebParam;
>>>>> +import javax.jws.WebResult;
>>>>> import javax.jws.WebService;
>>>>> 
>>>>> import org.apache.cxf.annotations.SchemaValidation;
>>>>> @@ -30,14 +31,18 @@ import
>>>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>>>> @SchemaValidation(type = SchemaValidationType.BOTH)
>>>>> public interface PersonService {
>>>>>   @WebMethod(operationName = "saveInheritEndpoint")
>>>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>>>> +    @WebResult(name = "Person")
>>>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
>> data);
>>>>> 
>>>>>   @WebMethod(operationName = "saveNoValidation")
>>>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
>>>>> +    @WebResult(name = "Person")
>>>>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
>>>>> 
>>>>>   @WebMethod(operationName = "saveValidateIn")
>>>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
>>>>> +    @WebResult(name = "Person")
>>>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>>>>> 
>>>>>   @WebMethod(operationName = "saveValidateOut")
>>>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
>>>>> +    @WebResult(name = "Person")
>>>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>>>>> }
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>>> index 3e06576..a760f27 100644
>>>>> ---
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>>> +++
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>>> @@ -21,6 +21,7 @@ package
>> org.apache.cxf.systest.jaxws.schemavalidation;
>>>>> 
>>>>> import javax.jws.WebMethod;
>>>>> import javax.jws.WebParam;
>>>>> +import javax.jws.WebResult;
>>>>> import javax.jws.WebService;
>>>>> 
>>>>> import org.apache.cxf.annotations.SchemaValidation;
>>>>> @@ -30,17 +31,21 @@ import
>>>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>>>> @SchemaValidation(type = SchemaValidationType.BOTH)
>>>>> public interface PersonServiceAnnotated {
>>>>>   @WebMethod(operationName = "saveInheritEndpoint")
>>>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>>>> +    @WebResult(name = "Person")
>>>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
>> data);
>>>>> 
>>>>>   @SchemaValidation(type = SchemaValidationType.NONE)
>>>>>   @WebMethod(operationName = "saveNoValidation")
>>>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
>>>>> +    @WebResult(name = "Person")
>>>>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
>>>>> 
>>>>>   @SchemaValidation(type = SchemaValidationType.IN)
>>>>>   @WebMethod(operationName = "saveValidateIn")
>>>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
>>>>> +    @WebResult(name = "Person")
>>>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>>>>> 
>>>>>   @SchemaValidation(type = SchemaValidationType.OUT)
>>>>>   @WebMethod(operationName = "saveValidateOut")
>>>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
>>>>> +    @WebResult(name = "Person")
>>>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>>>>> }
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>>> index c7b8038..78973c9 100644
>>>>> ---
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>>> +++
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>>> @@ -26,18 +26,25 @@ import javax.jws.WebService;
>>>>>   targetNamespace = "
>>>> http://org.apache.cxf/service/PersonServiceAnnotated")
>>>>> public class PersonServiceAnnotatedImpl implements
>>>> PersonServiceAnnotated {
>>>>>   @Override
>>>>> -    public void saveNoValidation(Person data) {
>>>>> +    public Person saveNoValidation(Person data) {
>>>>> +        return data;
>>>>>   }
>>>>> 
>>>>>   @Override
>>>>> -    public void saveInheritEndpoint(Person data) {
>>>>> +    public Person saveInheritEndpoint(Person data) {
>>>>> +        return data;
>>>>>   }
>>>>> 
>>>>>   @Override
>>>>> -    public void saveValidateIn(Person data) {
>>>>> +    public Person saveValidateIn(Person data) {
>>>>> +        if ("InvalidResponse".equals(data.getFirstName())) {
>>>>> +            return new Person();
>>>>> +        }
>>>>> +        return data;
>>>>>   }
>>>>> 
>>>>>   @Override
>>>>> -    public void saveValidateOut(Person data) {
>>>>> +    public Person saveValidateOut(Person data) {
>>>>> +        return data;
>>>>>   }
>>>>> }
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>>> index fe1d656..9edec45 100644
>>>>> ---
>>>> 
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>>> +++
>>>> 
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>>> @@ -26,18 +26,22 @@ import javax.jws.WebService;
>>>>>   targetNamespace = "http://org.apache.cxf/service/PersonService")
>>>>> public class PersonServiceImpl implements PersonService {
>>>>>   @Override
>>>>> -    public void saveNoValidation(Person data) {
>>>>> +    public Person saveNoValidation(Person data) {
>>>>> +        return data;
>>>>>   }
>>>>> 
>>>>>   @Override
>>>>> -    public void saveInheritEndpoint(Person data) {
>>>>> +    public Person saveInheritEndpoint(Person data) {
>>>>> +        return data;
>>>>>   }
>>>>> 
>>>>>   @Override
>>>>> -    public void saveValidateIn(Person data) {
>>>>> +    public Person saveValidateIn(Person data) {
>>>>> +        return data;
>>>>>   }
>>>>> 
>>>>>   @Override
>>>>> -    public void saveValidateOut(Person data) {
>>>>> +    public Person saveValidateOut(Person data) {
>>>>> +        return data;
>>>>>   }
>>>>> }
>>>>> 
>>>>> 
>>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>>>> ----------------------------------------------------------------------
>>>>> diff --git
>>>> 
>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>>> 
>> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>>>> deleted file mode 100644
>>>>> index 18e66ae..0000000
>>>>> ---
>>>> 
>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>>>> +++ /dev/null
>>>>> @@ -1,69 +0,0 @@
>>>>> -/**
>>>>> - * Licensed to the Apache Software Foundation (ASF) under one
>>>>> - * or more contributor license agreements. See the NOTICE file
>>>>> - * distributed with this work for additional information
>>>>> - * regarding copyright ownership. The ASF licenses this file
>>>>> - * to you 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.cxf.systest.mtom_schema_validation;
>>>>> -
>>>>> -import java.io.File;
>>>>> -import java.net.URL;
>>>>> -
>>>>> -import javax.activation.DataHandler;
>>>>> -import javax.activation.FileDataSource;
>>>>> -import javax.xml.namespace.QName;
>>>>> -import javax.xml.ws.soap.MTOMFeature;
>>>>> -
>>>>> -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
>>>>> -
>>>>> -import org.junit.BeforeClass;
>>>>> -import org.junit.Test;
>>>>> -
>>>>> -public final class MTOMProviderSchemaValidationTest extends
>>>> AbstractBusClientServerTestBase {
>>>>> -    public static final String PORT = "9001";
>>>>> -        //Server.PORT;
>>>>> -
>>>>> -    private final QName serviceName = new QName("
>> http://cxf.apache.org/",
>>>> "HelloWS");
>>>>> -
>>>>> -    @BeforeClass
>>>>> -    public static void startservers() throws Exception {
>>>>> -        //assertTrue("server did not launch correctly",
>>>> launchServer(Server.class, true));
>>>>> -    }
>>>>> -    @Test
>>>>> -    public void testSchemaValidation() throws Exception {
>>>>> -        HelloWS port = createService();
>>>>> -        Hello request = new Hello();
>>>>> -        request.setArg0("value");
>>>>> -        URL wsdl =
>>>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>>>>> -        File attachment = new File(wsdl.getFile());
>>>>> -        request.setFile(new DataHandler(new
>>>> FileDataSource(attachment)));
>>>>> -        HelloResponse response = port.hello(request);
>>>>> -        assertEquals("Hello CXF", response.getReturn());
>>>>> -    }
>>>>> -
>>>>> -    private HelloWS createService() throws Exception {
>>>>> -        URL wsdl =
>>>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>>>>> -        assertNotNull(wsdl);
>>>>> -
>>>>> -        HelloWSClient service = new HelloWSClient(wsdl, serviceName);
>>>>> -        assertNotNull(service);
>>>>> -
>>>>> -        HelloWS port = service.getHello(new MTOMFeature());
>>>>> -
>>>>> -        updateAddressPort(port, PORT);
>>>>> -
>>>>> -        return port;
>>>>> -    }
>>>>> -}
>>>>> 
>>>> 
>>>> --
>>>> Daniel Kulp
>>>> dkulp@apache.org - http://dankulp.com/blog
>>>> Talend Community Coder - http://coders.talend.com
>>>> 
>>>> 
>> 
>> --
>> Daniel Kulp
>> dkulp@apache.org - http://dankulp.com/blog
>> Talend Community Coder - http://coders.talend.com
>> 
>> 

-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com


Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Jason Pell <ja...@pellcorp.com>.
If the same SEI is used for both service endpoint and client. The use of IN
would result in request being validated on server and response on client.

This is two different jaxb structures. In my theoretical case the service
designer only wants to validate the request because the service response
could be incomplete.

In the current situation jaxws client would throw schema violation for the
response even though service designer did not ever envision validation the
response.

This is where I struggle to see why that is acceptable.

Of course we can now just turn off validation on client so not really too
much of an issue.
On 29/11/2014 3:18 PM, "Daniel Kulp" <dk...@apache.org> wrote:

>
> > On Nov 28, 2014, at 10:11 PM, Jason Pell <jp...@apache.org> wrote:
> >
> > Its only reversing what's coming from the model. If you define IN in the
> > jaxws properties on the client it will continue to validate IN on the
> > client as before.
> >
> > If I have IN defined for a operation using an annotation the old code
> would
> > actually validate the response coming back to the client.
>
> That’s exactly what IN is supposed to mean.
>
> > This does seem
> > counter intuitive especially as IN might have been specified because the
> > response may be incomplete and so can't be validated.
>
> It would be way more counter intuitive to me for IN to apply to messages
> that are going OUT.    That’s completely back wards.
>
>
> > An IN for service is the OUT for client.
> >
> > The previous code was just plain wrong for client side - my code by the
> way
> > :-)
>
> Why do you think it’s wrong?
>
> Basically, we have services that specify validation for IN as that is the
> only direction that we don’t control and we need to validate that.  For
> messages that we produce (out on client, out on server), we know the
> messages are valid as we populate the data correctly.   However, we
> need/want to validate any incoming data to make sure that is correct.  That
> is exactly what IN is supposed to mean.  Validate any data coming IN.  By
> putting the annotation on the SEI specified with IN, we would get what I
> would regard as the correct behavior.  Validation of the stuff we cannot
> control and no validation for the stuff we already know is correct.
>
>
> > This particular piece is only a few lines in ServiceUtils so I am happy
> to
> > remove it if you are still -1
>
> That part, yes.  It’s wrong.
>
> Dan
>
>
> > The alternative is I will add a property to enable it but only if the
> > property is used.
> >
> > Would that be OK?
> > On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:
> >
> >>
> >> I’m -1 on the part of this that changes the IN to an OUT on the client
> >> side.   The IN and OUT are specifically named that way as they apply to
> the
> >> messages that come IN to the client or IN to the server.   The “IN”
> >> validation should definitely not be applying to the messages going OUT.
> >> Plus, that would be a huge behavioral change that would break many
> peoples
> >> existing applications.
> >>
> >> Dan
> >>
> >>
> >>
> >>
> >>> On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
> >>>
> >>> Repository: cxf
> >>> Updated Branches:
> >>> refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
> >>>
> >>>
> >>> CXF-6118 support overriding schema validation at jaxws endpoint and
> >> client level and applying the correct validation direction at client
> level
> >>>
> >>>
> >>> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
> >>> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
> >>> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
> >>> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
> >>>
> >>> Branch: refs/heads/2.7.x-fixes
> >>> Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
> >>> Parents: e172a3e
> >>> Author: Jason Pell <jp...@apache.org>
> >>> Authored: Thu Nov 27 16:54:01 2014 +1100
> >>> Committer: Jason Pell <jp...@apache.org>
> >>> Committed: Fri Nov 28 15:52:36 2014 +1100
> >>>
> >>> ----------------------------------------------------------------------
> >>> .../validation/SchemaValidationFeature.java     |   2 +-
> >>> .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
> >>> .../AbstractInDatabindingInterceptor.java       |  23 +-
> >>> .../AbstractOutDatabindingInterceptor.java      |  22 +-
> >>> .../java/org/apache/cxf/message/Message.java    |   9 +
> >>> .../soap/interceptor/RPCInInterceptor.java      |   2 +-
> >>> .../factory/AnnotationsFactoryBeanListener.java |   9 +-
> >>> .../JavaFirstSchemaValidationTest.java          | 256
> ++++++++++++++-----
> >>> .../jaxws/schemavalidation/PersonService.java   |  13 +-
> >>> .../PersonServiceAnnotated.java                 |  13 +-
> >>> .../PersonServiceAnnotatedImpl.java             |  15 +-
> >>> .../schemavalidation/PersonServiceImpl.java     |  12 +-
> >>> .../MTOMProviderSchemaValidationTest.bak        |  69 -----
> >>> 13 files changed, 342 insertions(+), 201 deletions(-)
> >>> ----------------------------------------------------------------------
> >>>
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>
> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>> index 5eda79c..c314eaf 100644
> >>> ---
> >>
> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>> +++
> >>
> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>> @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
> >> AbstractFeature {
> >>>        for (BindingOperationInfo bop :
> >> endpoint.getEndpointInfo().getBinding().getOperations()) {
> >>>            SchemaValidationType type =
> >> provider.getSchemaValidationType(bop.getOperationInfo());
> >>>            if (type != null) {
> >>> -
> >> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> type);
> >>> +
> >> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> type);
> >>>            }
> >>>        }
> >>>    }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>> ----------------------------------------------------------------------
> >>> diff --git a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>> index 85d77d0..28c7ba2 100644
> >>> --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>> +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>> @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
> >>> import javax.xml.namespace.QName;
> >>>
> >>> import
> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>> +import org.apache.cxf.endpoint.Endpoint;
> >>> +import org.apache.cxf.message.Exchange;
> >>> import org.apache.cxf.message.Message;
> >>> +import org.apache.cxf.message.MessageUtils;
> >>> +import org.apache.cxf.service.model.AbstractPropertiesHolder;
> >>> +import org.apache.cxf.service.model.BindingOperationInfo;
> >>> +import org.apache.cxf.service.model.EndpointInfo;
> >>> +import org.apache.cxf.service.model.OperationInfo;
> >>>
> >>> public final class ServiceUtils {
> >>> -
> >>>    private ServiceUtils() {
> >>>    }
> >>>
> >>> @@ -42,24 +48,94 @@ public final class ServiceUtils {
> >>>     * @param type
> >>>     */
> >>>    public static boolean isSchemaValidationEnabled(SchemaValidationType
> >> type, Message message) {
> >>> -        SchemaValidationType messageType =
> >> getSchemaValidationType(message);
> >>> +        SchemaValidationType validationType =
> >> getSchemaValidationType(message);
> >>>
> >>> -        return messageType.equals(type)
> >>> +        return validationType.equals(type)
> >>>            || ((SchemaValidationType.IN.equals(type) ||
> >> SchemaValidationType.OUT.equals(type))
> >>> -                && SchemaValidationType.BOTH.equals(messageType));
> >>> +                && SchemaValidationType.BOTH.equals(validationType));
> >>>    }
> >>> -
> >>> +
> >>>    /**
> >>> -     * Determines the appropriate SchemaValidationType to return based
> >> on either
> >>> -     * a Boolean (for backwards compatibility) or the selected Schema
> >> Validation Type.
> >>> -     *
> >>> -     * Package private as the isSchemaValidationEnabled method should
> >> be used instead.  Only
> >>> -     * visible for easier testing
> >>> +     * A convenience method to check for schema validation config in
> >> the message context, and then in the service model.
> >>> +     * Does not modify the Message context (other than what is done in
> >> the getContextualProperty itself)
> >>>     *
> >>>     * @param message
> >>> +     * @param type
> >>>     */
> >>> -    static SchemaValidationType getSchemaValidationType(Message
> >> message) {
> >>> +    public static SchemaValidationType getSchemaValidationType(Message
> >> message) {
> >>> +        SchemaValidationType validationType =
> >> getOverrideSchemaValidationType(message);
> >>> +        if (validationType == null) {
> >>> +            validationType =
> getSchemaValidationTypeFromModel(message);
> >>> +        }
> >>> +
> >>> +        if (validationType == null) {
> >>> +            validationType = SchemaValidationType.NONE;
> >>> +        }
> >>> +
> >>> +        return validationType;
> >>> +    }
> >>> +
> >>> +    private static SchemaValidationType
> >> getOverrideSchemaValidationType(Message message) {
> >>>        Object obj =
> >> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>> +        if (obj != null) {
> >>> +            // this method will transform the legacy enabled as well
> >>> +            return getSchemaValidationType(obj);
> >>> +        } else {
> >>> +            return null;
> >>> +        }
> >>> +    }
> >>> +
> >>> +    private static SchemaValidationType
> >> getSchemaValidationTypeFromModel(Message message) {
> >>> +        boolean isRequestor = MessageUtils.isRequestor(message);
> >>> +        Exchange exchange = message.getExchange();
> >>> +
> >>> +        if (exchange != null) {
> >>> +            BindingOperationInfo boi =
> >> exchange.getBindingOperationInfo();
> >>> +            Endpoint endpoint = exchange.getEndpoint();
> >>> +
> >>> +            if (boi != null && endpoint != null) {
> >>> +                SchemaValidationType validationType = null;
> >>> +                OperationInfo opInfo = boi.getOperationInfo();
> >>> +                EndpointInfo ep = endpoint.getEndpointInfo();
> >>> +
> >>> +                if (validationType == null && opInfo != null) {
> >>> +                    validationType =
> >> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
> >>> +
> >>> +                    if (validationType == null && ep != null) {
> >>> +                        validationType =
> >> getSchemaValidationTypeFromModel(message, ep, isRequestor);
> >>> +                    }
> >>> +                }
> >>> +
> >>> +                return validationType;
> >>> +            }
> >>> +        }
> >>> +
> >>> +        // else
> >>> +        return null;
> >>> +    }
> >>> +
> >>> +    private static SchemaValidationType
> >> getSchemaValidationTypeFromModel(
> >>> +            Message message, AbstractPropertiesHolder properties,
> >> boolean isRequestor) {
> >>> +        Object obj =
> >> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
> >>> +        if (obj != null) {
> >>> +            SchemaValidationType validationType =
> >> getSchemaValidationType(obj);
> >>> +
> >>> +            // Reverse the direction of any IN / OUT for requestor
> >> (client)
> >>> +            if (isRequestor) {
> >>> +                if (SchemaValidationType.IN.equals(validationType)) {
> >>> +                    return SchemaValidationType.OUT;
> >>> +                } else if
> >> (SchemaValidationType.OUT.equals(validationType)) {
> >>> +                    return SchemaValidationType.IN;
> >>> +                }
> >>> +            }
> >>> +
> >>> +            return validationType;
> >>> +        } else {
> >>> +            return null;
> >>> +        }
> >>> +    }
> >>> +
> >>> +    public static SchemaValidationType getSchemaValidationType(Object
> >> obj) {
> >>>        if (obj instanceof SchemaValidationType) {
> >>>            return (SchemaValidationType)obj;
> >>>        } else if (obj != null) {
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>> index c47417a..ec8cf71 100644
> >>> ---
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>> +++
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>> @@ -125,24 +125,9 @@ public abstract class
> >> AbstractInDatabindingInterceptor extends AbstractPhaseInte
> >>>        }
> >>>    }
> >>>
> >>> -    /**
> >>> -     * Where an operation level validation type has been set, copy it
> >> to the message, so it can be interrogated
> >>> -     * by all downstream interceptors.  It is expected that sub
> classes
> >> will call setDataReaderValidation subsequent
> >>> -     * to this to ensure the DataReader schema reference is updated as
> >> appropriate.
> >>> -     *
> >>> -     * @param bop
> >>> -     * @param message
> >>> -     * @param reader
> >>> -     * @see #setDataReaderValidation(Service, Message, DataReader)
> >>> -     */
> >>> -    protected void setOperationSchemaValidation(OperationInfo opInfo,
> >> Message message) {
> >>> -        if (opInfo != null) {
> >>> -            SchemaValidationType validationType =
> >>> -                (SchemaValidationType)
> >> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>> -            if (validationType != null) {
> >>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> validationType);
> >>> -            }
> >>> -        }
> >>> +    protected void setOperationSchemaValidation(Message message) {
> >>> +        SchemaValidationType validationType =
> >> ServiceUtils.getSchemaValidationType(message);
> >>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
> validationType);
> >>>    }
> >>>
> >>>    protected DepthXMLStreamReader getXMLStreamReader(Message message) {
> >>> @@ -247,7 +232,7 @@ public abstract class
> >> AbstractInDatabindingInterceptor extends AbstractPhaseInte
> >>>        }
> >>>
> >>>        // configure endpoint and operation level schema validation
> >>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >> message);
> >>> +        setOperationSchemaValidation(message);
> >>>
> >>>        QName serviceQName = si.getName();
> >>>        message.put(Message.WSDL_SERVICE, serviceQName);
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>> index db3ba6c..52d1cb1 100644
> >>> ---
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>> +++
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>> @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
> >>> import org.apache.cxf.service.model.BindingInfo;
> >>> import org.apache.cxf.service.model.BindingOperationInfo;
> >>> import org.apache.cxf.service.model.MessagePartInfo;
> >>> -import org.apache.cxf.service.model.OperationInfo;
> >>> import org.apache.cxf.staxutils.CachingXmlEventWriter;
> >>> import org.apache.cxf.staxutils.StaxUtils;
> >>> import org.apache.cxf.wsdl.EndpointReferenceUtils;
> >>> @@ -85,7 +84,7 @@ public abstract class
> >> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
> >>>        CachingXmlEventWriter cache = null;
> >>>
> >>>        // configure endpoint and operation level schema validation
> >>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >> message);
> >>> +        setOperationSchemaValidation(message);
> >>>
> >>>        // need to cache the events in case validation fails or
> >> buffering is enabled
> >>>        if (shouldBuffer(message)) {
> >>> @@ -159,22 +158,9 @@ public abstract class
> >> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
> >>>        }
> >>>    }
> >>>
> >>> -    /**
> >>> -     * Where an operation level validation type has been set, copy it
> >> to the message, so it can be interrogated
> >>> -     * by all downstream interceptors
> >>> -     *
> >>> -     * @param bop
> >>> -     * @param message
> >>> -     * @param reader
> >>> -     */
> >>> -    private void setOperationSchemaValidation(OperationInfo opInfo,
> >> Message message) {
> >>> -        if (opInfo != null) {
> >>> -            SchemaValidationType validationType =
> >>> -                (SchemaValidationType)
> >> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>> -            if (validationType != null) {
> >>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> validationType);
> >>> -            }
> >>> -        }
> >>> +    protected void setOperationSchemaValidation(Message message) {
> >>> +        SchemaValidationType validationType =
> >> ServiceUtils.getSchemaValidationType(message);
> >>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
> validationType);
> >>>    }
> >>>
> >>>    protected boolean shouldValidate(Message m) {
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
> >>> ----------------------------------------------------------------------
> >>> diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
> >> b/api/src/main/java/org/apache/cxf/message/Message.java
> >>> index 35e94af..5854a18 100644
> >>> --- a/api/src/main/java/org/apache/cxf/message/Message.java
> >>> +++ b/api/src/main/java/org/apache/cxf/message/Message.java
> >>> @@ -105,7 +105,16 @@ public interface Message extends StringMap {
> >>>     */
> >>>    String MTOM_ENABLED = "mtom-enabled";
> >>>    String MTOM_THRESHOLD = "mtom-threshold";
> >>> +
> >>> +    /**
> >>> +     * Runtime schema validation property
> >>> +     */
> >>>    String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
> >>> +
> >>> +    /**
> >>> +     * The default values for schema validation will be set in the
> >> service model using this property
> >>> +     */
> >>> +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
> >>>
> >>>    /**
> >>>     * Boolean property specifying if the Java stack trace is returned
> >> as a
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>
> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>> index fafd0a9..d49f090 100644
> >>> ---
> >>
> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>> +++
> >>
> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>> @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
> >> AbstractInDatabindingInterceptor {
> >>>        message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
> >>>
> >>>        // configure endpoint and operation level schema validation
> >>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >> message);
> >>> +        setOperationSchemaValidation(message);
> >>>    }
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>
> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>> index 7100f2c..9a7cbc8 100644
> >>> ---
> >>
> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>> +++
> >>
> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>> @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
> >> implements FactoryBeanListener {
> >>>            // if someone has gone to the effort of specifying
> >> enabled=false, then we need to
> >>>            // handle that, otherwise we use the new
> >> SchemaValidationType type only
> >>>            if (!annotation.enabled()) {
> >>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> SchemaValidationType.NONE);
> >>> +
> >> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >> SchemaValidationType.NONE);
> >>>            } else {
> >>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> annotation.type());
> >>> +
> >> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >> annotation.type());
> >>>            }
> >>>        }
> >>>    }
> >>> @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
> >> implements FactoryBeanListener {
> >>>    }
> >>>
> >>>    private void addSchemaValidationSupport(OperationInfo inf,
> >> SchemaValidation annotation) {
> >>> -        // Notice no support for deprecated enabled property here!
> >>> -        // TODO - should we check for the use of this property and at
> >> least log the fact we are
> >>> -        // ignoring it
> >>>        if (annotation != null) {
> >>> -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> >> annotation.type());
> >>> +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >> annotation.type());
> >>>        }
> >>>    }
> >>>
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>> index 888e5a8..9f08839 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>> @@ -20,12 +20,15 @@
> >>> package org.apache.cxf.systest.jaxws.schemavalidation;
> >>>
> >>> import java.io.IOException;
> >>> +import java.io.PrintWriter;
> >>> +import java.io.StringWriter;
> >>> import java.util.ArrayList;
> >>> import java.util.Arrays;
> >>> import java.util.HashMap;
> >>> import java.util.List;
> >>> import java.util.Map;
> >>>
> >>> +import javax.xml.ws.WebServiceException;
> >>> import javax.xml.ws.soap.SOAPFaultException;
> >>>
> >>> import
> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>> @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
> >>> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
> >>> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
> >>> import org.apache.cxf.message.Message;
> >>> -import org.apache.cxf.service.model.BindingOperationInfo;
> >>> import org.apache.cxf.testutil.common.TestUtil;
> >>> +import org.apache.cxf.transport.http.HTTPConduit;
> >>> +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
> >>> import org.junit.AfterClass;
> >>> import org.junit.Assert;
> >>> import org.junit.BeforeClass;
> >>> import org.junit.Test;
> >>>
> >>> -/**
> >>> - * TODO - test where the default is NONE at the service level test
> >> where the default is IN or OUT, and then
> >>> - * override at operation levels
> >>> - */
> >>> public class JavaFirstSchemaValidationTest extends Assert {
> >>> -    static final String PORT =
> >> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
> >>> +    static final String PORT =
> >> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> >>> +    static final String PORT_UNUSED =
> >> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> >>>
> >>>    private static List<Server> serverList = new ArrayList<Server>();
> >>>    private static PersonServiceAnnotated annotatedClient;
> >>> +    private static PersonServiceAnnotated annotatedValidatingClient;
> >>>    private static PersonService client;
> >>>    private static PersonServiceRPC rpcClient;
> >>> +
> >>> +    private static PersonService disconnectedClient;
> >>>
> >>>    @BeforeClass
> >>>    public static void startServers() throws Exception {
> >>> @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends
> >> Assert {
> >>>
> >>>        createServer(PersonServiceRPC.class, new PersonServiceRPCImpl(),
> >> feature, new LoggingFeature());
> >>>
> >>> -        annotatedClient = createClient(PersonServiceAnnotated.class);
> >>> -        client = createClient(PersonService.class);
> >>> -        rpcClient = createClient(PersonServiceRPC.class);
> >>> +        annotatedClient = createClient(PORT,
> >> PersonServiceAnnotated.class, SchemaValidationType.NONE);
> >>> +        annotatedValidatingClient = createClient(PORT,
> >> PersonServiceAnnotated.class, null);
> >>> +        client = createClient(PORT, PersonService.class,
> >> SchemaValidationType.NONE);
> >>> +        disconnectedClient = createClient(PORT_UNUSED,
> >> PersonService.class, SchemaValidationType.OUT);
> >>> +        rpcClient = createClient(PORT, PersonServiceRPC.class,
> >> SchemaValidationType.NONE);
> >>>    }
> >>>
> >>>    @AfterClass
> >>> @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends
> >> Assert {
> >>>        }
> >>>    }
> >>>
> >>> -    static String getAddress(Class<?> sei) {
> >>> -        return "http://localhost:" + PORT + "/" +
> sei.getSimpleName();
> >>> +    static String getAddress(String port, Class<?> sei) {
> >>> +        return "http://localhost:" + port + "/" +
> sei.getSimpleName();
> >>>    }
> >>> -
> >>>
> >>>    @Test
> >>>    public void testRPCLit() throws Exception {
> >>> @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest extends
> >> Assert {
> >>>        try {
> >>>            person.setFirstName(null);
> >>>            rpcClient.saveValidateOut(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>>            assertTrue(sfe.getMessage().contains("Marshalling Error"));
> >>>            assertTrue(sfe.getMessage().contains("lastName"));
> >>>        }
> >>> @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest
> extends
> >> Assert {
> >>>
> >>>        try {
> >>>            annotatedClient.saveInheritEndpoint(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        try {
> >>>            person.setFirstName(""); // empty string is valid
> >>>            annotatedClient.saveInheritEndpoint(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>>        annotatedClient.saveInheritEndpoint(person);
> >>>    }
> >>> -
> >>> +
> >>>    @Test
> >>>    public void testSaveValidateInAnnotated() {
> >>>        Person person = new Person();
> >>>
> >>>        try {
> >>>            annotatedClient.saveValidateIn(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        try {
> >>>            person.setFirstName(""); // empty string is valid
> >>>            annotatedClient.saveValidateIn(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>> @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
> >> extends Assert {
> >>>        annotatedClient.saveNoValidation(person);
> >>>    }
> >>>
> >>> -    // no validation is required for incoming
> >>>    @Test
> >>> -    public void testSaveValidationOutAnnotated() {
> >>> +    public void
> >> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
> >>>        Person person = new Person();
> >>>
> >>> -        annotatedClient.saveValidateOut(person);
> >>> +        try {
> >>> +            annotatedClient.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its server side and a schema validation
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>> +            // it's still a server side fault, because server side
> >> validation coming in failed
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>> +        person.setFirstName(""); // empty string is valid
> >>> +        try {
> >>> +            annotatedClient.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its server side and a schema validation
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>> +            // it's still a server side fault, because server side
> >> validation coming in failed
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>>
> >>> +        person.setLastName(""); // empty string is valid
> >>> +        annotatedClient.saveValidateIn(person);
> >>> +    }
> >>> +
> >>> +    // this will still all be server side, as the OUT validation is
> >> turned into an IN validation for
> >>> +    // the client, but by then the server has already thrown the
> >> exception for the OUT
> >>> +    @Test
> >>> +    public void
> >> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
> >>> +        Person person = new Person();
> >>> +
> >>> +        try {
> >>> +            annotatedValidatingClient.saveValidateIn(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>>        person.setFirstName(""); // empty string is valid
> >>> -        annotatedClient.saveValidateOut(person);
> >>> +        try {
> >>> +            annotatedValidatingClient.saveValidateIn(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>> -        annotatedClient.saveValidateOut(person);
> >>> +        annotatedValidatingClient.saveValidateIn(person);
> >>> +    }
> >>> +
> >>> +    @Test
> >>> +    public void
> >> testSaveValidationInAnnotatedWithClientValidationEnabled() {
> >>> +        Person person = new Person();
> >>> +
> >>> +        try {
> >>> +            person.setFirstName("InvalidResponse");
> >>> +            person.setLastName("WhoCares");
> >>> +            annotatedValidatingClient.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>>    }
> >>>
> >>> -    // so this is the default, we are inheriting from the service
> level
> >> SchemaValidation annotation
> >>> -    // which is set to BOTH
> >>>    @Test
> >>>    public void testEndpointSchemaValidationProvider() {
> >>>        Person person = new Person();
> >>>
> >>>        try {
> >>>            client.saveInheritEndpoint(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>> -
> >>> +
> >>>        try {
> >>>            person.setFirstName(""); // empty string is valid
> >>>            client.saveInheritEndpoint(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>> @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest
> extends
> >> Assert {
> >>>
> >>>        try {
> >>>            client.saveValidateIn(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        try {
> >>>            person.setFirstName(""); // empty string is valid
> >>>            client.saveValidateIn(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>>        client.saveValidateIn(person);
> >>>    }
> >>>
> >>> -    // no validation at all is required
> >>>    @Test
> >>>    public void testSaveNoValidationProvider() {
> >>>        Person person = new Person();
> >>> @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest
> extends
> >> Assert {
> >>>        client.saveNoValidation(person);
> >>>    }
> >>>
> >>> -    // no validation is required for incoming
> >>>    @Test
> >>> -    public void testSaveValidationOutProvider() {
> >>> +    public void testSaveValidationOutProviderClientOnly() {
> >>>        Person person = new Person();
> >>>
> >>> -        client.saveValidateOut(person);
> >>> +        try {
> >>> +            disconnectedClient.saveValidateOut(person);
> >>> +            fail("Expected exception");
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its client side outgoing
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>> +        person.setFirstName(""); // empty string is valid
> >>> +        try {
> >>> +            disconnectedClient.saveValidateOut(person);
> >>> +            fail("Expected exception");
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its client side outgoing
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>> +        person.setLastName(""); // empty string is valid
> >>> +
> >>> +        // this confirms that we passed client validation as we then
> >> got the connectivity error
> >>> +        try {
> >>> +            disconnectedClient.saveValidateOut(person);
> >>> +            fail("Expected exception");
> >>> +        } catch (WebServiceException e) {
> >>> +            assertTrue(e.getMessage().contains("Could not send
> >> Message"));
> >>> +        }
> >>> +    }
> >>>
> >>> +
> >>> +    @Test
> >>> +    public void testSaveValidationOutProvider() {
> >>> +        Person person = new Person();
> >>> +
> >>> +        try {
> >>> +            client.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its server side outgoing
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>>        person.setFirstName(""); // empty string is valid
> >>> -        client.saveValidateOut(person);
> >>> +        try {
> >>> +            client.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its server side outgoing
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>>        client.saveValidateOut(person);
> >>>    }
> >>>
> >>> -    private static <T> T createClient(Class<T> serviceClass) {
> >>> +    private static <T> T createClient(String port, Class<T>
> >> serviceClass, SchemaValidationType type) {
> >>>        JaxWsProxyFactoryBean clientFactory = new
> >> JaxWsProxyFactoryBean();
> >>>        clientFactory.setServiceClass(serviceClass);
> >>> -
> >>> -        // ensure all client schema validation is disabled
> >>> -        Map<String, Object> properties = new HashMap<String,
> Object>();
> >>> -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> SchemaValidationType.NONE);
> >>> -        clientFactory.setProperties(properties);
> >>> -
> >>> -        clientFactory.setAddress(getAddress(serviceClass));
> >>> -
> >>> +
> >>> +
> >>> +        clientFactory.setAddress(getAddress(port, serviceClass));
> >>> +
> >>> +
> >>>        @SuppressWarnings("unchecked")
> >>>        T newClient = (T)clientFactory.create();
> >>>
> >>> -        Client clientProxy = ClientProxy.getClient(newClient);
> >>> -
> >>> -        // ensure all client schema validation is disabled
> >>> -        for (BindingOperationInfo bop :
> >> clientProxy.getEndpoint().getEndpointInfo().getBinding()
> >>> -            .getOperations()) {
> >>> -
> >> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> >> SchemaValidationType.NONE);
> >>> +        Client proxy = ClientProxy.getClient(newClient);
> >>> +
> >>> +        if (type != null) {
> >>> +
> >> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED, type);
> >>>        }
> >>> -
> >>> +
> >>> +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
> >>> +        // give me longer debug times
> >>> +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
> >>> +        clientPolicy.setConnectionTimeout(1000000);
> >>> +        clientPolicy.setReceiveTimeout(1000000);
> >>> +        conduit.setClient(clientPolicy);
> >>> +
> >>>        return newClient;
> >>>    }
> >>>
> >>> @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest
> extends
> >> Assert {
> >>>        if (features != null) {
> >>>            svrFactory.getFeatures().addAll(Arrays.asList(features));
> >>>        }
> >>> -        svrFactory.setAddress(getAddress(serviceInterface));
> >>> +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
> >>>        svrFactory.setServiceBean(serviceImpl);
> >>>        Server server = svrFactory.create();
> >>>        serverList.add(server);
> >>>        return server;
> >>>    }
> >>> +
> >>> +    private String getStackTrace(Exception e) {
> >>> +        StringWriter sWriter = new StringWriter();
> >>> +        PrintWriter writer = new PrintWriter(sWriter, true);
> >>> +        e.printStackTrace(writer);
> >>> +        return sWriter.toString();
> >>> +    }
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>> index e3ee10c..d594e4e 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>> @@ -21,6 +21,7 @@ package
> org.apache.cxf.systest.jaxws.schemavalidation;
> >>>
> >>> import javax.jws.WebMethod;
> >>> import javax.jws.WebParam;
> >>> +import javax.jws.WebResult;
> >>> import javax.jws.WebService;
> >>>
> >>> import org.apache.cxf.annotations.SchemaValidation;
> >>> @@ -30,14 +31,18 @@ import
> >> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>> @SchemaValidation(type = SchemaValidationType.BOTH)
> >>> public interface PersonService {
> >>>    @WebMethod(operationName = "saveInheritEndpoint")
> >>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
> data);
> >>>
> >>>    @WebMethod(operationName = "saveNoValidation")
> >>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> >>>
> >>>    @WebMethod(operationName = "saveValidateIn")
> >>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> >>>
> >>>    @WebMethod(operationName = "saveValidateOut")
> >>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>> index 3e06576..a760f27 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>> @@ -21,6 +21,7 @@ package
> org.apache.cxf.systest.jaxws.schemavalidation;
> >>>
> >>> import javax.jws.WebMethod;
> >>> import javax.jws.WebParam;
> >>> +import javax.jws.WebResult;
> >>> import javax.jws.WebService;
> >>>
> >>> import org.apache.cxf.annotations.SchemaValidation;
> >>> @@ -30,17 +31,21 @@ import
> >> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>> @SchemaValidation(type = SchemaValidationType.BOTH)
> >>> public interface PersonServiceAnnotated {
> >>>    @WebMethod(operationName = "saveInheritEndpoint")
> >>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
> data);
> >>>
> >>>    @SchemaValidation(type = SchemaValidationType.NONE)
> >>>    @WebMethod(operationName = "saveNoValidation")
> >>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> >>>
> >>>    @SchemaValidation(type = SchemaValidationType.IN)
> >>>    @WebMethod(operationName = "saveValidateIn")
> >>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> >>>
> >>>    @SchemaValidation(type = SchemaValidationType.OUT)
> >>>    @WebMethod(operationName = "saveValidateOut")
> >>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>> index c7b8038..78973c9 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>> @@ -26,18 +26,25 @@ import javax.jws.WebService;
> >>>    targetNamespace = "
> >> http://org.apache.cxf/service/PersonServiceAnnotated")
> >>> public class PersonServiceAnnotatedImpl implements
> >> PersonServiceAnnotated {
> >>>    @Override
> >>> -    public void saveNoValidation(Person data) {
> >>> +    public Person saveNoValidation(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveInheritEndpoint(Person data) {
> >>> +    public Person saveInheritEndpoint(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveValidateIn(Person data) {
> >>> +    public Person saveValidateIn(Person data) {
> >>> +        if ("InvalidResponse".equals(data.getFirstName())) {
> >>> +            return new Person();
> >>> +        }
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveValidateOut(Person data) {
> >>> +    public Person saveValidateOut(Person data) {
> >>> +        return data;
> >>>    }
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>> index fe1d656..9edec45 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>> @@ -26,18 +26,22 @@ import javax.jws.WebService;
> >>>    targetNamespace = "http://org.apache.cxf/service/PersonService")
> >>> public class PersonServiceImpl implements PersonService {
> >>>    @Override
> >>> -    public void saveNoValidation(Person data) {
> >>> +    public Person saveNoValidation(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveInheritEndpoint(Person data) {
> >>> +    public Person saveInheritEndpoint(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveValidateIn(Person data) {
> >>> +    public Person saveValidateIn(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveValidateOut(Person data) {
> >>> +    public Person saveValidateOut(Person data) {
> >>> +        return data;
> >>>    }
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>
> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>> deleted file mode 100644
> >>> index 18e66ae..0000000
> >>> ---
> >>
> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>> +++ /dev/null
> >>> @@ -1,69 +0,0 @@
> >>> -/**
> >>> - * Licensed to the Apache Software Foundation (ASF) under one
> >>> - * or more contributor license agreements. See the NOTICE file
> >>> - * distributed with this work for additional information
> >>> - * regarding copyright ownership. The ASF licenses this file
> >>> - * to you 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.cxf.systest.mtom_schema_validation;
> >>> -
> >>> -import java.io.File;
> >>> -import java.net.URL;
> >>> -
> >>> -import javax.activation.DataHandler;
> >>> -import javax.activation.FileDataSource;
> >>> -import javax.xml.namespace.QName;
> >>> -import javax.xml.ws.soap.MTOMFeature;
> >>> -
> >>> -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> >>> -
> >>> -import org.junit.BeforeClass;
> >>> -import org.junit.Test;
> >>> -
> >>> -public final class MTOMProviderSchemaValidationTest extends
> >> AbstractBusClientServerTestBase {
> >>> -    public static final String PORT = "9001";
> >>> -        //Server.PORT;
> >>> -
> >>> -    private final QName serviceName = new QName("
> http://cxf.apache.org/",
> >> "HelloWS");
> >>> -
> >>> -    @BeforeClass
> >>> -    public static void startservers() throws Exception {
> >>> -        //assertTrue("server did not launch correctly",
> >> launchServer(Server.class, true));
> >>> -    }
> >>> -    @Test
> >>> -    public void testSchemaValidation() throws Exception {
> >>> -        HelloWS port = createService();
> >>> -        Hello request = new Hello();
> >>> -        request.setArg0("value");
> >>> -        URL wsdl =
> >> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> >>> -        File attachment = new File(wsdl.getFile());
> >>> -        request.setFile(new DataHandler(new
> >> FileDataSource(attachment)));
> >>> -        HelloResponse response = port.hello(request);
> >>> -        assertEquals("Hello CXF", response.getReturn());
> >>> -    }
> >>> -
> >>> -    private HelloWS createService() throws Exception {
> >>> -        URL wsdl =
> >> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> >>> -        assertNotNull(wsdl);
> >>> -
> >>> -        HelloWSClient service = new HelloWSClient(wsdl, serviceName);
> >>> -        assertNotNull(service);
> >>> -
> >>> -        HelloWS port = service.getHello(new MTOMFeature());
> >>> -
> >>> -        updateAddressPort(port, PORT);
> >>> -
> >>> -        return port;
> >>> -    }
> >>> -}
> >>>
> >>
> >> --
> >> Daniel Kulp
> >> dkulp@apache.org - http://dankulp.com/blog
> >> Talend Community Coder - http://coders.talend.com
> >>
> >>
>
> --
> Daniel Kulp
> dkulp@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
>
>

Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Jason Pell <ja...@pellcorp.com>.
Why ever have client validation then I guess if we know its valid.

The reporter had a problem that their cxf client was validating the
incoming data to the client that was never going to be valid. Because only
the incoming data to the server is guaranteed valid.  I still don't
understand how that can be the desired behavior.  However I will remove
those lines as requested hopefully tomorrow.

My additional changes will at least allow clients to turn off validation
completely which was not working if annotations were used.
On 29/11/2014 3:18 PM, "Daniel Kulp" <dk...@apache.org> wrote:

>
> > On Nov 28, 2014, at 10:11 PM, Jason Pell <jp...@apache.org> wrote:
> >
> > Its only reversing what's coming from the model. If you define IN in the
> > jaxws properties on the client it will continue to validate IN on the
> > client as before.
> >
> > If I have IN defined for a operation using an annotation the old code
> would
> > actually validate the response coming back to the client.
>
> That’s exactly what IN is supposed to mean.
>
> > This does seem
> > counter intuitive especially as IN might have been specified because the
> > response may be incomplete and so can't be validated.
>
> It would be way more counter intuitive to me for IN to apply to messages
> that are going OUT.    That’s completely back wards.
>
>
> > An IN for service is the OUT for client.
> >
> > The previous code was just plain wrong for client side - my code by the
> way
> > :-)
>
> Why do you think it’s wrong?
>
> Basically, we have services that specify validation for IN as that is the
> only direction that we don’t control and we need to validate that.  For
> messages that we produce (out on client, out on server), we know the
> messages are valid as we populate the data correctly.   However, we
> need/want to validate any incoming data to make sure that is correct.  That
> is exactly what IN is supposed to mean.  Validate any data coming IN.  By
> putting the annotation on the SEI specified with IN, we would get what I
> would regard as the correct behavior.  Validation of the stuff we cannot
> control and no validation for the stuff we already know is correct.
>
>
> > This particular piece is only a few lines in ServiceUtils so I am happy
> to
> > remove it if you are still -1
>
> That part, yes.  It’s wrong.
>
> Dan
>
>
> > The alternative is I will add a property to enable it but only if the
> > property is used.
> >
> > Would that be OK?
> > On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:
> >
> >>
> >> I’m -1 on the part of this that changes the IN to an OUT on the client
> >> side.   The IN and OUT are specifically named that way as they apply to
> the
> >> messages that come IN to the client or IN to the server.   The “IN”
> >> validation should definitely not be applying to the messages going OUT.
> >> Plus, that would be a huge behavioral change that would break many
> peoples
> >> existing applications.
> >>
> >> Dan
> >>
> >>
> >>
> >>
> >>> On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
> >>>
> >>> Repository: cxf
> >>> Updated Branches:
> >>> refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
> >>>
> >>>
> >>> CXF-6118 support overriding schema validation at jaxws endpoint and
> >> client level and applying the correct validation direction at client
> level
> >>>
> >>>
> >>> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
> >>> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
> >>> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
> >>> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
> >>>
> >>> Branch: refs/heads/2.7.x-fixes
> >>> Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
> >>> Parents: e172a3e
> >>> Author: Jason Pell <jp...@apache.org>
> >>> Authored: Thu Nov 27 16:54:01 2014 +1100
> >>> Committer: Jason Pell <jp...@apache.org>
> >>> Committed: Fri Nov 28 15:52:36 2014 +1100
> >>>
> >>> ----------------------------------------------------------------------
> >>> .../validation/SchemaValidationFeature.java     |   2 +-
> >>> .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
> >>> .../AbstractInDatabindingInterceptor.java       |  23 +-
> >>> .../AbstractOutDatabindingInterceptor.java      |  22 +-
> >>> .../java/org/apache/cxf/message/Message.java    |   9 +
> >>> .../soap/interceptor/RPCInInterceptor.java      |   2 +-
> >>> .../factory/AnnotationsFactoryBeanListener.java |   9 +-
> >>> .../JavaFirstSchemaValidationTest.java          | 256
> ++++++++++++++-----
> >>> .../jaxws/schemavalidation/PersonService.java   |  13 +-
> >>> .../PersonServiceAnnotated.java                 |  13 +-
> >>> .../PersonServiceAnnotatedImpl.java             |  15 +-
> >>> .../schemavalidation/PersonServiceImpl.java     |  12 +-
> >>> .../MTOMProviderSchemaValidationTest.bak        |  69 -----
> >>> 13 files changed, 342 insertions(+), 201 deletions(-)
> >>> ----------------------------------------------------------------------
> >>>
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>
> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>> index 5eda79c..c314eaf 100644
> >>> ---
> >>
> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>> +++
> >>
> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> >>> @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
> >> AbstractFeature {
> >>>        for (BindingOperationInfo bop :
> >> endpoint.getEndpointInfo().getBinding().getOperations()) {
> >>>            SchemaValidationType type =
> >> provider.getSchemaValidationType(bop.getOperationInfo());
> >>>            if (type != null) {
> >>> -
> >> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> type);
> >>> +
> >> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> type);
> >>>            }
> >>>        }
> >>>    }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>> ----------------------------------------------------------------------
> >>> diff --git a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>> index 85d77d0..28c7ba2 100644
> >>> --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>> +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> >>> @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
> >>> import javax.xml.namespace.QName;
> >>>
> >>> import
> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>> +import org.apache.cxf.endpoint.Endpoint;
> >>> +import org.apache.cxf.message.Exchange;
> >>> import org.apache.cxf.message.Message;
> >>> +import org.apache.cxf.message.MessageUtils;
> >>> +import org.apache.cxf.service.model.AbstractPropertiesHolder;
> >>> +import org.apache.cxf.service.model.BindingOperationInfo;
> >>> +import org.apache.cxf.service.model.EndpointInfo;
> >>> +import org.apache.cxf.service.model.OperationInfo;
> >>>
> >>> public final class ServiceUtils {
> >>> -
> >>>    private ServiceUtils() {
> >>>    }
> >>>
> >>> @@ -42,24 +48,94 @@ public final class ServiceUtils {
> >>>     * @param type
> >>>     */
> >>>    public static boolean isSchemaValidationEnabled(SchemaValidationType
> >> type, Message message) {
> >>> -        SchemaValidationType messageType =
> >> getSchemaValidationType(message);
> >>> +        SchemaValidationType validationType =
> >> getSchemaValidationType(message);
> >>>
> >>> -        return messageType.equals(type)
> >>> +        return validationType.equals(type)
> >>>            || ((SchemaValidationType.IN.equals(type) ||
> >> SchemaValidationType.OUT.equals(type))
> >>> -                && SchemaValidationType.BOTH.equals(messageType));
> >>> +                && SchemaValidationType.BOTH.equals(validationType));
> >>>    }
> >>> -
> >>> +
> >>>    /**
> >>> -     * Determines the appropriate SchemaValidationType to return based
> >> on either
> >>> -     * a Boolean (for backwards compatibility) or the selected Schema
> >> Validation Type.
> >>> -     *
> >>> -     * Package private as the isSchemaValidationEnabled method should
> >> be used instead.  Only
> >>> -     * visible for easier testing
> >>> +     * A convenience method to check for schema validation config in
> >> the message context, and then in the service model.
> >>> +     * Does not modify the Message context (other than what is done in
> >> the getContextualProperty itself)
> >>>     *
> >>>     * @param message
> >>> +     * @param type
> >>>     */
> >>> -    static SchemaValidationType getSchemaValidationType(Message
> >> message) {
> >>> +    public static SchemaValidationType getSchemaValidationType(Message
> >> message) {
> >>> +        SchemaValidationType validationType =
> >> getOverrideSchemaValidationType(message);
> >>> +        if (validationType == null) {
> >>> +            validationType =
> getSchemaValidationTypeFromModel(message);
> >>> +        }
> >>> +
> >>> +        if (validationType == null) {
> >>> +            validationType = SchemaValidationType.NONE;
> >>> +        }
> >>> +
> >>> +        return validationType;
> >>> +    }
> >>> +
> >>> +    private static SchemaValidationType
> >> getOverrideSchemaValidationType(Message message) {
> >>>        Object obj =
> >> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>> +        if (obj != null) {
> >>> +            // this method will transform the legacy enabled as well
> >>> +            return getSchemaValidationType(obj);
> >>> +        } else {
> >>> +            return null;
> >>> +        }
> >>> +    }
> >>> +
> >>> +    private static SchemaValidationType
> >> getSchemaValidationTypeFromModel(Message message) {
> >>> +        boolean isRequestor = MessageUtils.isRequestor(message);
> >>> +        Exchange exchange = message.getExchange();
> >>> +
> >>> +        if (exchange != null) {
> >>> +            BindingOperationInfo boi =
> >> exchange.getBindingOperationInfo();
> >>> +            Endpoint endpoint = exchange.getEndpoint();
> >>> +
> >>> +            if (boi != null && endpoint != null) {
> >>> +                SchemaValidationType validationType = null;
> >>> +                OperationInfo opInfo = boi.getOperationInfo();
> >>> +                EndpointInfo ep = endpoint.getEndpointInfo();
> >>> +
> >>> +                if (validationType == null && opInfo != null) {
> >>> +                    validationType =
> >> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
> >>> +
> >>> +                    if (validationType == null && ep != null) {
> >>> +                        validationType =
> >> getSchemaValidationTypeFromModel(message, ep, isRequestor);
> >>> +                    }
> >>> +                }
> >>> +
> >>> +                return validationType;
> >>> +            }
> >>> +        }
> >>> +
> >>> +        // else
> >>> +        return null;
> >>> +    }
> >>> +
> >>> +    private static SchemaValidationType
> >> getSchemaValidationTypeFromModel(
> >>> +            Message message, AbstractPropertiesHolder properties,
> >> boolean isRequestor) {
> >>> +        Object obj =
> >> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
> >>> +        if (obj != null) {
> >>> +            SchemaValidationType validationType =
> >> getSchemaValidationType(obj);
> >>> +
> >>> +            // Reverse the direction of any IN / OUT for requestor
> >> (client)
> >>> +            if (isRequestor) {
> >>> +                if (SchemaValidationType.IN.equals(validationType)) {
> >>> +                    return SchemaValidationType.OUT;
> >>> +                } else if
> >> (SchemaValidationType.OUT.equals(validationType)) {
> >>> +                    return SchemaValidationType.IN;
> >>> +                }
> >>> +            }
> >>> +
> >>> +            return validationType;
> >>> +        } else {
> >>> +            return null;
> >>> +        }
> >>> +    }
> >>> +
> >>> +    public static SchemaValidationType getSchemaValidationType(Object
> >> obj) {
> >>>        if (obj instanceof SchemaValidationType) {
> >>>            return (SchemaValidationType)obj;
> >>>        } else if (obj != null) {
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>> index c47417a..ec8cf71 100644
> >>> ---
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>> +++
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> >>> @@ -125,24 +125,9 @@ public abstract class
> >> AbstractInDatabindingInterceptor extends AbstractPhaseInte
> >>>        }
> >>>    }
> >>>
> >>> -    /**
> >>> -     * Where an operation level validation type has been set, copy it
> >> to the message, so it can be interrogated
> >>> -     * by all downstream interceptors.  It is expected that sub
> classes
> >> will call setDataReaderValidation subsequent
> >>> -     * to this to ensure the DataReader schema reference is updated as
> >> appropriate.
> >>> -     *
> >>> -     * @param bop
> >>> -     * @param message
> >>> -     * @param reader
> >>> -     * @see #setDataReaderValidation(Service, Message, DataReader)
> >>> -     */
> >>> -    protected void setOperationSchemaValidation(OperationInfo opInfo,
> >> Message message) {
> >>> -        if (opInfo != null) {
> >>> -            SchemaValidationType validationType =
> >>> -                (SchemaValidationType)
> >> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>> -            if (validationType != null) {
> >>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> validationType);
> >>> -            }
> >>> -        }
> >>> +    protected void setOperationSchemaValidation(Message message) {
> >>> +        SchemaValidationType validationType =
> >> ServiceUtils.getSchemaValidationType(message);
> >>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
> validationType);
> >>>    }
> >>>
> >>>    protected DepthXMLStreamReader getXMLStreamReader(Message message) {
> >>> @@ -247,7 +232,7 @@ public abstract class
> >> AbstractInDatabindingInterceptor extends AbstractPhaseInte
> >>>        }
> >>>
> >>>        // configure endpoint and operation level schema validation
> >>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >> message);
> >>> +        setOperationSchemaValidation(message);
> >>>
> >>>        QName serviceQName = si.getName();
> >>>        message.put(Message.WSDL_SERVICE, serviceQName);
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>> index db3ba6c..52d1cb1 100644
> >>> ---
> >>
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>> +++
> >>
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> >>> @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
> >>> import org.apache.cxf.service.model.BindingInfo;
> >>> import org.apache.cxf.service.model.BindingOperationInfo;
> >>> import org.apache.cxf.service.model.MessagePartInfo;
> >>> -import org.apache.cxf.service.model.OperationInfo;
> >>> import org.apache.cxf.staxutils.CachingXmlEventWriter;
> >>> import org.apache.cxf.staxutils.StaxUtils;
> >>> import org.apache.cxf.wsdl.EndpointReferenceUtils;
> >>> @@ -85,7 +84,7 @@ public abstract class
> >> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
> >>>        CachingXmlEventWriter cache = null;
> >>>
> >>>        // configure endpoint and operation level schema validation
> >>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >> message);
> >>> +        setOperationSchemaValidation(message);
> >>>
> >>>        // need to cache the events in case validation fails or
> >> buffering is enabled
> >>>        if (shouldBuffer(message)) {
> >>> @@ -159,22 +158,9 @@ public abstract class
> >> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
> >>>        }
> >>>    }
> >>>
> >>> -    /**
> >>> -     * Where an operation level validation type has been set, copy it
> >> to the message, so it can be interrogated
> >>> -     * by all downstream interceptors
> >>> -     *
> >>> -     * @param bop
> >>> -     * @param message
> >>> -     * @param reader
> >>> -     */
> >>> -    private void setOperationSchemaValidation(OperationInfo opInfo,
> >> Message message) {
> >>> -        if (opInfo != null) {
> >>> -            SchemaValidationType validationType =
> >>> -                (SchemaValidationType)
> >> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> >>> -            if (validationType != null) {
> >>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> validationType);
> >>> -            }
> >>> -        }
> >>> +    protected void setOperationSchemaValidation(Message message) {
> >>> +        SchemaValidationType validationType =
> >> ServiceUtils.getSchemaValidationType(message);
> >>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED,
> validationType);
> >>>    }
> >>>
> >>>    protected boolean shouldValidate(Message m) {
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
> >>> ----------------------------------------------------------------------
> >>> diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
> >> b/api/src/main/java/org/apache/cxf/message/Message.java
> >>> index 35e94af..5854a18 100644
> >>> --- a/api/src/main/java/org/apache/cxf/message/Message.java
> >>> +++ b/api/src/main/java/org/apache/cxf/message/Message.java
> >>> @@ -105,7 +105,16 @@ public interface Message extends StringMap {
> >>>     */
> >>>    String MTOM_ENABLED = "mtom-enabled";
> >>>    String MTOM_THRESHOLD = "mtom-threshold";
> >>> +
> >>> +    /**
> >>> +     * Runtime schema validation property
> >>> +     */
> >>>    String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
> >>> +
> >>> +    /**
> >>> +     * The default values for schema validation will be set in the
> >> service model using this property
> >>> +     */
> >>> +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
> >>>
> >>>    /**
> >>>     * Boolean property specifying if the Java stack trace is returned
> >> as a
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>
> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>> index fafd0a9..d49f090 100644
> >>> ---
> >>
> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>> +++
> >>
> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> >>> @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
> >> AbstractInDatabindingInterceptor {
> >>>        message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
> >>>
> >>>        // configure endpoint and operation level schema validation
> >>> -        setOperationSchemaValidation(operation.getOperationInfo(),
> >> message);
> >>> +        setOperationSchemaValidation(message);
> >>>    }
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>
> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>> index 7100f2c..9a7cbc8 100644
> >>> ---
> >>
> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>> +++
> >>
> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> >>> @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
> >> implements FactoryBeanListener {
> >>>            // if someone has gone to the effort of specifying
> >> enabled=false, then we need to
> >>>            // handle that, otherwise we use the new
> >> SchemaValidationType type only
> >>>            if (!annotation.enabled()) {
> >>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> SchemaValidationType.NONE);
> >>> +
> >> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >> SchemaValidationType.NONE);
> >>>            } else {
> >>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> annotation.type());
> >>> +
> >> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >> annotation.type());
> >>>            }
> >>>        }
> >>>    }
> >>> @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
> >> implements FactoryBeanListener {
> >>>    }
> >>>
> >>>    private void addSchemaValidationSupport(OperationInfo inf,
> >> SchemaValidation annotation) {
> >>> -        // Notice no support for deprecated enabled property here!
> >>> -        // TODO - should we check for the use of this property and at
> >> least log the fact we are
> >>> -        // ignoring it
> >>>        if (annotation != null) {
> >>> -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> >> annotation.type());
> >>> +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
> >> annotation.type());
> >>>        }
> >>>    }
> >>>
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>> index 888e5a8..9f08839 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> >>> @@ -20,12 +20,15 @@
> >>> package org.apache.cxf.systest.jaxws.schemavalidation;
> >>>
> >>> import java.io.IOException;
> >>> +import java.io.PrintWriter;
> >>> +import java.io.StringWriter;
> >>> import java.util.ArrayList;
> >>> import java.util.Arrays;
> >>> import java.util.HashMap;
> >>> import java.util.List;
> >>> import java.util.Map;
> >>>
> >>> +import javax.xml.ws.WebServiceException;
> >>> import javax.xml.ws.soap.SOAPFaultException;
> >>>
> >>> import
> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>> @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
> >>> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
> >>> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
> >>> import org.apache.cxf.message.Message;
> >>> -import org.apache.cxf.service.model.BindingOperationInfo;
> >>> import org.apache.cxf.testutil.common.TestUtil;
> >>> +import org.apache.cxf.transport.http.HTTPConduit;
> >>> +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
> >>> import org.junit.AfterClass;
> >>> import org.junit.Assert;
> >>> import org.junit.BeforeClass;
> >>> import org.junit.Test;
> >>>
> >>> -/**
> >>> - * TODO - test where the default is NONE at the service level test
> >> where the default is IN or OUT, and then
> >>> - * override at operation levels
> >>> - */
> >>> public class JavaFirstSchemaValidationTest extends Assert {
> >>> -    static final String PORT =
> >> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
> >>> +    static final String PORT =
> >> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> >>> +    static final String PORT_UNUSED =
> >> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> >>>
> >>>    private static List<Server> serverList = new ArrayList<Server>();
> >>>    private static PersonServiceAnnotated annotatedClient;
> >>> +    private static PersonServiceAnnotated annotatedValidatingClient;
> >>>    private static PersonService client;
> >>>    private static PersonServiceRPC rpcClient;
> >>> +
> >>> +    private static PersonService disconnectedClient;
> >>>
> >>>    @BeforeClass
> >>>    public static void startServers() throws Exception {
> >>> @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends
> >> Assert {
> >>>
> >>>        createServer(PersonServiceRPC.class, new PersonServiceRPCImpl(),
> >> feature, new LoggingFeature());
> >>>
> >>> -        annotatedClient = createClient(PersonServiceAnnotated.class);
> >>> -        client = createClient(PersonService.class);
> >>> -        rpcClient = createClient(PersonServiceRPC.class);
> >>> +        annotatedClient = createClient(PORT,
> >> PersonServiceAnnotated.class, SchemaValidationType.NONE);
> >>> +        annotatedValidatingClient = createClient(PORT,
> >> PersonServiceAnnotated.class, null);
> >>> +        client = createClient(PORT, PersonService.class,
> >> SchemaValidationType.NONE);
> >>> +        disconnectedClient = createClient(PORT_UNUSED,
> >> PersonService.class, SchemaValidationType.OUT);
> >>> +        rpcClient = createClient(PORT, PersonServiceRPC.class,
> >> SchemaValidationType.NONE);
> >>>    }
> >>>
> >>>    @AfterClass
> >>> @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends
> >> Assert {
> >>>        }
> >>>    }
> >>>
> >>> -    static String getAddress(Class<?> sei) {
> >>> -        return "http://localhost:" + PORT + "/" +
> sei.getSimpleName();
> >>> +    static String getAddress(String port, Class<?> sei) {
> >>> +        return "http://localhost:" + port + "/" +
> sei.getSimpleName();
> >>>    }
> >>> -
> >>>
> >>>    @Test
> >>>    public void testRPCLit() throws Exception {
> >>> @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest extends
> >> Assert {
> >>>        try {
> >>>            person.setFirstName(null);
> >>>            rpcClient.saveValidateOut(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>>            assertTrue(sfe.getMessage().contains("Marshalling Error"));
> >>>            assertTrue(sfe.getMessage().contains("lastName"));
> >>>        }
> >>> @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest
> extends
> >> Assert {
> >>>
> >>>        try {
> >>>            annotatedClient.saveInheritEndpoint(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        try {
> >>>            person.setFirstName(""); // empty string is valid
> >>>            annotatedClient.saveInheritEndpoint(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>>        annotatedClient.saveInheritEndpoint(person);
> >>>    }
> >>> -
> >>> +
> >>>    @Test
> >>>    public void testSaveValidateInAnnotated() {
> >>>        Person person = new Person();
> >>>
> >>>        try {
> >>>            annotatedClient.saveValidateIn(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        try {
> >>>            person.setFirstName(""); // empty string is valid
> >>>            annotatedClient.saveValidateIn(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>> @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
> >> extends Assert {
> >>>        annotatedClient.saveNoValidation(person);
> >>>    }
> >>>
> >>> -    // no validation is required for incoming
> >>>    @Test
> >>> -    public void testSaveValidationOutAnnotated() {
> >>> +    public void
> >> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
> >>>        Person person = new Person();
> >>>
> >>> -        annotatedClient.saveValidateOut(person);
> >>> +        try {
> >>> +            annotatedClient.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its server side and a schema validation
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>> +            // it's still a server side fault, because server side
> >> validation coming in failed
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>> +        person.setFirstName(""); // empty string is valid
> >>> +        try {
> >>> +            annotatedClient.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its server side and a schema validation
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>> +            // it's still a server side fault, because server side
> >> validation coming in failed
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>>
> >>> +        person.setLastName(""); // empty string is valid
> >>> +        annotatedClient.saveValidateIn(person);
> >>> +    }
> >>> +
> >>> +    // this will still all be server side, as the OUT validation is
> >> turned into an IN validation for
> >>> +    // the client, but by then the server has already thrown the
> >> exception for the OUT
> >>> +    @Test
> >>> +    public void
> >> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
> >>> +        Person person = new Person();
> >>> +
> >>> +        try {
> >>> +            annotatedValidatingClient.saveValidateIn(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>>        person.setFirstName(""); // empty string is valid
> >>> -        annotatedClient.saveValidateOut(person);
> >>> +        try {
> >>> +            annotatedValidatingClient.saveValidateIn(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>> -        annotatedClient.saveValidateOut(person);
> >>> +        annotatedValidatingClient.saveValidateIn(person);
> >>> +    }
> >>> +
> >>> +    @Test
> >>> +    public void
> >> testSaveValidationInAnnotatedWithClientValidationEnabled() {
> >>> +        Person person = new Person();
> >>> +
> >>> +        try {
> >>> +            person.setFirstName("InvalidResponse");
> >>> +            person.setLastName("WhoCares");
> >>> +            annotatedValidatingClient.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>>    }
> >>>
> >>> -    // so this is the default, we are inheriting from the service
> level
> >> SchemaValidation annotation
> >>> -    // which is set to BOTH
> >>>    @Test
> >>>    public void testEndpointSchemaValidationProvider() {
> >>>        Person person = new Person();
> >>>
> >>>        try {
> >>>            client.saveInheritEndpoint(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>> -
> >>> +
> >>>        try {
> >>>            person.setFirstName(""); // empty string is valid
> >>>            client.saveInheritEndpoint(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>> @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest
> extends
> >> Assert {
> >>>
> >>>        try {
> >>>            client.saveValidateIn(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        try {
> >>>            person.setFirstName(""); // empty string is valid
> >>>            client.saveValidateIn(person);
> >>> +            fail("Expected exception");
> >>>        } catch (SOAPFaultException sfe) {
> >>> -            // verify its server side and a schema validation
> >>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
> >> Error"));
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>>        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>>        client.saveValidateIn(person);
> >>>    }
> >>>
> >>> -    // no validation at all is required
> >>>    @Test
> >>>    public void testSaveNoValidationProvider() {
> >>>        Person person = new Person();
> >>> @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest
> extends
> >> Assert {
> >>>        client.saveNoValidation(person);
> >>>    }
> >>>
> >>> -    // no validation is required for incoming
> >>>    @Test
> >>> -    public void testSaveValidationOutProvider() {
> >>> +    public void testSaveValidationOutProviderClientOnly() {
> >>>        Person person = new Person();
> >>>
> >>> -        client.saveValidateOut(person);
> >>> +        try {
> >>> +            disconnectedClient.saveValidateOut(person);
> >>> +            fail("Expected exception");
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its client side outgoing
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>> +        person.setFirstName(""); // empty string is valid
> >>> +        try {
> >>> +            disconnectedClient.saveValidateOut(person);
> >>> +            fail("Expected exception");
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its client side outgoing
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>> +        person.setLastName(""); // empty string is valid
> >>> +
> >>> +        // this confirms that we passed client validation as we then
> >> got the connectivity error
> >>> +        try {
> >>> +            disconnectedClient.saveValidateOut(person);
> >>> +            fail("Expected exception");
> >>> +        } catch (WebServiceException e) {
> >>> +            assertTrue(e.getMessage().contains("Could not send
> >> Message"));
> >>> +        }
> >>> +    }
> >>>
> >>> +
> >>> +    @Test
> >>> +    public void testSaveValidationOutProvider() {
> >>> +        Person person = new Person();
> >>> +
> >>> +        try {
> >>> +            client.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its server side outgoing
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>> +
> >>>        person.setFirstName(""); // empty string is valid
> >>> -        client.saveValidateOut(person);
> >>> +        try {
> >>> +            client.saveValidateOut(person);
> >>> +        } catch (SOAPFaultException sfe) {
> >>> +            // verify its server side outgoing
> >>> +            String stackTrace = getStackTrace(sfe);
> >>> +            assertTrue(stackTrace.contains("Marshalling Error"));
> >>> +
> >>
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >>> +        }
> >>>
> >>>        person.setLastName(""); // empty string is valid
> >>>        client.saveValidateOut(person);
> >>>    }
> >>>
> >>> -    private static <T> T createClient(Class<T> serviceClass) {
> >>> +    private static <T> T createClient(String port, Class<T>
> >> serviceClass, SchemaValidationType type) {
> >>>        JaxWsProxyFactoryBean clientFactory = new
> >> JaxWsProxyFactoryBean();
> >>>        clientFactory.setServiceClass(serviceClass);
> >>> -
> >>> -        // ensure all client schema validation is disabled
> >>> -        Map<String, Object> properties = new HashMap<String,
> Object>();
> >>> -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
> >> SchemaValidationType.NONE);
> >>> -        clientFactory.setProperties(properties);
> >>> -
> >>> -        clientFactory.setAddress(getAddress(serviceClass));
> >>> -
> >>> +
> >>> +
> >>> +        clientFactory.setAddress(getAddress(port, serviceClass));
> >>> +
> >>> +
> >>>        @SuppressWarnings("unchecked")
> >>>        T newClient = (T)clientFactory.create();
> >>>
> >>> -        Client clientProxy = ClientProxy.getClient(newClient);
> >>> -
> >>> -        // ensure all client schema validation is disabled
> >>> -        for (BindingOperationInfo bop :
> >> clientProxy.getEndpoint().getEndpointInfo().getBinding()
> >>> -            .getOperations()) {
> >>> -
> >> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> >> SchemaValidationType.NONE);
> >>> +        Client proxy = ClientProxy.getClient(newClient);
> >>> +
> >>> +        if (type != null) {
> >>> +
> >> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED, type);
> >>>        }
> >>> -
> >>> +
> >>> +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
> >>> +        // give me longer debug times
> >>> +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
> >>> +        clientPolicy.setConnectionTimeout(1000000);
> >>> +        clientPolicy.setReceiveTimeout(1000000);
> >>> +        conduit.setClient(clientPolicy);
> >>> +
> >>>        return newClient;
> >>>    }
> >>>
> >>> @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest
> extends
> >> Assert {
> >>>        if (features != null) {
> >>>            svrFactory.getFeatures().addAll(Arrays.asList(features));
> >>>        }
> >>> -        svrFactory.setAddress(getAddress(serviceInterface));
> >>> +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
> >>>        svrFactory.setServiceBean(serviceImpl);
> >>>        Server server = svrFactory.create();
> >>>        serverList.add(server);
> >>>        return server;
> >>>    }
> >>> +
> >>> +    private String getStackTrace(Exception e) {
> >>> +        StringWriter sWriter = new StringWriter();
> >>> +        PrintWriter writer = new PrintWriter(sWriter, true);
> >>> +        e.printStackTrace(writer);
> >>> +        return sWriter.toString();
> >>> +    }
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>> index e3ee10c..d594e4e 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> >>> @@ -21,6 +21,7 @@ package
> org.apache.cxf.systest.jaxws.schemavalidation;
> >>>
> >>> import javax.jws.WebMethod;
> >>> import javax.jws.WebParam;
> >>> +import javax.jws.WebResult;
> >>> import javax.jws.WebService;
> >>>
> >>> import org.apache.cxf.annotations.SchemaValidation;
> >>> @@ -30,14 +31,18 @@ import
> >> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>> @SchemaValidation(type = SchemaValidationType.BOTH)
> >>> public interface PersonService {
> >>>    @WebMethod(operationName = "saveInheritEndpoint")
> >>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
> data);
> >>>
> >>>    @WebMethod(operationName = "saveNoValidation")
> >>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> >>>
> >>>    @WebMethod(operationName = "saveValidateIn")
> >>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> >>>
> >>>    @WebMethod(operationName = "saveValidateOut")
> >>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>> index 3e06576..a760f27 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> >>> @@ -21,6 +21,7 @@ package
> org.apache.cxf.systest.jaxws.schemavalidation;
> >>>
> >>> import javax.jws.WebMethod;
> >>> import javax.jws.WebParam;
> >>> +import javax.jws.WebResult;
> >>> import javax.jws.WebService;
> >>>
> >>> import org.apache.cxf.annotations.SchemaValidation;
> >>> @@ -30,17 +31,21 @@ import
> >> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> >>> @SchemaValidation(type = SchemaValidationType.BOTH)
> >>> public interface PersonServiceAnnotated {
> >>>    @WebMethod(operationName = "saveInheritEndpoint")
> >>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person
> data);
> >>>
> >>>    @SchemaValidation(type = SchemaValidationType.NONE)
> >>>    @WebMethod(operationName = "saveNoValidation")
> >>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> >>>
> >>>    @SchemaValidation(type = SchemaValidationType.IN)
> >>>    @WebMethod(operationName = "saveValidateIn")
> >>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> >>>
> >>>    @SchemaValidation(type = SchemaValidationType.OUT)
> >>>    @WebMethod(operationName = "saveValidateOut")
> >>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
> >>> +    @WebResult(name = "Person")
> >>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>> index c7b8038..78973c9 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> >>> @@ -26,18 +26,25 @@ import javax.jws.WebService;
> >>>    targetNamespace = "
> >> http://org.apache.cxf/service/PersonServiceAnnotated")
> >>> public class PersonServiceAnnotatedImpl implements
> >> PersonServiceAnnotated {
> >>>    @Override
> >>> -    public void saveNoValidation(Person data) {
> >>> +    public Person saveNoValidation(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveInheritEndpoint(Person data) {
> >>> +    public Person saveInheritEndpoint(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveValidateIn(Person data) {
> >>> +    public Person saveValidateIn(Person data) {
> >>> +        if ("InvalidResponse".equals(data.getFirstName())) {
> >>> +            return new Person();
> >>> +        }
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveValidateOut(Person data) {
> >>> +    public Person saveValidateOut(Person data) {
> >>> +        return data;
> >>>    }
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>> index fe1d656..9edec45 100644
> >>> ---
> >>
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>> +++
> >>
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> >>> @@ -26,18 +26,22 @@ import javax.jws.WebService;
> >>>    targetNamespace = "http://org.apache.cxf/service/PersonService")
> >>> public class PersonServiceImpl implements PersonService {
> >>>    @Override
> >>> -    public void saveNoValidation(Person data) {
> >>> +    public Person saveNoValidation(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveInheritEndpoint(Person data) {
> >>> +    public Person saveInheritEndpoint(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveValidateIn(Person data) {
> >>> +    public Person saveValidateIn(Person data) {
> >>> +        return data;
> >>>    }
> >>>
> >>>    @Override
> >>> -    public void saveValidateOut(Person data) {
> >>> +    public Person saveValidateOut(Person data) {
> >>> +        return data;
> >>>    }
> >>> }
> >>>
> >>>
> >>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>> ----------------------------------------------------------------------
> >>> diff --git
> >>
> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>
> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>> deleted file mode 100644
> >>> index 18e66ae..0000000
> >>> ---
> >>
> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> >>> +++ /dev/null
> >>> @@ -1,69 +0,0 @@
> >>> -/**
> >>> - * Licensed to the Apache Software Foundation (ASF) under one
> >>> - * or more contributor license agreements. See the NOTICE file
> >>> - * distributed with this work for additional information
> >>> - * regarding copyright ownership. The ASF licenses this file
> >>> - * to you 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.cxf.systest.mtom_schema_validation;
> >>> -
> >>> -import java.io.File;
> >>> -import java.net.URL;
> >>> -
> >>> -import javax.activation.DataHandler;
> >>> -import javax.activation.FileDataSource;
> >>> -import javax.xml.namespace.QName;
> >>> -import javax.xml.ws.soap.MTOMFeature;
> >>> -
> >>> -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> >>> -
> >>> -import org.junit.BeforeClass;
> >>> -import org.junit.Test;
> >>> -
> >>> -public final class MTOMProviderSchemaValidationTest extends
> >> AbstractBusClientServerTestBase {
> >>> -    public static final String PORT = "9001";
> >>> -        //Server.PORT;
> >>> -
> >>> -    private final QName serviceName = new QName("
> http://cxf.apache.org/",
> >> "HelloWS");
> >>> -
> >>> -    @BeforeClass
> >>> -    public static void startservers() throws Exception {
> >>> -        //assertTrue("server did not launch correctly",
> >> launchServer(Server.class, true));
> >>> -    }
> >>> -    @Test
> >>> -    public void testSchemaValidation() throws Exception {
> >>> -        HelloWS port = createService();
> >>> -        Hello request = new Hello();
> >>> -        request.setArg0("value");
> >>> -        URL wsdl =
> >> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> >>> -        File attachment = new File(wsdl.getFile());
> >>> -        request.setFile(new DataHandler(new
> >> FileDataSource(attachment)));
> >>> -        HelloResponse response = port.hello(request);
> >>> -        assertEquals("Hello CXF", response.getReturn());
> >>> -    }
> >>> -
> >>> -    private HelloWS createService() throws Exception {
> >>> -        URL wsdl =
> >> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> >>> -        assertNotNull(wsdl);
> >>> -
> >>> -        HelloWSClient service = new HelloWSClient(wsdl, serviceName);
> >>> -        assertNotNull(service);
> >>> -
> >>> -        HelloWS port = service.getHello(new MTOMFeature());
> >>> -
> >>> -        updateAddressPort(port, PORT);
> >>> -
> >>> -        return port;
> >>> -    }
> >>> -}
> >>>
> >>
> >> --
> >> Daniel Kulp
> >> dkulp@apache.org - http://dankulp.com/blog
> >> Talend Community Coder - http://coders.talend.com
> >>
> >>
>
> --
> Daniel Kulp
> dkulp@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
>
>

Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Daniel Kulp <dk...@apache.org>.
> On Nov 28, 2014, at 10:11 PM, Jason Pell <jp...@apache.org> wrote:
> 
> Its only reversing what's coming from the model. If you define IN in the
> jaxws properties on the client it will continue to validate IN on the
> client as before.
> 
> If I have IN defined for a operation using an annotation the old code would
> actually validate the response coming back to the client.

That’s exactly what IN is supposed to mean.

> This does seem
> counter intuitive especially as IN might have been specified because the
> response may be incomplete and so can't be validated.

It would be way more counter intuitive to me for IN to apply to messages that are going OUT.    That’s completely back wards.


> An IN for service is the OUT for client.
> 
> The previous code was just plain wrong for client side - my code by the way
> :-)

Why do you think it’s wrong?   

Basically, we have services that specify validation for IN as that is the only direction that we don’t control and we need to validate that.  For messages that we produce (out on client, out on server), we know the messages are valid as we populate the data correctly.   However, we need/want to validate any incoming data to make sure that is correct.  That is exactly what IN is supposed to mean.  Validate any data coming IN.  By putting the annotation on the SEI specified with IN, we would get what I would regard as the correct behavior.  Validation of the stuff we cannot control and no validation for the stuff we already know is correct.


> This particular piece is only a few lines in ServiceUtils so I am happy to
> remove it if you are still -1

That part, yes.  It’s wrong. 

Dan


> The alternative is I will add a property to enable it but only if the
> property is used.
> 
> Would that be OK?
> On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:
> 
>> 
>> I’m -1 on the part of this that changes the IN to an OUT on the client
>> side.   The IN and OUT are specifically named that way as they apply to the
>> messages that come IN to the client or IN to the server.   The “IN”
>> validation should definitely not be applying to the messages going OUT.
>> Plus, that would be a huge behavioral change that would break many peoples
>> existing applications.
>> 
>> Dan
>> 
>> 
>> 
>> 
>>> On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
>>> 
>>> Repository: cxf
>>> Updated Branches:
>>> refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
>>> 
>>> 
>>> CXF-6118 support overriding schema validation at jaxws endpoint and
>> client level and applying the correct validation direction at client level
>>> 
>>> 
>>> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
>>> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
>>> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
>>> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
>>> 
>>> Branch: refs/heads/2.7.x-fixes
>>> Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
>>> Parents: e172a3e
>>> Author: Jason Pell <jp...@apache.org>
>>> Authored: Thu Nov 27 16:54:01 2014 +1100
>>> Committer: Jason Pell <jp...@apache.org>
>>> Committed: Fri Nov 28 15:52:36 2014 +1100
>>> 
>>> ----------------------------------------------------------------------
>>> .../validation/SchemaValidationFeature.java     |   2 +-
>>> .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
>>> .../AbstractInDatabindingInterceptor.java       |  23 +-
>>> .../AbstractOutDatabindingInterceptor.java      |  22 +-
>>> .../java/org/apache/cxf/message/Message.java    |   9 +
>>> .../soap/interceptor/RPCInInterceptor.java      |   2 +-
>>> .../factory/AnnotationsFactoryBeanListener.java |   9 +-
>>> .../JavaFirstSchemaValidationTest.java          | 256 ++++++++++++++-----
>>> .../jaxws/schemavalidation/PersonService.java   |  13 +-
>>> .../PersonServiceAnnotated.java                 |  13 +-
>>> .../PersonServiceAnnotatedImpl.java             |  15 +-
>>> .../schemavalidation/PersonServiceImpl.java     |  12 +-
>>> .../MTOMProviderSchemaValidationTest.bak        |  69 -----
>>> 13 files changed, 342 insertions(+), 201 deletions(-)
>>> ----------------------------------------------------------------------
>>> 
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>> index 5eda79c..c314eaf 100644
>>> ---
>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>> +++
>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>> @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
>> AbstractFeature {
>>>        for (BindingOperationInfo bop :
>> endpoint.getEndpointInfo().getBinding().getOperations()) {
>>>            SchemaValidationType type =
>> provider.getSchemaValidationType(bop.getOperationInfo());
>>>            if (type != null) {
>>> -
>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED, type);
>>> +
>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE, type);
>>>            }
>>>        }
>>>    }
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>> ----------------------------------------------------------------------
>>> diff --git a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>> index 85d77d0..28c7ba2 100644
>>> --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>> +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>> @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
>>> import javax.xml.namespace.QName;
>>> 
>>> import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>> +import org.apache.cxf.endpoint.Endpoint;
>>> +import org.apache.cxf.message.Exchange;
>>> import org.apache.cxf.message.Message;
>>> +import org.apache.cxf.message.MessageUtils;
>>> +import org.apache.cxf.service.model.AbstractPropertiesHolder;
>>> +import org.apache.cxf.service.model.BindingOperationInfo;
>>> +import org.apache.cxf.service.model.EndpointInfo;
>>> +import org.apache.cxf.service.model.OperationInfo;
>>> 
>>> public final class ServiceUtils {
>>> -
>>>    private ServiceUtils() {
>>>    }
>>> 
>>> @@ -42,24 +48,94 @@ public final class ServiceUtils {
>>>     * @param type
>>>     */
>>>    public static boolean isSchemaValidationEnabled(SchemaValidationType
>> type, Message message) {
>>> -        SchemaValidationType messageType =
>> getSchemaValidationType(message);
>>> +        SchemaValidationType validationType =
>> getSchemaValidationType(message);
>>> 
>>> -        return messageType.equals(type)
>>> +        return validationType.equals(type)
>>>            || ((SchemaValidationType.IN.equals(type) ||
>> SchemaValidationType.OUT.equals(type))
>>> -                && SchemaValidationType.BOTH.equals(messageType));
>>> +                && SchemaValidationType.BOTH.equals(validationType));
>>>    }
>>> -
>>> +
>>>    /**
>>> -     * Determines the appropriate SchemaValidationType to return based
>> on either
>>> -     * a Boolean (for backwards compatibility) or the selected Schema
>> Validation Type.
>>> -     *
>>> -     * Package private as the isSchemaValidationEnabled method should
>> be used instead.  Only
>>> -     * visible for easier testing
>>> +     * A convenience method to check for schema validation config in
>> the message context, and then in the service model.
>>> +     * Does not modify the Message context (other than what is done in
>> the getContextualProperty itself)
>>>     *
>>>     * @param message
>>> +     * @param type
>>>     */
>>> -    static SchemaValidationType getSchemaValidationType(Message
>> message) {
>>> +    public static SchemaValidationType getSchemaValidationType(Message
>> message) {
>>> +        SchemaValidationType validationType =
>> getOverrideSchemaValidationType(message);
>>> +        if (validationType == null) {
>>> +            validationType = getSchemaValidationTypeFromModel(message);
>>> +        }
>>> +
>>> +        if (validationType == null) {
>>> +            validationType = SchemaValidationType.NONE;
>>> +        }
>>> +
>>> +        return validationType;
>>> +    }
>>> +
>>> +    private static SchemaValidationType
>> getOverrideSchemaValidationType(Message message) {
>>>        Object obj =
>> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>> +        if (obj != null) {
>>> +            // this method will transform the legacy enabled as well
>>> +            return getSchemaValidationType(obj);
>>> +        } else {
>>> +            return null;
>>> +        }
>>> +    }
>>> +
>>> +    private static SchemaValidationType
>> getSchemaValidationTypeFromModel(Message message) {
>>> +        boolean isRequestor = MessageUtils.isRequestor(message);
>>> +        Exchange exchange = message.getExchange();
>>> +
>>> +        if (exchange != null) {
>>> +            BindingOperationInfo boi =
>> exchange.getBindingOperationInfo();
>>> +            Endpoint endpoint = exchange.getEndpoint();
>>> +
>>> +            if (boi != null && endpoint != null) {
>>> +                SchemaValidationType validationType = null;
>>> +                OperationInfo opInfo = boi.getOperationInfo();
>>> +                EndpointInfo ep = endpoint.getEndpointInfo();
>>> +
>>> +                if (validationType == null && opInfo != null) {
>>> +                    validationType =
>> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
>>> +
>>> +                    if (validationType == null && ep != null) {
>>> +                        validationType =
>> getSchemaValidationTypeFromModel(message, ep, isRequestor);
>>> +                    }
>>> +                }
>>> +
>>> +                return validationType;
>>> +            }
>>> +        }
>>> +
>>> +        // else
>>> +        return null;
>>> +    }
>>> +
>>> +    private static SchemaValidationType
>> getSchemaValidationTypeFromModel(
>>> +            Message message, AbstractPropertiesHolder properties,
>> boolean isRequestor) {
>>> +        Object obj =
>> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
>>> +        if (obj != null) {
>>> +            SchemaValidationType validationType =
>> getSchemaValidationType(obj);
>>> +
>>> +            // Reverse the direction of any IN / OUT for requestor
>> (client)
>>> +            if (isRequestor) {
>>> +                if (SchemaValidationType.IN.equals(validationType)) {
>>> +                    return SchemaValidationType.OUT;
>>> +                } else if
>> (SchemaValidationType.OUT.equals(validationType)) {
>>> +                    return SchemaValidationType.IN;
>>> +                }
>>> +            }
>>> +
>>> +            return validationType;
>>> +        } else {
>>> +            return null;
>>> +        }
>>> +    }
>>> +
>>> +    public static SchemaValidationType getSchemaValidationType(Object
>> obj) {
>>>        if (obj instanceof SchemaValidationType) {
>>>            return (SchemaValidationType)obj;
>>>        } else if (obj != null) {
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>> index c47417a..ec8cf71 100644
>>> ---
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>> +++
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>> @@ -125,24 +125,9 @@ public abstract class
>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>>>        }
>>>    }
>>> 
>>> -    /**
>>> -     * Where an operation level validation type has been set, copy it
>> to the message, so it can be interrogated
>>> -     * by all downstream interceptors.  It is expected that sub classes
>> will call setDataReaderValidation subsequent
>>> -     * to this to ensure the DataReader schema reference is updated as
>> appropriate.
>>> -     *
>>> -     * @param bop
>>> -     * @param message
>>> -     * @param reader
>>> -     * @see #setDataReaderValidation(Service, Message, DataReader)
>>> -     */
>>> -    protected void setOperationSchemaValidation(OperationInfo opInfo,
>> Message message) {
>>> -        if (opInfo != null) {
>>> -            SchemaValidationType validationType =
>>> -                (SchemaValidationType)
>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>> -            if (validationType != null) {
>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> validationType);
>>> -            }
>>> -        }
>>> +    protected void setOperationSchemaValidation(Message message) {
>>> +        SchemaValidationType validationType =
>> ServiceUtils.getSchemaValidationType(message);
>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
>>>    }
>>> 
>>>    protected DepthXMLStreamReader getXMLStreamReader(Message message) {
>>> @@ -247,7 +232,7 @@ public abstract class
>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>>>        }
>>> 
>>>        // configure endpoint and operation level schema validation
>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>> message);
>>> +        setOperationSchemaValidation(message);
>>> 
>>>        QName serviceQName = si.getName();
>>>        message.put(Message.WSDL_SERVICE, serviceQName);
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>> index db3ba6c..52d1cb1 100644
>>> ---
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>> +++
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>> @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
>>> import org.apache.cxf.service.model.BindingInfo;
>>> import org.apache.cxf.service.model.BindingOperationInfo;
>>> import org.apache.cxf.service.model.MessagePartInfo;
>>> -import org.apache.cxf.service.model.OperationInfo;
>>> import org.apache.cxf.staxutils.CachingXmlEventWriter;
>>> import org.apache.cxf.staxutils.StaxUtils;
>>> import org.apache.cxf.wsdl.EndpointReferenceUtils;
>>> @@ -85,7 +84,7 @@ public abstract class
>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>>>        CachingXmlEventWriter cache = null;
>>> 
>>>        // configure endpoint and operation level schema validation
>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>> message);
>>> +        setOperationSchemaValidation(message);
>>> 
>>>        // need to cache the events in case validation fails or
>> buffering is enabled
>>>        if (shouldBuffer(message)) {
>>> @@ -159,22 +158,9 @@ public abstract class
>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>>>        }
>>>    }
>>> 
>>> -    /**
>>> -     * Where an operation level validation type has been set, copy it
>> to the message, so it can be interrogated
>>> -     * by all downstream interceptors
>>> -     *
>>> -     * @param bop
>>> -     * @param message
>>> -     * @param reader
>>> -     */
>>> -    private void setOperationSchemaValidation(OperationInfo opInfo,
>> Message message) {
>>> -        if (opInfo != null) {
>>> -            SchemaValidationType validationType =
>>> -                (SchemaValidationType)
>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>> -            if (validationType != null) {
>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> validationType);
>>> -            }
>>> -        }
>>> +    protected void setOperationSchemaValidation(Message message) {
>>> +        SchemaValidationType validationType =
>> ServiceUtils.getSchemaValidationType(message);
>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
>>>    }
>>> 
>>>    protected boolean shouldValidate(Message m) {
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
>>> ----------------------------------------------------------------------
>>> diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
>> b/api/src/main/java/org/apache/cxf/message/Message.java
>>> index 35e94af..5854a18 100644
>>> --- a/api/src/main/java/org/apache/cxf/message/Message.java
>>> +++ b/api/src/main/java/org/apache/cxf/message/Message.java
>>> @@ -105,7 +105,16 @@ public interface Message extends StringMap {
>>>     */
>>>    String MTOM_ENABLED = "mtom-enabled";
>>>    String MTOM_THRESHOLD = "mtom-threshold";
>>> +
>>> +    /**
>>> +     * Runtime schema validation property
>>> +     */
>>>    String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
>>> +
>>> +    /**
>>> +     * The default values for schema validation will be set in the
>> service model using this property
>>> +     */
>>> +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
>>> 
>>>    /**
>>>     * Boolean property specifying if the Java stack trace is returned
>> as a
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>> index fafd0a9..d49f090 100644
>>> ---
>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>> +++
>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>> @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
>> AbstractInDatabindingInterceptor {
>>>        message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
>>> 
>>>        // configure endpoint and operation level schema validation
>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>> message);
>>> +        setOperationSchemaValidation(message);
>>>    }
>>> }
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>> index 7100f2c..9a7cbc8 100644
>>> ---
>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>> +++
>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>> @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
>> implements FactoryBeanListener {
>>>            // if someone has gone to the effort of specifying
>> enabled=false, then we need to
>>>            // handle that, otherwise we use the new
>> SchemaValidationType type only
>>>            if (!annotation.enabled()) {
>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>> SchemaValidationType.NONE);
>>> +
>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> SchemaValidationType.NONE);
>>>            } else {
>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>> annotation.type());
>>> +
>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> annotation.type());
>>>            }
>>>        }
>>>    }
>>> @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
>> implements FactoryBeanListener {
>>>    }
>>> 
>>>    private void addSchemaValidationSupport(OperationInfo inf,
>> SchemaValidation annotation) {
>>> -        // Notice no support for deprecated enabled property here!
>>> -        // TODO - should we check for the use of this property and at
>> least log the fact we are
>>> -        // ignoring it
>>>        if (annotation != null) {
>>> -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>> annotation.type());
>>> +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> annotation.type());
>>>        }
>>>    }
>>> 
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>> index 888e5a8..9f08839 100644
>>> ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>> +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>> @@ -20,12 +20,15 @@
>>> package org.apache.cxf.systest.jaxws.schemavalidation;
>>> 
>>> import java.io.IOException;
>>> +import java.io.PrintWriter;
>>> +import java.io.StringWriter;
>>> import java.util.ArrayList;
>>> import java.util.Arrays;
>>> import java.util.HashMap;
>>> import java.util.List;
>>> import java.util.Map;
>>> 
>>> +import javax.xml.ws.WebServiceException;
>>> import javax.xml.ws.soap.SOAPFaultException;
>>> 
>>> import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>> @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
>>> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
>>> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
>>> import org.apache.cxf.message.Message;
>>> -import org.apache.cxf.service.model.BindingOperationInfo;
>>> import org.apache.cxf.testutil.common.TestUtil;
>>> +import org.apache.cxf.transport.http.HTTPConduit;
>>> +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
>>> import org.junit.AfterClass;
>>> import org.junit.Assert;
>>> import org.junit.BeforeClass;
>>> import org.junit.Test;
>>> 
>>> -/**
>>> - * TODO - test where the default is NONE at the service level test
>> where the default is IN or OUT, and then
>>> - * override at operation levels
>>> - */
>>> public class JavaFirstSchemaValidationTest extends Assert {
>>> -    static final String PORT =
>> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
>>> +    static final String PORT =
>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>>> +    static final String PORT_UNUSED =
>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>>> 
>>>    private static List<Server> serverList = new ArrayList<Server>();
>>>    private static PersonServiceAnnotated annotatedClient;
>>> +    private static PersonServiceAnnotated annotatedValidatingClient;
>>>    private static PersonService client;
>>>    private static PersonServiceRPC rpcClient;
>>> +
>>> +    private static PersonService disconnectedClient;
>>> 
>>>    @BeforeClass
>>>    public static void startServers() throws Exception {
>>> @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>>> 
>>>        createServer(PersonServiceRPC.class, new PersonServiceRPCImpl(),
>> feature, new LoggingFeature());
>>> 
>>> -        annotatedClient = createClient(PersonServiceAnnotated.class);
>>> -        client = createClient(PersonService.class);
>>> -        rpcClient = createClient(PersonServiceRPC.class);
>>> +        annotatedClient = createClient(PORT,
>> PersonServiceAnnotated.class, SchemaValidationType.NONE);
>>> +        annotatedValidatingClient = createClient(PORT,
>> PersonServiceAnnotated.class, null);
>>> +        client = createClient(PORT, PersonService.class,
>> SchemaValidationType.NONE);
>>> +        disconnectedClient = createClient(PORT_UNUSED,
>> PersonService.class, SchemaValidationType.OUT);
>>> +        rpcClient = createClient(PORT, PersonServiceRPC.class,
>> SchemaValidationType.NONE);
>>>    }
>>> 
>>>    @AfterClass
>>> @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>>>        }
>>>    }
>>> 
>>> -    static String getAddress(Class<?> sei) {
>>> -        return "http://localhost:" + PORT + "/" + sei.getSimpleName();
>>> +    static String getAddress(String port, Class<?> sei) {
>>> +        return "http://localhost:" + port + "/" + sei.getSimpleName();
>>>    }
>>> -
>>> 
>>>    @Test
>>>    public void testRPCLit() throws Exception {
>>> @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>>>        try {
>>>            person.setFirstName(null);
>>>            rpcClient.saveValidateOut(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>>            assertTrue(sfe.getMessage().contains("Marshalling Error"));
>>>            assertTrue(sfe.getMessage().contains("lastName"));
>>>        }
>>> @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>>> 
>>>        try {
>>>            annotatedClient.saveInheritEndpoint(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>        }
>>> 
>>>        try {
>>>            person.setFirstName(""); // empty string is valid
>>>            annotatedClient.saveInheritEndpoint(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>        }
>>> 
>>>        person.setLastName(""); // empty string is valid
>>>        annotatedClient.saveInheritEndpoint(person);
>>>    }
>>> -
>>> +
>>>    @Test
>>>    public void testSaveValidateInAnnotated() {
>>>        Person person = new Person();
>>> 
>>>        try {
>>>            annotatedClient.saveValidateIn(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>        }
>>> 
>>>        try {
>>>            person.setFirstName(""); // empty string is valid
>>>            annotatedClient.saveValidateIn(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>        }
>>> 
>>>        person.setLastName(""); // empty string is valid
>>> @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
>> extends Assert {
>>>        annotatedClient.saveNoValidation(person);
>>>    }
>>> 
>>> -    // no validation is required for incoming
>>>    @Test
>>> -    public void testSaveValidationOutAnnotated() {
>>> +    public void
>> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
>>>        Person person = new Person();
>>> 
>>> -        annotatedClient.saveValidateOut(person);
>>> +        try {
>>> +            annotatedClient.saveValidateOut(person);
>>> +        } catch (SOAPFaultException sfe) {
>>> +            // verify its server side and a schema validation
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>>> +            // it's still a server side fault, because server side
>> validation coming in failed
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>> +
>>> +        person.setFirstName(""); // empty string is valid
>>> +        try {
>>> +            annotatedClient.saveValidateOut(person);
>>> +        } catch (SOAPFaultException sfe) {
>>> +            // verify its server side and a schema validation
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>>> +            // it's still a server side fault, because server side
>> validation coming in failed
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>> 
>>> +        person.setLastName(""); // empty string is valid
>>> +        annotatedClient.saveValidateIn(person);
>>> +    }
>>> +
>>> +    // this will still all be server side, as the OUT validation is
>> turned into an IN validation for
>>> +    // the client, but by then the server has already thrown the
>> exception for the OUT
>>> +    @Test
>>> +    public void
>> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
>>> +        Person person = new Person();
>>> +
>>> +        try {
>>> +            annotatedValidatingClient.saveValidateIn(person);
>>> +        } catch (SOAPFaultException sfe) {
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>> +
>>>        person.setFirstName(""); // empty string is valid
>>> -        annotatedClient.saveValidateOut(person);
>>> +        try {
>>> +            annotatedValidatingClient.saveValidateIn(person);
>>> +        } catch (SOAPFaultException sfe) {
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>> 
>>>        person.setLastName(""); // empty string is valid
>>> -        annotatedClient.saveValidateOut(person);
>>> +        annotatedValidatingClient.saveValidateIn(person);
>>> +    }
>>> +
>>> +    @Test
>>> +    public void
>> testSaveValidationInAnnotatedWithClientValidationEnabled() {
>>> +        Person person = new Person();
>>> +
>>> +        try {
>>> +            person.setFirstName("InvalidResponse");
>>> +            person.setLastName("WhoCares");
>>> +            annotatedValidatingClient.saveValidateOut(person);
>>> +        } catch (SOAPFaultException sfe) {
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>>    }
>>> 
>>> -    // so this is the default, we are inheriting from the service level
>> SchemaValidation annotation
>>> -    // which is set to BOTH
>>>    @Test
>>>    public void testEndpointSchemaValidationProvider() {
>>>        Person person = new Person();
>>> 
>>>        try {
>>>            client.saveInheritEndpoint(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>        }
>>> -
>>> +
>>>        try {
>>>            person.setFirstName(""); // empty string is valid
>>>            client.saveInheritEndpoint(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>        }
>>> 
>>>        person.setLastName(""); // empty string is valid
>>> @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>>> 
>>>        try {
>>>            client.saveValidateIn(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>        }
>>> 
>>>        try {
>>>            person.setFirstName(""); // empty string is valid
>>>            client.saveValidateIn(person);
>>> +            fail("Expected exception");
>>>        } catch (SOAPFaultException sfe) {
>>> -            // verify its server side and a schema validation
>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>        }
>>> 
>>>        person.setLastName(""); // empty string is valid
>>>        client.saveValidateIn(person);
>>>    }
>>> 
>>> -    // no validation at all is required
>>>    @Test
>>>    public void testSaveNoValidationProvider() {
>>>        Person person = new Person();
>>> @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>>>        client.saveNoValidation(person);
>>>    }
>>> 
>>> -    // no validation is required for incoming
>>>    @Test
>>> -    public void testSaveValidationOutProvider() {
>>> +    public void testSaveValidationOutProviderClientOnly() {
>>>        Person person = new Person();
>>> 
>>> -        client.saveValidateOut(person);
>>> +        try {
>>> +            disconnectedClient.saveValidateOut(person);
>>> +            fail("Expected exception");
>>> +        } catch (SOAPFaultException sfe) {
>>> +            // verify its client side outgoing
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>> +
>>> +        person.setFirstName(""); // empty string is valid
>>> +        try {
>>> +            disconnectedClient.saveValidateOut(person);
>>> +            fail("Expected exception");
>>> +        } catch (SOAPFaultException sfe) {
>>> +            // verify its client side outgoing
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>> +
>>> +        person.setLastName(""); // empty string is valid
>>> +
>>> +        // this confirms that we passed client validation as we then
>> got the connectivity error
>>> +        try {
>>> +            disconnectedClient.saveValidateOut(person);
>>> +            fail("Expected exception");
>>> +        } catch (WebServiceException e) {
>>> +            assertTrue(e.getMessage().contains("Could not send
>> Message"));
>>> +        }
>>> +    }
>>> 
>>> +
>>> +    @Test
>>> +    public void testSaveValidationOutProvider() {
>>> +        Person person = new Person();
>>> +
>>> +        try {
>>> +            client.saveValidateOut(person);
>>> +        } catch (SOAPFaultException sfe) {
>>> +            // verify its server side outgoing
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>> +
>>>        person.setFirstName(""); // empty string is valid
>>> -        client.saveValidateOut(person);
>>> +        try {
>>> +            client.saveValidateOut(person);
>>> +        } catch (SOAPFaultException sfe) {
>>> +            // verify its server side outgoing
>>> +            String stackTrace = getStackTrace(sfe);
>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>> +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>> +        }
>>> 
>>>        person.setLastName(""); // empty string is valid
>>>        client.saveValidateOut(person);
>>>    }
>>> 
>>> -    private static <T> T createClient(Class<T> serviceClass) {
>>> +    private static <T> T createClient(String port, Class<T>
>> serviceClass, SchemaValidationType type) {
>>>        JaxWsProxyFactoryBean clientFactory = new
>> JaxWsProxyFactoryBean();
>>>        clientFactory.setServiceClass(serviceClass);
>>> -
>>> -        // ensure all client schema validation is disabled
>>> -        Map<String, Object> properties = new HashMap<String, Object>();
>>> -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
>> SchemaValidationType.NONE);
>>> -        clientFactory.setProperties(properties);
>>> -
>>> -        clientFactory.setAddress(getAddress(serviceClass));
>>> -
>>> +
>>> +
>>> +        clientFactory.setAddress(getAddress(port, serviceClass));
>>> +
>>> +
>>>        @SuppressWarnings("unchecked")
>>>        T newClient = (T)clientFactory.create();
>>> 
>>> -        Client clientProxy = ClientProxy.getClient(newClient);
>>> -
>>> -        // ensure all client schema validation is disabled
>>> -        for (BindingOperationInfo bop :
>> clientProxy.getEndpoint().getEndpointInfo().getBinding()
>>> -            .getOperations()) {
>>> -
>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>> SchemaValidationType.NONE);
>>> +        Client proxy = ClientProxy.getClient(newClient);
>>> +
>>> +        if (type != null) {
>>> +
>> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED, type);
>>>        }
>>> -
>>> +
>>> +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
>>> +        // give me longer debug times
>>> +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
>>> +        clientPolicy.setConnectionTimeout(1000000);
>>> +        clientPolicy.setReceiveTimeout(1000000);
>>> +        conduit.setClient(clientPolicy);
>>> +
>>>        return newClient;
>>>    }
>>> 
>>> @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>>>        if (features != null) {
>>>            svrFactory.getFeatures().addAll(Arrays.asList(features));
>>>        }
>>> -        svrFactory.setAddress(getAddress(serviceInterface));
>>> +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
>>>        svrFactory.setServiceBean(serviceImpl);
>>>        Server server = svrFactory.create();
>>>        serverList.add(server);
>>>        return server;
>>>    }
>>> +
>>> +    private String getStackTrace(Exception e) {
>>> +        StringWriter sWriter = new StringWriter();
>>> +        PrintWriter writer = new PrintWriter(sWriter, true);
>>> +        e.printStackTrace(writer);
>>> +        return sWriter.toString();
>>> +    }
>>> }
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>> index e3ee10c..d594e4e 100644
>>> ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>> +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>> @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
>>> 
>>> import javax.jws.WebMethod;
>>> import javax.jws.WebParam;
>>> +import javax.jws.WebResult;
>>> import javax.jws.WebService;
>>> 
>>> import org.apache.cxf.annotations.SchemaValidation;
>>> @@ -30,14 +31,18 @@ import
>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>> @SchemaValidation(type = SchemaValidationType.BOTH)
>>> public interface PersonService {
>>>    @WebMethod(operationName = "saveInheritEndpoint")
>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>> +    @WebResult(name = "Person")
>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>> 
>>>    @WebMethod(operationName = "saveNoValidation")
>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
>>> +    @WebResult(name = "Person")
>>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
>>> 
>>>    @WebMethod(operationName = "saveValidateIn")
>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
>>> +    @WebResult(name = "Person")
>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>>> 
>>>    @WebMethod(operationName = "saveValidateOut")
>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
>>> +    @WebResult(name = "Person")
>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>>> }
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>> index 3e06576..a760f27 100644
>>> ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>> +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>> @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
>>> 
>>> import javax.jws.WebMethod;
>>> import javax.jws.WebParam;
>>> +import javax.jws.WebResult;
>>> import javax.jws.WebService;
>>> 
>>> import org.apache.cxf.annotations.SchemaValidation;
>>> @@ -30,17 +31,21 @@ import
>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>> @SchemaValidation(type = SchemaValidationType.BOTH)
>>> public interface PersonServiceAnnotated {
>>>    @WebMethod(operationName = "saveInheritEndpoint")
>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>> +    @WebResult(name = "Person")
>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>> 
>>>    @SchemaValidation(type = SchemaValidationType.NONE)
>>>    @WebMethod(operationName = "saveNoValidation")
>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
>>> +    @WebResult(name = "Person")
>>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
>>> 
>>>    @SchemaValidation(type = SchemaValidationType.IN)
>>>    @WebMethod(operationName = "saveValidateIn")
>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
>>> +    @WebResult(name = "Person")
>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>>> 
>>>    @SchemaValidation(type = SchemaValidationType.OUT)
>>>    @WebMethod(operationName = "saveValidateOut")
>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
>>> +    @WebResult(name = "Person")
>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>>> }
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>> index c7b8038..78973c9 100644
>>> ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>> +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>> @@ -26,18 +26,25 @@ import javax.jws.WebService;
>>>    targetNamespace = "
>> http://org.apache.cxf/service/PersonServiceAnnotated")
>>> public class PersonServiceAnnotatedImpl implements
>> PersonServiceAnnotated {
>>>    @Override
>>> -    public void saveNoValidation(Person data) {
>>> +    public Person saveNoValidation(Person data) {
>>> +        return data;
>>>    }
>>> 
>>>    @Override
>>> -    public void saveInheritEndpoint(Person data) {
>>> +    public Person saveInheritEndpoint(Person data) {
>>> +        return data;
>>>    }
>>> 
>>>    @Override
>>> -    public void saveValidateIn(Person data) {
>>> +    public Person saveValidateIn(Person data) {
>>> +        if ("InvalidResponse".equals(data.getFirstName())) {
>>> +            return new Person();
>>> +        }
>>> +        return data;
>>>    }
>>> 
>>>    @Override
>>> -    public void saveValidateOut(Person data) {
>>> +    public Person saveValidateOut(Person data) {
>>> +        return data;
>>>    }
>>> }
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>> index fe1d656..9edec45 100644
>>> ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>> +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>> @@ -26,18 +26,22 @@ import javax.jws.WebService;
>>>    targetNamespace = "http://org.apache.cxf/service/PersonService")
>>> public class PersonServiceImpl implements PersonService {
>>>    @Override
>>> -    public void saveNoValidation(Person data) {
>>> +    public Person saveNoValidation(Person data) {
>>> +        return data;
>>>    }
>>> 
>>>    @Override
>>> -    public void saveInheritEndpoint(Person data) {
>>> +    public Person saveInheritEndpoint(Person data) {
>>> +        return data;
>>>    }
>>> 
>>>    @Override
>>> -    public void saveValidateIn(Person data) {
>>> +    public Person saveValidateIn(Person data) {
>>> +        return data;
>>>    }
>>> 
>>>    @Override
>>> -    public void saveValidateOut(Person data) {
>>> +    public Person saveValidateOut(Person data) {
>>> +        return data;
>>>    }
>>> }
>>> 
>>> 
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>> ----------------------------------------------------------------------
>>> diff --git
>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>> deleted file mode 100644
>>> index 18e66ae..0000000
>>> ---
>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>> +++ /dev/null
>>> @@ -1,69 +0,0 @@
>>> -/**
>>> - * Licensed to the Apache Software Foundation (ASF) under one
>>> - * or more contributor license agreements. See the NOTICE file
>>> - * distributed with this work for additional information
>>> - * regarding copyright ownership. The ASF licenses this file
>>> - * to you 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.cxf.systest.mtom_schema_validation;
>>> -
>>> -import java.io.File;
>>> -import java.net.URL;
>>> -
>>> -import javax.activation.DataHandler;
>>> -import javax.activation.FileDataSource;
>>> -import javax.xml.namespace.QName;
>>> -import javax.xml.ws.soap.MTOMFeature;
>>> -
>>> -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
>>> -
>>> -import org.junit.BeforeClass;
>>> -import org.junit.Test;
>>> -
>>> -public final class MTOMProviderSchemaValidationTest extends
>> AbstractBusClientServerTestBase {
>>> -    public static final String PORT = "9001";
>>> -        //Server.PORT;
>>> -
>>> -    private final QName serviceName = new QName("http://cxf.apache.org/",
>> "HelloWS");
>>> -
>>> -    @BeforeClass
>>> -    public static void startservers() throws Exception {
>>> -        //assertTrue("server did not launch correctly",
>> launchServer(Server.class, true));
>>> -    }
>>> -    @Test
>>> -    public void testSchemaValidation() throws Exception {
>>> -        HelloWS port = createService();
>>> -        Hello request = new Hello();
>>> -        request.setArg0("value");
>>> -        URL wsdl =
>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>>> -        File attachment = new File(wsdl.getFile());
>>> -        request.setFile(new DataHandler(new
>> FileDataSource(attachment)));
>>> -        HelloResponse response = port.hello(request);
>>> -        assertEquals("Hello CXF", response.getReturn());
>>> -    }
>>> -
>>> -    private HelloWS createService() throws Exception {
>>> -        URL wsdl =
>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>>> -        assertNotNull(wsdl);
>>> -
>>> -        HelloWSClient service = new HelloWSClient(wsdl, serviceName);
>>> -        assertNotNull(service);
>>> -
>>> -        HelloWS port = service.getHello(new MTOMFeature());
>>> -
>>> -        updateAddressPort(port, PORT);
>>> -
>>> -        return port;
>>> -    }
>>> -}
>>> 
>> 
>> --
>> Daniel Kulp
>> dkulp@apache.org - http://dankulp.com/blog
>> Talend Community Coder - http://coders.talend.com
>> 
>> 

-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com


Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Daniel Kulp <dk...@apache.org>.
Another option could be to add two new values to the SchemaValidationType enum.   Not sure what to call them.  WSDL_INPUT and WSDL_OUTPUT maybe to apply to the WSDL Input/Output messages?

Dan



> On Nov 28, 2014, at 10:22 PM, Jason Pell <ja...@pellcorp.com> wrote:
> 
> I will add the property anyway as it occurs to me this would be a problem
> for anyone who has defined a client specific sei and already reversed the
> directions.
> 
> Unless you want me to remove the client reverse direction code completely I
> will get the property and any test changes committed this weekend.
> On 29/11/2014 2:11 PM, "Jason Pell" <jp...@apache.org> wrote:
> 
>> Its only reversing what's coming from the model. If you define IN in the
>> jaxws properties on the client it will continue to validate IN on the
>> client as before.
>> 
>> If I have IN defined for a operation using an annotation the old code
>> would actually validate the response coming back to the client. This does
>> seem counter intuitive especially as IN might have been specified because
>> the response may be incomplete and so can't be validated.
>> 
>> An IN for service is the OUT for client.
>> 
>> The previous code was just plain wrong for client side - my code by the
>> way :-)
>> 
>> This particular piece is only a few lines in ServiceUtils so I am happy to
>> remove it if you are still -1
>> 
>> The alternative is I will add a property to enable it but only if the
>> property is used.
>> 
>> Would that be OK?
>> On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:
>> 
>>> 
>>> I’m -1 on the part of this that changes the IN to an OUT on the client
>>> side.   The IN and OUT are specifically named that way as they apply to the
>>> messages that come IN to the client or IN to the server.   The “IN”
>>> validation should definitely not be applying to the messages going OUT.
>>> Plus, that would be a huge behavioral change that would break many peoples
>>> existing applications.
>>> 
>>> Dan
>>> 
>>> 
>>> 
>>> 
>>>> On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
>>>> 
>>>> Repository: cxf
>>>> Updated Branches:
>>>> refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
>>>> 
>>>> 
>>>> CXF-6118 support overriding schema validation at jaxws endpoint and
>>> client level and applying the correct validation direction at client level
>>>> 
>>>> 
>>>> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
>>>> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
>>>> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
>>>> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
>>>> 
>>>> Branch: refs/heads/2.7.x-fixes
>>>> Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
>>>> Parents: e172a3e
>>>> Author: Jason Pell <jp...@apache.org>
>>>> Authored: Thu Nov 27 16:54:01 2014 +1100
>>>> Committer: Jason Pell <jp...@apache.org>
>>>> Committed: Fri Nov 28 15:52:36 2014 +1100
>>>> 
>>>> ----------------------------------------------------------------------
>>>> .../validation/SchemaValidationFeature.java     |   2 +-
>>>> .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
>>>> .../AbstractInDatabindingInterceptor.java       |  23 +-
>>>> .../AbstractOutDatabindingInterceptor.java      |  22 +-
>>>> .../java/org/apache/cxf/message/Message.java    |   9 +
>>>> .../soap/interceptor/RPCInInterceptor.java      |   2 +-
>>>> .../factory/AnnotationsFactoryBeanListener.java |   9 +-
>>>> .../JavaFirstSchemaValidationTest.java          | 256
>>> ++++++++++++++-----
>>>> .../jaxws/schemavalidation/PersonService.java   |  13 +-
>>>> .../PersonServiceAnnotated.java                 |  13 +-
>>>> .../PersonServiceAnnotatedImpl.java             |  15 +-
>>>> .../schemavalidation/PersonServiceImpl.java     |  12 +-
>>>> .../MTOMProviderSchemaValidationTest.bak        |  69 -----
>>>> 13 files changed, 342 insertions(+), 201 deletions(-)
>>>> ----------------------------------------------------------------------
>>>> 
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>> index 5eda79c..c314eaf 100644
>>>> ---
>>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>> +++
>>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>>>> @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
>>> AbstractFeature {
>>>>        for (BindingOperationInfo bop :
>>> endpoint.getEndpointInfo().getBinding().getOperations()) {
>>>>            SchemaValidationType type =
>>> provider.getSchemaValidationType(bop.getOperationInfo());
>>>>            if (type != null) {
>>>> -
>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED, type);
>>>> +
>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE, type);
>>>>            }
>>>>        }
>>>>    }
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>> ----------------------------------------------------------------------
>>>> diff --git a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>> index 85d77d0..28c7ba2 100644
>>>> --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>> +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>>>> @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
>>>> import javax.xml.namespace.QName;
>>>> 
>>>> import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>>> +import org.apache.cxf.endpoint.Endpoint;
>>>> +import org.apache.cxf.message.Exchange;
>>>> import org.apache.cxf.message.Message;
>>>> +import org.apache.cxf.message.MessageUtils;
>>>> +import org.apache.cxf.service.model.AbstractPropertiesHolder;
>>>> +import org.apache.cxf.service.model.BindingOperationInfo;
>>>> +import org.apache.cxf.service.model.EndpointInfo;
>>>> +import org.apache.cxf.service.model.OperationInfo;
>>>> 
>>>> public final class ServiceUtils {
>>>> -
>>>>    private ServiceUtils() {
>>>>    }
>>>> 
>>>> @@ -42,24 +48,94 @@ public final class ServiceUtils {
>>>>     * @param type
>>>>     */
>>>>    public static boolean
>>> isSchemaValidationEnabled(SchemaValidationType type, Message message) {
>>>> -        SchemaValidationType messageType =
>>> getSchemaValidationType(message);
>>>> +        SchemaValidationType validationType =
>>> getSchemaValidationType(message);
>>>> 
>>>> -        return messageType.equals(type)
>>>> +        return validationType.equals(type)
>>>>            || ((SchemaValidationType.IN.equals(type) ||
>>> SchemaValidationType.OUT.equals(type))
>>>> -                && SchemaValidationType.BOTH.equals(messageType));
>>>> +                && SchemaValidationType.BOTH.equals(validationType));
>>>>    }
>>>> -
>>>> +
>>>>    /**
>>>> -     * Determines the appropriate SchemaValidationType to return based
>>> on either
>>>> -     * a Boolean (for backwards compatibility) or the selected Schema
>>> Validation Type.
>>>> -     *
>>>> -     * Package private as the isSchemaValidationEnabled method should
>>> be used instead.  Only
>>>> -     * visible for easier testing
>>>> +     * A convenience method to check for schema validation config in
>>> the message context, and then in the service model.
>>>> +     * Does not modify the Message context (other than what is done in
>>> the getContextualProperty itself)
>>>>     *
>>>>     * @param message
>>>> +     * @param type
>>>>     */
>>>> -    static SchemaValidationType getSchemaValidationType(Message
>>> message) {
>>>> +    public static SchemaValidationType getSchemaValidationType(Message
>>> message) {
>>>> +        SchemaValidationType validationType =
>>> getOverrideSchemaValidationType(message);
>>>> +        if (validationType == null) {
>>>> +            validationType = getSchemaValidationTypeFromModel(message);
>>>> +        }
>>>> +
>>>> +        if (validationType == null) {
>>>> +            validationType = SchemaValidationType.NONE;
>>>> +        }
>>>> +
>>>> +        return validationType;
>>>> +    }
>>>> +
>>>> +    private static SchemaValidationType
>>> getOverrideSchemaValidationType(Message message) {
>>>>        Object obj =
>>> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>>> +        if (obj != null) {
>>>> +            // this method will transform the legacy enabled as well
>>>> +            return getSchemaValidationType(obj);
>>>> +        } else {
>>>> +            return null;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    private static SchemaValidationType
>>> getSchemaValidationTypeFromModel(Message message) {
>>>> +        boolean isRequestor = MessageUtils.isRequestor(message);
>>>> +        Exchange exchange = message.getExchange();
>>>> +
>>>> +        if (exchange != null) {
>>>> +            BindingOperationInfo boi =
>>> exchange.getBindingOperationInfo();
>>>> +            Endpoint endpoint = exchange.getEndpoint();
>>>> +
>>>> +            if (boi != null && endpoint != null) {
>>>> +                SchemaValidationType validationType = null;
>>>> +                OperationInfo opInfo = boi.getOperationInfo();
>>>> +                EndpointInfo ep = endpoint.getEndpointInfo();
>>>> +
>>>> +                if (validationType == null && opInfo != null) {
>>>> +                    validationType =
>>> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
>>>> +
>>>> +                    if (validationType == null && ep != null) {
>>>> +                        validationType =
>>> getSchemaValidationTypeFromModel(message, ep, isRequestor);
>>>> +                    }
>>>> +                }
>>>> +
>>>> +                return validationType;
>>>> +            }
>>>> +        }
>>>> +
>>>> +        // else
>>>> +        return null;
>>>> +    }
>>>> +
>>>> +    private static SchemaValidationType
>>> getSchemaValidationTypeFromModel(
>>>> +            Message message, AbstractPropertiesHolder properties,
>>> boolean isRequestor) {
>>>> +        Object obj =
>>> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
>>>> +        if (obj != null) {
>>>> +            SchemaValidationType validationType =
>>> getSchemaValidationType(obj);
>>>> +
>>>> +            // Reverse the direction of any IN / OUT for requestor
>>> (client)
>>>> +            if (isRequestor) {
>>>> +                if (SchemaValidationType.IN.equals(validationType)) {
>>>> +                    return SchemaValidationType.OUT;
>>>> +                } else if
>>> (SchemaValidationType.OUT.equals(validationType)) {
>>>> +                    return SchemaValidationType.IN;
>>>> +                }
>>>> +            }
>>>> +
>>>> +            return validationType;
>>>> +        } else {
>>>> +            return null;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public static SchemaValidationType getSchemaValidationType(Object
>>> obj) {
>>>>        if (obj instanceof SchemaValidationType) {
>>>>            return (SchemaValidationType)obj;
>>>>        } else if (obj != null) {
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>> index c47417a..ec8cf71 100644
>>>> ---
>>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>> +++
>>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>>>> @@ -125,24 +125,9 @@ public abstract class
>>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>>>>        }
>>>>    }
>>>> 
>>>> -    /**
>>>> -     * Where an operation level validation type has been set, copy it
>>> to the message, so it can be interrogated
>>>> -     * by all downstream interceptors.  It is expected that sub
>>> classes will call setDataReaderValidation subsequent
>>>> -     * to this to ensure the DataReader schema reference is updated as
>>> appropriate.
>>>> -     *
>>>> -     * @param bop
>>>> -     * @param message
>>>> -     * @param reader
>>>> -     * @see #setDataReaderValidation(Service, Message, DataReader)
>>>> -     */
>>>> -    protected void setOperationSchemaValidation(OperationInfo opInfo,
>>> Message message) {
>>>> -        if (opInfo != null) {
>>>> -            SchemaValidationType validationType =
>>>> -                (SchemaValidationType)
>>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>>> -            if (validationType != null) {
>>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>>> validationType);
>>>> -            }
>>>> -        }
>>>> +    protected void setOperationSchemaValidation(Message message) {
>>>> +        SchemaValidationType validationType =
>>> ServiceUtils.getSchemaValidationType(message);
>>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
>>>>    }
>>>> 
>>>>    protected DepthXMLStreamReader getXMLStreamReader(Message message) {
>>>> @@ -247,7 +232,7 @@ public abstract class
>>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>>>>        }
>>>> 
>>>>        // configure endpoint and operation level schema validation
>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>>> message);
>>>> +        setOperationSchemaValidation(message);
>>>> 
>>>>        QName serviceQName = si.getName();
>>>>        message.put(Message.WSDL_SERVICE, serviceQName);
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>> index db3ba6c..52d1cb1 100644
>>>> ---
>>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>> +++
>>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>>>> @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
>>>> import org.apache.cxf.service.model.BindingInfo;
>>>> import org.apache.cxf.service.model.BindingOperationInfo;
>>>> import org.apache.cxf.service.model.MessagePartInfo;
>>>> -import org.apache.cxf.service.model.OperationInfo;
>>>> import org.apache.cxf.staxutils.CachingXmlEventWriter;
>>>> import org.apache.cxf.staxutils.StaxUtils;
>>>> import org.apache.cxf.wsdl.EndpointReferenceUtils;
>>>> @@ -85,7 +84,7 @@ public abstract class
>>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>>>>        CachingXmlEventWriter cache = null;
>>>> 
>>>>        // configure endpoint and operation level schema validation
>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>>> message);
>>>> +        setOperationSchemaValidation(message);
>>>> 
>>>>        // need to cache the events in case validation fails or
>>> buffering is enabled
>>>>        if (shouldBuffer(message)) {
>>>> @@ -159,22 +158,9 @@ public abstract class
>>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>>>>        }
>>>>    }
>>>> 
>>>> -    /**
>>>> -     * Where an operation level validation type has been set, copy it
>>> to the message, so it can be interrogated
>>>> -     * by all downstream interceptors
>>>> -     *
>>>> -     * @param bop
>>>> -     * @param message
>>>> -     * @param reader
>>>> -     */
>>>> -    private void setOperationSchemaValidation(OperationInfo opInfo,
>>> Message message) {
>>>> -        if (opInfo != null) {
>>>> -            SchemaValidationType validationType =
>>>> -                (SchemaValidationType)
>>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>>>> -            if (validationType != null) {
>>>> -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>>> validationType);
>>>> -            }
>>>> -        }
>>>> +    protected void setOperationSchemaValidation(Message message) {
>>>> +        SchemaValidationType validationType =
>>> ServiceUtils.getSchemaValidationType(message);
>>>> +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
>>>>    }
>>>> 
>>>>    protected boolean shouldValidate(Message m) {
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
>>>> ----------------------------------------------------------------------
>>>> diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
>>> b/api/src/main/java/org/apache/cxf/message/Message.java
>>>> index 35e94af..5854a18 100644
>>>> --- a/api/src/main/java/org/apache/cxf/message/Message.java
>>>> +++ b/api/src/main/java/org/apache/cxf/message/Message.java
>>>> @@ -105,7 +105,16 @@ public interface Message extends StringMap {
>>>>     */
>>>>    String MTOM_ENABLED = "mtom-enabled";
>>>>    String MTOM_THRESHOLD = "mtom-threshold";
>>>> +
>>>> +    /**
>>>> +     * Runtime schema validation property
>>>> +     */
>>>>    String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
>>>> +
>>>> +    /**
>>>> +     * The default values for schema validation will be set in the
>>> service model using this property
>>>> +     */
>>>> +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
>>>> 
>>>>    /**
>>>>     * Boolean property specifying if the Java stack trace is returned
>>> as a
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>> index fafd0a9..d49f090 100644
>>>> ---
>>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>> +++
>>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>>>> @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
>>> AbstractInDatabindingInterceptor {
>>>>        message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
>>>> 
>>>>        // configure endpoint and operation level schema validation
>>>> -        setOperationSchemaValidation(operation.getOperationInfo(),
>>> message);
>>>> +        setOperationSchemaValidation(message);
>>>>    }
>>>> }
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>> index 7100f2c..9a7cbc8 100644
>>>> ---
>>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>> +++
>>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>>>> @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
>>> implements FactoryBeanListener {
>>>>            // if someone has gone to the effort of specifying
>>> enabled=false, then we need to
>>>>            // handle that, otherwise we use the new
>>> SchemaValidationType type only
>>>>            if (!annotation.enabled()) {
>>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>>> SchemaValidationType.NONE);
>>>> +
>>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>>> SchemaValidationType.NONE);
>>>>            } else {
>>>> -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>>> annotation.type());
>>>> +
>>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>>> annotation.type());
>>>>            }
>>>>        }
>>>>    }
>>>> @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
>>> implements FactoryBeanListener {
>>>>    }
>>>> 
>>>>    private void addSchemaValidationSupport(OperationInfo inf,
>>> SchemaValidation annotation) {
>>>> -        // Notice no support for deprecated enabled property here!
>>>> -        // TODO - should we check for the use of this property and at
>>> least log the fact we are
>>>> -        // ignoring it
>>>>        if (annotation != null) {
>>>> -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>>> annotation.type());
>>>> +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
>>> annotation.type());
>>>>        }
>>>>    }
>>>> 
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>> index 888e5a8..9f08839 100644
>>>> ---
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>> +++
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>>>> @@ -20,12 +20,15 @@
>>>> package org.apache.cxf.systest.jaxws.schemavalidation;
>>>> 
>>>> import java.io.IOException;
>>>> +import java.io.PrintWriter;
>>>> +import java.io.StringWriter;
>>>> import java.util.ArrayList;
>>>> import java.util.Arrays;
>>>> import java.util.HashMap;
>>>> import java.util.List;
>>>> import java.util.Map;
>>>> 
>>>> +import javax.xml.ws.WebServiceException;
>>>> import javax.xml.ws.soap.SOAPFaultException;
>>>> 
>>>> import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>>> @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
>>>> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
>>>> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
>>>> import org.apache.cxf.message.Message;
>>>> -import org.apache.cxf.service.model.BindingOperationInfo;
>>>> import org.apache.cxf.testutil.common.TestUtil;
>>>> +import org.apache.cxf.transport.http.HTTPConduit;
>>>> +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
>>>> import org.junit.AfterClass;
>>>> import org.junit.Assert;
>>>> import org.junit.BeforeClass;
>>>> import org.junit.Test;
>>>> 
>>>> -/**
>>>> - * TODO - test where the default is NONE at the service level test
>>> where the default is IN or OUT, and then
>>>> - * override at operation levels
>>>> - */
>>>> public class JavaFirstSchemaValidationTest extends Assert {
>>>> -    static final String PORT =
>>> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
>>>> +    static final String PORT =
>>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>>>> +    static final String PORT_UNUSED =
>>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>>>> 
>>>>    private static List<Server> serverList = new ArrayList<Server>();
>>>>    private static PersonServiceAnnotated annotatedClient;
>>>> +    private static PersonServiceAnnotated annotatedValidatingClient;
>>>>    private static PersonService client;
>>>>    private static PersonServiceRPC rpcClient;
>>>> +
>>>> +    private static PersonService disconnectedClient;
>>>> 
>>>>    @BeforeClass
>>>>    public static void startServers() throws Exception {
>>>> @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends
>>> Assert {
>>>> 
>>>>        createServer(PersonServiceRPC.class, new
>>> PersonServiceRPCImpl(), feature, new LoggingFeature());
>>>> 
>>>> -        annotatedClient = createClient(PersonServiceAnnotated.class);
>>>> -        client = createClient(PersonService.class);
>>>> -        rpcClient = createClient(PersonServiceRPC.class);
>>>> +        annotatedClient = createClient(PORT,
>>> PersonServiceAnnotated.class, SchemaValidationType.NONE);
>>>> +        annotatedValidatingClient = createClient(PORT,
>>> PersonServiceAnnotated.class, null);
>>>> +        client = createClient(PORT, PersonService.class,
>>> SchemaValidationType.NONE);
>>>> +        disconnectedClient = createClient(PORT_UNUSED,
>>> PersonService.class, SchemaValidationType.OUT);
>>>> +        rpcClient = createClient(PORT, PersonServiceRPC.class,
>>> SchemaValidationType.NONE);
>>>>    }
>>>> 
>>>>    @AfterClass
>>>> @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends
>>> Assert {
>>>>        }
>>>>    }
>>>> 
>>>> -    static String getAddress(Class<?> sei) {
>>>> -        return "http://localhost:" + PORT + "/" + sei.getSimpleName();
>>>> +    static String getAddress(String port, Class<?> sei) {
>>>> +        return "http://localhost:" + port + "/" + sei.getSimpleName();
>>>>    }
>>>> -
>>>> 
>>>>    @Test
>>>>    public void testRPCLit() throws Exception {
>>>> @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest extends
>>> Assert {
>>>>        try {
>>>>            person.setFirstName(null);
>>>>            rpcClient.saveValidateOut(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>>            assertTrue(sfe.getMessage().contains("Marshalling Error"));
>>>>            assertTrue(sfe.getMessage().contains("lastName"));
>>>>        }
>>>> @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest
>>> extends Assert {
>>>> 
>>>>        try {
>>>>            annotatedClient.saveInheritEndpoint(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>> Error"));
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>        }
>>>> 
>>>>        try {
>>>>            person.setFirstName(""); // empty string is valid
>>>>            annotatedClient.saveInheritEndpoint(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>> Error"));
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>        }
>>>> 
>>>>        person.setLastName(""); // empty string is valid
>>>>        annotatedClient.saveInheritEndpoint(person);
>>>>    }
>>>> -
>>>> +
>>>>    @Test
>>>>    public void testSaveValidateInAnnotated() {
>>>>        Person person = new Person();
>>>> 
>>>>        try {
>>>>            annotatedClient.saveValidateIn(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>> Error"));
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>        }
>>>> 
>>>>        try {
>>>>            person.setFirstName(""); // empty string is valid
>>>>            annotatedClient.saveValidateIn(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>> Error"));
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>        }
>>>> 
>>>>        person.setLastName(""); // empty string is valid
>>>> @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
>>> extends Assert {
>>>>        annotatedClient.saveNoValidation(person);
>>>>    }
>>>> 
>>>> -    // no validation is required for incoming
>>>>    @Test
>>>> -    public void testSaveValidationOutAnnotated() {
>>>> +    public void
>>> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
>>>>        Person person = new Person();
>>>> 
>>>> -        annotatedClient.saveValidateOut(person);
>>>> +        try {
>>>> +            annotatedClient.saveValidateOut(person);
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            // verify its server side and a schema validation
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>>> +            // it's still a server side fault, because server side
>>> validation coming in failed
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>> +
>>>> +        person.setFirstName(""); // empty string is valid
>>>> +        try {
>>>> +            annotatedClient.saveValidateOut(person);
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            // verify its server side and a schema validation
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>>> +            // it's still a server side fault, because server side
>>> validation coming in failed
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>> 
>>>> +        person.setLastName(""); // empty string is valid
>>>> +        annotatedClient.saveValidateIn(person);
>>>> +    }
>>>> +
>>>> +    // this will still all be server side, as the OUT validation is
>>> turned into an IN validation for
>>>> +    // the client, but by then the server has already thrown the
>>> exception for the OUT
>>>> +    @Test
>>>> +    public void
>>> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
>>>> +        Person person = new Person();
>>>> +
>>>> +        try {
>>>> +            annotatedValidatingClient.saveValidateIn(person);
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>> +
>>>>        person.setFirstName(""); // empty string is valid
>>>> -        annotatedClient.saveValidateOut(person);
>>>> +        try {
>>>> +            annotatedValidatingClient.saveValidateIn(person);
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>> 
>>>>        person.setLastName(""); // empty string is valid
>>>> -        annotatedClient.saveValidateOut(person);
>>>> +        annotatedValidatingClient.saveValidateIn(person);
>>>> +    }
>>>> +
>>>> +    @Test
>>>> +    public void
>>> testSaveValidationInAnnotatedWithClientValidationEnabled() {
>>>> +        Person person = new Person();
>>>> +
>>>> +        try {
>>>> +            person.setFirstName("InvalidResponse");
>>>> +            person.setLastName("WhoCares");
>>>> +            annotatedValidatingClient.saveValidateOut(person);
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>>    }
>>>> 
>>>> -    // so this is the default, we are inheriting from the service
>>> level SchemaValidation annotation
>>>> -    // which is set to BOTH
>>>>    @Test
>>>>    public void testEndpointSchemaValidationProvider() {
>>>>        Person person = new Person();
>>>> 
>>>>        try {
>>>>            client.saveInheritEndpoint(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>> Error"));
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>        }
>>>> -
>>>> +
>>>>        try {
>>>>            person.setFirstName(""); // empty string is valid
>>>>            client.saveInheritEndpoint(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>> Error"));
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>        }
>>>> 
>>>>        person.setLastName(""); // empty string is valid
>>>> @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest
>>> extends Assert {
>>>> 
>>>>        try {
>>>>            client.saveValidateIn(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>> Error"));
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>        }
>>>> 
>>>>        try {
>>>>            person.setFirstName(""); // empty string is valid
>>>>            client.saveValidateIn(person);
>>>> +            fail("Expected exception");
>>>>        } catch (SOAPFaultException sfe) {
>>>> -            // verify its server side and a schema validation
>>>> -            assertTrue(sfe.getMessage().contains("Unmarshalling
>>> Error"));
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>>        }
>>>> 
>>>>        person.setLastName(""); // empty string is valid
>>>>        client.saveValidateIn(person);
>>>>    }
>>>> 
>>>> -    // no validation at all is required
>>>>    @Test
>>>>    public void testSaveNoValidationProvider() {
>>>>        Person person = new Person();
>>>> @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest
>>> extends Assert {
>>>>        client.saveNoValidation(person);
>>>>    }
>>>> 
>>>> -    // no validation is required for incoming
>>>>    @Test
>>>> -    public void testSaveValidationOutProvider() {
>>>> +    public void testSaveValidationOutProviderClientOnly() {
>>>>        Person person = new Person();
>>>> 
>>>> -        client.saveValidateOut(person);
>>>> +        try {
>>>> +            disconnectedClient.saveValidateOut(person);
>>>> +            fail("Expected exception");
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            // verify its client side outgoing
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>> +
>>>> +        person.setFirstName(""); // empty string is valid
>>>> +        try {
>>>> +            disconnectedClient.saveValidateOut(person);
>>>> +            fail("Expected exception");
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            // verify its client side outgoing
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>> +
>>>> +        person.setLastName(""); // empty string is valid
>>>> +
>>>> +        // this confirms that we passed client validation as we then
>>> got the connectivity error
>>>> +        try {
>>>> +            disconnectedClient.saveValidateOut(person);
>>>> +            fail("Expected exception");
>>>> +        } catch (WebServiceException e) {
>>>> +            assertTrue(e.getMessage().contains("Could not send
>>> Message"));
>>>> +        }
>>>> +    }
>>>> 
>>>> +
>>>> +    @Test
>>>> +    public void testSaveValidationOutProvider() {
>>>> +        Person person = new Person();
>>>> +
>>>> +        try {
>>>> +            client.saveValidateOut(person);
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            // verify its server side outgoing
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>> +
>>>>        person.setFirstName(""); // empty string is valid
>>>> -        client.saveValidateOut(person);
>>>> +        try {
>>>> +            client.saveValidateOut(person);
>>>> +        } catch (SOAPFaultException sfe) {
>>>> +            // verify its server side outgoing
>>>> +            String stackTrace = getStackTrace(sfe);
>>>> +            assertTrue(stackTrace.contains("Marshalling Error"));
>>>> +
>>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>>>> +        }
>>>> 
>>>>        person.setLastName(""); // empty string is valid
>>>>        client.saveValidateOut(person);
>>>>    }
>>>> 
>>>> -    private static <T> T createClient(Class<T> serviceClass) {
>>>> +    private static <T> T createClient(String port, Class<T>
>>> serviceClass, SchemaValidationType type) {
>>>>        JaxWsProxyFactoryBean clientFactory = new
>>> JaxWsProxyFactoryBean();
>>>>        clientFactory.setServiceClass(serviceClass);
>>>> -
>>>> -        // ensure all client schema validation is disabled
>>>> -        Map<String, Object> properties = new HashMap<String, Object>();
>>>> -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
>>> SchemaValidationType.NONE);
>>>> -        clientFactory.setProperties(properties);
>>>> -
>>>> -        clientFactory.setAddress(getAddress(serviceClass));
>>>> -
>>>> +
>>>> +
>>>> +        clientFactory.setAddress(getAddress(port, serviceClass));
>>>> +
>>>> +
>>>>        @SuppressWarnings("unchecked")
>>>>        T newClient = (T)clientFactory.create();
>>>> 
>>>> -        Client clientProxy = ClientProxy.getClient(newClient);
>>>> -
>>>> -        // ensure all client schema validation is disabled
>>>> -        for (BindingOperationInfo bop :
>>> clientProxy.getEndpoint().getEndpointInfo().getBinding()
>>>> -            .getOperations()) {
>>>> -
>>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>>> SchemaValidationType.NONE);
>>>> +        Client proxy = ClientProxy.getClient(newClient);
>>>> +
>>>> +        if (type != null) {
>>>> +
>>> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED, type);
>>>>        }
>>>> -
>>>> +
>>>> +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
>>>> +        // give me longer debug times
>>>> +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
>>>> +        clientPolicy.setConnectionTimeout(1000000);
>>>> +        clientPolicy.setReceiveTimeout(1000000);
>>>> +        conduit.setClient(clientPolicy);
>>>> +
>>>>        return newClient;
>>>>    }
>>>> 
>>>> @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest
>>> extends Assert {
>>>>        if (features != null) {
>>>>            svrFactory.getFeatures().addAll(Arrays.asList(features));
>>>>        }
>>>> -        svrFactory.setAddress(getAddress(serviceInterface));
>>>> +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
>>>>        svrFactory.setServiceBean(serviceImpl);
>>>>        Server server = svrFactory.create();
>>>>        serverList.add(server);
>>>>        return server;
>>>>    }
>>>> +
>>>> +    private String getStackTrace(Exception e) {
>>>> +        StringWriter sWriter = new StringWriter();
>>>> +        PrintWriter writer = new PrintWriter(sWriter, true);
>>>> +        e.printStackTrace(writer);
>>>> +        return sWriter.toString();
>>>> +    }
>>>> }
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>> index e3ee10c..d594e4e 100644
>>>> ---
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>> +++
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>>>> @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
>>>> 
>>>> import javax.jws.WebMethod;
>>>> import javax.jws.WebParam;
>>>> +import javax.jws.WebResult;
>>>> import javax.jws.WebService;
>>>> 
>>>> import org.apache.cxf.annotations.SchemaValidation;
>>>> @@ -30,14 +31,18 @@ import
>>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>>> @SchemaValidation(type = SchemaValidationType.BOTH)
>>>> public interface PersonService {
>>>>    @WebMethod(operationName = "saveInheritEndpoint")
>>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>>> +    @WebResult(name = "Person")
>>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>>> 
>>>>    @WebMethod(operationName = "saveNoValidation")
>>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
>>>> +    @WebResult(name = "Person")
>>>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
>>>> 
>>>>    @WebMethod(operationName = "saveValidateIn")
>>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
>>>> +    @WebResult(name = "Person")
>>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>>>> 
>>>>    @WebMethod(operationName = "saveValidateOut")
>>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
>>>> +    @WebResult(name = "Person")
>>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>>>> }
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>> index 3e06576..a760f27 100644
>>>> ---
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>> +++
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>>>> @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
>>>> 
>>>> import javax.jws.WebMethod;
>>>> import javax.jws.WebParam;
>>>> +import javax.jws.WebResult;
>>>> import javax.jws.WebService;
>>>> 
>>>> import org.apache.cxf.annotations.SchemaValidation;
>>>> @@ -30,17 +31,21 @@ import
>>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>>>> @SchemaValidation(type = SchemaValidationType.BOTH)
>>>> public interface PersonServiceAnnotated {
>>>>    @WebMethod(operationName = "saveInheritEndpoint")
>>>> -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>>> +    @WebResult(name = "Person")
>>>> +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
>>>> 
>>>>    @SchemaValidation(type = SchemaValidationType.NONE)
>>>>    @WebMethod(operationName = "saveNoValidation")
>>>> -    void saveNoValidation(@WebParam(name = "Person") Person data);
>>>> +    @WebResult(name = "Person")
>>>> +    Person saveNoValidation(@WebParam(name = "Person") Person data);
>>>> 
>>>>    @SchemaValidation(type = SchemaValidationType.IN)
>>>>    @WebMethod(operationName = "saveValidateIn")
>>>> -    void saveValidateIn(@WebParam(name = "Person") Person data);
>>>> +    @WebResult(name = "Person")
>>>> +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>>>> 
>>>>    @SchemaValidation(type = SchemaValidationType.OUT)
>>>>    @WebMethod(operationName = "saveValidateOut")
>>>> -    void saveValidateOut(@WebParam(name = "Person") Person data);
>>>> +    @WebResult(name = "Person")
>>>> +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>>>> }
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>> index c7b8038..78973c9 100644
>>>> ---
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>> +++
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>>>> @@ -26,18 +26,25 @@ import javax.jws.WebService;
>>>>    targetNamespace = "
>>> http://org.apache.cxf/service/PersonServiceAnnotated")
>>>> public class PersonServiceAnnotatedImpl implements
>>> PersonServiceAnnotated {
>>>>    @Override
>>>> -    public void saveNoValidation(Person data) {
>>>> +    public Person saveNoValidation(Person data) {
>>>> +        return data;
>>>>    }
>>>> 
>>>>    @Override
>>>> -    public void saveInheritEndpoint(Person data) {
>>>> +    public Person saveInheritEndpoint(Person data) {
>>>> +        return data;
>>>>    }
>>>> 
>>>>    @Override
>>>> -    public void saveValidateIn(Person data) {
>>>> +    public Person saveValidateIn(Person data) {
>>>> +        if ("InvalidResponse".equals(data.getFirstName())) {
>>>> +            return new Person();
>>>> +        }
>>>> +        return data;
>>>>    }
>>>> 
>>>>    @Override
>>>> -    public void saveValidateOut(Person data) {
>>>> +    public Person saveValidateOut(Person data) {
>>>> +        return data;
>>>>    }
>>>> }
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>> index fe1d656..9edec45 100644
>>>> ---
>>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>> +++
>>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>>>> @@ -26,18 +26,22 @@ import javax.jws.WebService;
>>>>    targetNamespace = "http://org.apache.cxf/service/PersonService")
>>>> public class PersonServiceImpl implements PersonService {
>>>>    @Override
>>>> -    public void saveNoValidation(Person data) {
>>>> +    public Person saveNoValidation(Person data) {
>>>> +        return data;
>>>>    }
>>>> 
>>>>    @Override
>>>> -    public void saveInheritEndpoint(Person data) {
>>>> +    public Person saveInheritEndpoint(Person data) {
>>>> +        return data;
>>>>    }
>>>> 
>>>>    @Override
>>>> -    public void saveValidateIn(Person data) {
>>>> +    public Person saveValidateIn(Person data) {
>>>> +        return data;
>>>>    }
>>>> 
>>>>    @Override
>>>> -    public void saveValidateOut(Person data) {
>>>> +    public Person saveValidateOut(Person data) {
>>>> +        return data;
>>>>    }
>>>> }
>>>> 
>>>> 
>>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>>> deleted file mode 100644
>>>> index 18e66ae..0000000
>>>> ---
>>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>>>> +++ /dev/null
>>>> @@ -1,69 +0,0 @@
>>>> -/**
>>>> - * Licensed to the Apache Software Foundation (ASF) under one
>>>> - * or more contributor license agreements. See the NOTICE file
>>>> - * distributed with this work for additional information
>>>> - * regarding copyright ownership. The ASF licenses this file
>>>> - * to you 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.cxf.systest.mtom_schema_validation;
>>>> -
>>>> -import java.io.File;
>>>> -import java.net.URL;
>>>> -
>>>> -import javax.activation.DataHandler;
>>>> -import javax.activation.FileDataSource;
>>>> -import javax.xml.namespace.QName;
>>>> -import javax.xml.ws.soap.MTOMFeature;
>>>> -
>>>> -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
>>>> -
>>>> -import org.junit.BeforeClass;
>>>> -import org.junit.Test;
>>>> -
>>>> -public final class MTOMProviderSchemaValidationTest extends
>>> AbstractBusClientServerTestBase {
>>>> -    public static final String PORT = "9001";
>>>> -        //Server.PORT;
>>>> -
>>>> -    private final QName serviceName = new QName("
>>> http://cxf.apache.org/", "HelloWS");
>>>> -
>>>> -    @BeforeClass
>>>> -    public static void startservers() throws Exception {
>>>> -        //assertTrue("server did not launch correctly",
>>> launchServer(Server.class, true));
>>>> -    }
>>>> -    @Test
>>>> -    public void testSchemaValidation() throws Exception {
>>>> -        HelloWS port = createService();
>>>> -        Hello request = new Hello();
>>>> -        request.setArg0("value");
>>>> -        URL wsdl =
>>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>>>> -        File attachment = new File(wsdl.getFile());
>>>> -        request.setFile(new DataHandler(new
>>> FileDataSource(attachment)));
>>>> -        HelloResponse response = port.hello(request);
>>>> -        assertEquals("Hello CXF", response.getReturn());
>>>> -    }
>>>> -
>>>> -    private HelloWS createService() throws Exception {
>>>> -        URL wsdl =
>>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>>>> -        assertNotNull(wsdl);
>>>> -
>>>> -        HelloWSClient service = new HelloWSClient(wsdl, serviceName);
>>>> -        assertNotNull(service);
>>>> -
>>>> -        HelloWS port = service.getHello(new MTOMFeature());
>>>> -
>>>> -        updateAddressPort(port, PORT);
>>>> -
>>>> -        return port;
>>>> -    }
>>>> -}
>>>> 
>>> 
>>> --
>>> Daniel Kulp
>>> dkulp@apache.org - http://dankulp.com/blog
>>> Talend Community Coder - http://coders.talend.com
>>> 
>>> 

-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com


Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Jason Pell <ja...@pellcorp.com>.
I will add the property anyway as it occurs to me this would be a problem
for anyone who has defined a client specific sei and already reversed the
directions.

Unless you want me to remove the client reverse direction code completely I
will get the property and any test changes committed this weekend.
On 29/11/2014 2:11 PM, "Jason Pell" <jp...@apache.org> wrote:

> Its only reversing what's coming from the model. If you define IN in the
> jaxws properties on the client it will continue to validate IN on the
> client as before.
>
> If I have IN defined for a operation using an annotation the old code
> would actually validate the response coming back to the client. This does
> seem counter intuitive especially as IN might have been specified because
> the response may be incomplete and so can't be validated.
>
> An IN for service is the OUT for client.
>
> The previous code was just plain wrong for client side - my code by the
> way :-)
>
> This particular piece is only a few lines in ServiceUtils so I am happy to
> remove it if you are still -1
>
> The alternative is I will add a property to enable it but only if the
> property is used.
>
> Would that be OK?
> On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:
>
>>
>> I’m -1 on the part of this that changes the IN to an OUT on the client
>> side.   The IN and OUT are specifically named that way as they apply to the
>> messages that come IN to the client or IN to the server.   The “IN”
>> validation should definitely not be applying to the messages going OUT.
>> Plus, that would be a huge behavioral change that would break many peoples
>> existing applications.
>>
>> Dan
>>
>>
>>
>>
>> > On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
>> >
>> > Repository: cxf
>> > Updated Branches:
>> >  refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
>> >
>> >
>> > CXF-6118 support overriding schema validation at jaxws endpoint and
>> client level and applying the correct validation direction at client level
>> >
>> >
>> > Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
>> > Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
>> > Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
>> > Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
>> >
>> > Branch: refs/heads/2.7.x-fixes
>> > Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
>> > Parents: e172a3e
>> > Author: Jason Pell <jp...@apache.org>
>> > Authored: Thu Nov 27 16:54:01 2014 +1100
>> > Committer: Jason Pell <jp...@apache.org>
>> > Committed: Fri Nov 28 15:52:36 2014 +1100
>> >
>> > ----------------------------------------------------------------------
>> > .../validation/SchemaValidationFeature.java     |   2 +-
>> > .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
>> > .../AbstractInDatabindingInterceptor.java       |  23 +-
>> > .../AbstractOutDatabindingInterceptor.java      |  22 +-
>> > .../java/org/apache/cxf/message/Message.java    |   9 +
>> > .../soap/interceptor/RPCInInterceptor.java      |   2 +-
>> > .../factory/AnnotationsFactoryBeanListener.java |   9 +-
>> > .../JavaFirstSchemaValidationTest.java          | 256
>> ++++++++++++++-----
>> > .../jaxws/schemavalidation/PersonService.java   |  13 +-
>> > .../PersonServiceAnnotated.java                 |  13 +-
>> > .../PersonServiceAnnotatedImpl.java             |  15 +-
>> > .../schemavalidation/PersonServiceImpl.java     |  12 +-
>> > .../MTOMProviderSchemaValidationTest.bak        |  69 -----
>> > 13 files changed, 342 insertions(+), 201 deletions(-)
>> > ----------------------------------------------------------------------
>> >
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> > index 5eda79c..c314eaf 100644
>> > ---
>> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> > +++
>> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
>> > @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
>> AbstractFeature {
>> >         for (BindingOperationInfo bop :
>> endpoint.getEndpointInfo().getBinding().getOperations()) {
>> >             SchemaValidationType type =
>> provider.getSchemaValidationType(bop.getOperationInfo());
>> >             if (type != null) {
>> > -
>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED, type);
>> > +
>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE, type);
>> >             }
>> >         }
>> >     }
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> > ----------------------------------------------------------------------
>> > diff --git a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> > index 85d77d0..28c7ba2 100644
>> > --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> > +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
>> > @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
>> > import javax.xml.namespace.QName;
>> >
>> > import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>> > +import org.apache.cxf.endpoint.Endpoint;
>> > +import org.apache.cxf.message.Exchange;
>> > import org.apache.cxf.message.Message;
>> > +import org.apache.cxf.message.MessageUtils;
>> > +import org.apache.cxf.service.model.AbstractPropertiesHolder;
>> > +import org.apache.cxf.service.model.BindingOperationInfo;
>> > +import org.apache.cxf.service.model.EndpointInfo;
>> > +import org.apache.cxf.service.model.OperationInfo;
>> >
>> > public final class ServiceUtils {
>> > -
>> >     private ServiceUtils() {
>> >     }
>> >
>> > @@ -42,24 +48,94 @@ public final class ServiceUtils {
>> >      * @param type
>> >      */
>> >     public static boolean
>> isSchemaValidationEnabled(SchemaValidationType type, Message message) {
>> > -        SchemaValidationType messageType =
>> getSchemaValidationType(message);
>> > +        SchemaValidationType validationType =
>> getSchemaValidationType(message);
>> >
>> > -        return messageType.equals(type)
>> > +        return validationType.equals(type)
>> >             || ((SchemaValidationType.IN.equals(type) ||
>> SchemaValidationType.OUT.equals(type))
>> > -                && SchemaValidationType.BOTH.equals(messageType));
>> > +                && SchemaValidationType.BOTH.equals(validationType));
>> >     }
>> > -
>> > +
>> >     /**
>> > -     * Determines the appropriate SchemaValidationType to return based
>> on either
>> > -     * a Boolean (for backwards compatibility) or the selected Schema
>> Validation Type.
>> > -     *
>> > -     * Package private as the isSchemaValidationEnabled method should
>> be used instead.  Only
>> > -     * visible for easier testing
>> > +     * A convenience method to check for schema validation config in
>> the message context, and then in the service model.
>> > +     * Does not modify the Message context (other than what is done in
>> the getContextualProperty itself)
>> >      *
>> >      * @param message
>> > +     * @param type
>> >      */
>> > -    static SchemaValidationType getSchemaValidationType(Message
>> message) {
>> > +    public static SchemaValidationType getSchemaValidationType(Message
>> message) {
>> > +        SchemaValidationType validationType =
>> getOverrideSchemaValidationType(message);
>> > +        if (validationType == null) {
>> > +            validationType = getSchemaValidationTypeFromModel(message);
>> > +        }
>> > +
>> > +        if (validationType == null) {
>> > +            validationType = SchemaValidationType.NONE;
>> > +        }
>> > +
>> > +        return validationType;
>> > +    }
>> > +
>> > +    private static SchemaValidationType
>> getOverrideSchemaValidationType(Message message) {
>> >         Object obj =
>> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
>> > +        if (obj != null) {
>> > +            // this method will transform the legacy enabled as well
>> > +            return getSchemaValidationType(obj);
>> > +        } else {
>> > +            return null;
>> > +        }
>> > +    }
>> > +
>> > +    private static SchemaValidationType
>> getSchemaValidationTypeFromModel(Message message) {
>> > +        boolean isRequestor = MessageUtils.isRequestor(message);
>> > +        Exchange exchange = message.getExchange();
>> > +
>> > +        if (exchange != null) {
>> > +            BindingOperationInfo boi =
>> exchange.getBindingOperationInfo();
>> > +            Endpoint endpoint = exchange.getEndpoint();
>> > +
>> > +            if (boi != null && endpoint != null) {
>> > +                SchemaValidationType validationType = null;
>> > +                OperationInfo opInfo = boi.getOperationInfo();
>> > +                EndpointInfo ep = endpoint.getEndpointInfo();
>> > +
>> > +                if (validationType == null && opInfo != null) {
>> > +                    validationType =
>> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
>> > +
>> > +                    if (validationType == null && ep != null) {
>> > +                        validationType =
>> getSchemaValidationTypeFromModel(message, ep, isRequestor);
>> > +                    }
>> > +                }
>> > +
>> > +                return validationType;
>> > +            }
>> > +        }
>> > +
>> > +        // else
>> > +        return null;
>> > +    }
>> > +
>> > +    private static SchemaValidationType
>> getSchemaValidationTypeFromModel(
>> > +            Message message, AbstractPropertiesHolder properties,
>> boolean isRequestor) {
>> > +        Object obj =
>> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
>> > +        if (obj != null) {
>> > +            SchemaValidationType validationType =
>> getSchemaValidationType(obj);
>> > +
>> > +            // Reverse the direction of any IN / OUT for requestor
>> (client)
>> > +            if (isRequestor) {
>> > +                if (SchemaValidationType.IN.equals(validationType)) {
>> > +                    return SchemaValidationType.OUT;
>> > +                } else if
>> (SchemaValidationType.OUT.equals(validationType)) {
>> > +                    return SchemaValidationType.IN;
>> > +                }
>> > +            }
>> > +
>> > +            return validationType;
>> > +        } else {
>> > +            return null;
>> > +        }
>> > +    }
>> > +
>> > +    public static SchemaValidationType getSchemaValidationType(Object
>> obj) {
>> >         if (obj instanceof SchemaValidationType) {
>> >             return (SchemaValidationType)obj;
>> >         } else if (obj != null) {
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> > index c47417a..ec8cf71 100644
>> > ---
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> > +++
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
>> > @@ -125,24 +125,9 @@ public abstract class
>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>> >         }
>> >     }
>> >
>> > -    /**
>> > -     * Where an operation level validation type has been set, copy it
>> to the message, so it can be interrogated
>> > -     * by all downstream interceptors.  It is expected that sub
>> classes will call setDataReaderValidation subsequent
>> > -     * to this to ensure the DataReader schema reference is updated as
>> appropriate.
>> > -     *
>> > -     * @param bop
>> > -     * @param message
>> > -     * @param reader
>> > -     * @see #setDataReaderValidation(Service, Message, DataReader)
>> > -     */
>> > -    protected void setOperationSchemaValidation(OperationInfo opInfo,
>> Message message) {
>> > -        if (opInfo != null) {
>> > -            SchemaValidationType validationType =
>> > -                (SchemaValidationType)
>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>> > -            if (validationType != null) {
>> > -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> validationType);
>> > -            }
>> > -        }
>> > +    protected void setOperationSchemaValidation(Message message) {
>> > +        SchemaValidationType validationType =
>> ServiceUtils.getSchemaValidationType(message);
>> > +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
>> >     }
>> >
>> >     protected DepthXMLStreamReader getXMLStreamReader(Message message) {
>> > @@ -247,7 +232,7 @@ public abstract class
>> AbstractInDatabindingInterceptor extends AbstractPhaseInte
>> >         }
>> >
>> >         // configure endpoint and operation level schema validation
>> > -        setOperationSchemaValidation(operation.getOperationInfo(),
>> message);
>> > +        setOperationSchemaValidation(message);
>> >
>> >         QName serviceQName = si.getName();
>> >         message.put(Message.WSDL_SERVICE, serviceQName);
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> > index db3ba6c..52d1cb1 100644
>> > ---
>> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> > +++
>> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
>> > @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
>> > import org.apache.cxf.service.model.BindingInfo;
>> > import org.apache.cxf.service.model.BindingOperationInfo;
>> > import org.apache.cxf.service.model.MessagePartInfo;
>> > -import org.apache.cxf.service.model.OperationInfo;
>> > import org.apache.cxf.staxutils.CachingXmlEventWriter;
>> > import org.apache.cxf.staxutils.StaxUtils;
>> > import org.apache.cxf.wsdl.EndpointReferenceUtils;
>> > @@ -85,7 +84,7 @@ public abstract class
>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>> >         CachingXmlEventWriter cache = null;
>> >
>> >         // configure endpoint and operation level schema validation
>> > -        setOperationSchemaValidation(operation.getOperationInfo(),
>> message);
>> > +        setOperationSchemaValidation(message);
>> >
>> >         // need to cache the events in case validation fails or
>> buffering is enabled
>> >         if (shouldBuffer(message)) {
>> > @@ -159,22 +158,9 @@ public abstract class
>> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
>> >         }
>> >     }
>> >
>> > -    /**
>> > -     * Where an operation level validation type has been set, copy it
>> to the message, so it can be interrogated
>> > -     * by all downstream interceptors
>> > -     *
>> > -     * @param bop
>> > -     * @param message
>> > -     * @param reader
>> > -     */
>> > -    private void setOperationSchemaValidation(OperationInfo opInfo,
>> Message message) {
>> > -        if (opInfo != null) {
>> > -            SchemaValidationType validationType =
>> > -                (SchemaValidationType)
>> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
>> > -            if (validationType != null) {
>> > -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
>> validationType);
>> > -            }
>> > -        }
>> > +    protected void setOperationSchemaValidation(Message message) {
>> > +        SchemaValidationType validationType =
>> ServiceUtils.getSchemaValidationType(message);
>> > +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
>> >     }
>> >
>> >     protected boolean shouldValidate(Message m) {
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
>> > ----------------------------------------------------------------------
>> > diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
>> b/api/src/main/java/org/apache/cxf/message/Message.java
>> > index 35e94af..5854a18 100644
>> > --- a/api/src/main/java/org/apache/cxf/message/Message.java
>> > +++ b/api/src/main/java/org/apache/cxf/message/Message.java
>> > @@ -105,7 +105,16 @@ public interface Message extends StringMap {
>> >      */
>> >     String MTOM_ENABLED = "mtom-enabled";
>> >     String MTOM_THRESHOLD = "mtom-threshold";
>> > +
>> > +    /**
>> > +     * Runtime schema validation property
>> > +     */
>> >     String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
>> > +
>> > +    /**
>> > +     * The default values for schema validation will be set in the
>> service model using this property
>> > +     */
>> > +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
>> >
>> >     /**
>> >      * Boolean property specifying if the Java stack trace is returned
>> as a
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> > index fafd0a9..d49f090 100644
>> > ---
>> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> > +++
>> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
>> > @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
>> AbstractInDatabindingInterceptor {
>> >         message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
>> >
>> >         // configure endpoint and operation level schema validation
>> > -        setOperationSchemaValidation(operation.getOperationInfo(),
>> message);
>> > +        setOperationSchemaValidation(message);
>> >     }
>> > }
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> > index 7100f2c..9a7cbc8 100644
>> > ---
>> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> > +++
>> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
>> > @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
>> implements FactoryBeanListener {
>> >             // if someone has gone to the effort of specifying
>> enabled=false, then we need to
>> >             // handle that, otherwise we use the new
>> SchemaValidationType type only
>> >             if (!annotation.enabled()) {
>> > -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>> SchemaValidationType.NONE);
>> > +
>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> SchemaValidationType.NONE);
>> >             } else {
>> > -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
>> annotation.type());
>> > +
>> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> annotation.type());
>> >             }
>> >         }
>> >     }
>> > @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
>> implements FactoryBeanListener {
>> >     }
>> >
>> >     private void addSchemaValidationSupport(OperationInfo inf,
>> SchemaValidation annotation) {
>> > -        // Notice no support for deprecated enabled property here!
>> > -        // TODO - should we check for the use of this property and at
>> least log the fact we are
>> > -        // ignoring it
>> >         if (annotation != null) {
>> > -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>> annotation.type());
>> > +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
>> annotation.type());
>> >         }
>> >     }
>> >
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> > index 888e5a8..9f08839 100644
>> > ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> > +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
>> > @@ -20,12 +20,15 @@
>> > package org.apache.cxf.systest.jaxws.schemavalidation;
>> >
>> > import java.io.IOException;
>> > +import java.io.PrintWriter;
>> > +import java.io.StringWriter;
>> > import java.util.ArrayList;
>> > import java.util.Arrays;
>> > import java.util.HashMap;
>> > import java.util.List;
>> > import java.util.Map;
>> >
>> > +import javax.xml.ws.WebServiceException;
>> > import javax.xml.ws.soap.SOAPFaultException;
>> >
>> > import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>> > @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
>> > import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
>> > import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
>> > import org.apache.cxf.message.Message;
>> > -import org.apache.cxf.service.model.BindingOperationInfo;
>> > import org.apache.cxf.testutil.common.TestUtil;
>> > +import org.apache.cxf.transport.http.HTTPConduit;
>> > +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
>> > import org.junit.AfterClass;
>> > import org.junit.Assert;
>> > import org.junit.BeforeClass;
>> > import org.junit.Test;
>> >
>> > -/**
>> > - * TODO - test where the default is NONE at the service level test
>> where the default is IN or OUT, and then
>> > - * override at operation levels
>> > - */
>> > public class JavaFirstSchemaValidationTest extends Assert {
>> > -    static final String PORT =
>> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
>> > +    static final String PORT =
>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>> > +    static final String PORT_UNUSED =
>> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
>> >
>> >     private static List<Server> serverList = new ArrayList<Server>();
>> >     private static PersonServiceAnnotated annotatedClient;
>> > +    private static PersonServiceAnnotated annotatedValidatingClient;
>> >     private static PersonService client;
>> >     private static PersonServiceRPC rpcClient;
>> > +
>> > +    private static PersonService disconnectedClient;
>> >
>> >     @BeforeClass
>> >     public static void startServers() throws Exception {
>> > @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>> >
>> >         createServer(PersonServiceRPC.class, new
>> PersonServiceRPCImpl(), feature, new LoggingFeature());
>> >
>> > -        annotatedClient = createClient(PersonServiceAnnotated.class);
>> > -        client = createClient(PersonService.class);
>> > -        rpcClient = createClient(PersonServiceRPC.class);
>> > +        annotatedClient = createClient(PORT,
>> PersonServiceAnnotated.class, SchemaValidationType.NONE);
>> > +        annotatedValidatingClient = createClient(PORT,
>> PersonServiceAnnotated.class, null);
>> > +        client = createClient(PORT, PersonService.class,
>> SchemaValidationType.NONE);
>> > +        disconnectedClient = createClient(PORT_UNUSED,
>> PersonService.class, SchemaValidationType.OUT);
>> > +        rpcClient = createClient(PORT, PersonServiceRPC.class,
>> SchemaValidationType.NONE);
>> >     }
>> >
>> >     @AfterClass
>> > @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>> >         }
>> >     }
>> >
>> > -    static String getAddress(Class<?> sei) {
>> > -        return "http://localhost:" + PORT + "/" + sei.getSimpleName();
>> > +    static String getAddress(String port, Class<?> sei) {
>> > +        return "http://localhost:" + port + "/" + sei.getSimpleName();
>> >     }
>> > -
>> >
>> >     @Test
>> >     public void testRPCLit() throws Exception {
>> > @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest extends
>> Assert {
>> >         try {
>> >             person.setFirstName(null);
>> >             rpcClient.saveValidateOut(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> >             assertTrue(sfe.getMessage().contains("Marshalling Error"));
>> >             assertTrue(sfe.getMessage().contains("lastName"));
>> >         }
>> > @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest
>> extends Assert {
>> >
>> >         try {
>> >             annotatedClient.saveInheritEndpoint(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >         }
>> >
>> >         try {
>> >             person.setFirstName(""); // empty string is valid
>> >             annotatedClient.saveInheritEndpoint(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >         }
>> >
>> >         person.setLastName(""); // empty string is valid
>> >         annotatedClient.saveInheritEndpoint(person);
>> >     }
>> > -
>> > +
>> >     @Test
>> >     public void testSaveValidateInAnnotated() {
>> >         Person person = new Person();
>> >
>> >         try {
>> >             annotatedClient.saveValidateIn(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >         }
>> >
>> >         try {
>> >             person.setFirstName(""); // empty string is valid
>> >             annotatedClient.saveValidateIn(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >         }
>> >
>> >         person.setLastName(""); // empty string is valid
>> > @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
>> extends Assert {
>> >         annotatedClient.saveNoValidation(person);
>> >     }
>> >
>> > -    // no validation is required for incoming
>> >     @Test
>> > -    public void testSaveValidationOutAnnotated() {
>> > +    public void
>> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
>> >         Person person = new Person();
>> >
>> > -        annotatedClient.saveValidateOut(person);
>> > +        try {
>> > +            annotatedClient.saveValidateOut(person);
>> > +        } catch (SOAPFaultException sfe) {
>> > +            // verify its server side and a schema validation
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> > +            // it's still a server side fault, because server side
>> validation coming in failed
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> > +
>> > +        person.setFirstName(""); // empty string is valid
>> > +        try {
>> > +            annotatedClient.saveValidateOut(person);
>> > +        } catch (SOAPFaultException sfe) {
>> > +            // verify its server side and a schema validation
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> > +            // it's still a server side fault, because server side
>> validation coming in failed
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> >
>> > +        person.setLastName(""); // empty string is valid
>> > +        annotatedClient.saveValidateIn(person);
>> > +    }
>> > +
>> > +    // this will still all be server side, as the OUT validation is
>> turned into an IN validation for
>> > +    // the client, but by then the server has already thrown the
>> exception for the OUT
>> > +    @Test
>> > +    public void
>> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
>> > +        Person person = new Person();
>> > +
>> > +        try {
>> > +            annotatedValidatingClient.saveValidateIn(person);
>> > +        } catch (SOAPFaultException sfe) {
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> > +
>> >         person.setFirstName(""); // empty string is valid
>> > -        annotatedClient.saveValidateOut(person);
>> > +        try {
>> > +            annotatedValidatingClient.saveValidateIn(person);
>> > +        } catch (SOAPFaultException sfe) {
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> >
>> >         person.setLastName(""); // empty string is valid
>> > -        annotatedClient.saveValidateOut(person);
>> > +        annotatedValidatingClient.saveValidateIn(person);
>> > +    }
>> > +
>> > +    @Test
>> > +    public void
>> testSaveValidationInAnnotatedWithClientValidationEnabled() {
>> > +        Person person = new Person();
>> > +
>> > +        try {
>> > +            person.setFirstName("InvalidResponse");
>> > +            person.setLastName("WhoCares");
>> > +            annotatedValidatingClient.saveValidateOut(person);
>> > +        } catch (SOAPFaultException sfe) {
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> >     }
>> >
>> > -    // so this is the default, we are inheriting from the service
>> level SchemaValidation annotation
>> > -    // which is set to BOTH
>> >     @Test
>> >     public void testEndpointSchemaValidationProvider() {
>> >         Person person = new Person();
>> >
>> >         try {
>> >             client.saveInheritEndpoint(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >         }
>> > -
>> > +
>> >         try {
>> >             person.setFirstName(""); // empty string is valid
>> >             client.saveInheritEndpoint(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >         }
>> >
>> >         person.setLastName(""); // empty string is valid
>> > @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest
>> extends Assert {
>> >
>> >         try {
>> >             client.saveValidateIn(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >         }
>> >
>> >         try {
>> >             person.setFirstName(""); // empty string is valid
>> >             client.saveValidateIn(person);
>> > +            fail("Expected exception");
>> >         } catch (SOAPFaultException sfe) {
>> > -            // verify its server side and a schema validation
>> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
>> Error"));
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> >         }
>> >
>> >         person.setLastName(""); // empty string is valid
>> >         client.saveValidateIn(person);
>> >     }
>> >
>> > -    // no validation at all is required
>> >     @Test
>> >     public void testSaveNoValidationProvider() {
>> >         Person person = new Person();
>> > @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest
>> extends Assert {
>> >         client.saveNoValidation(person);
>> >     }
>> >
>> > -    // no validation is required for incoming
>> >     @Test
>> > -    public void testSaveValidationOutProvider() {
>> > +    public void testSaveValidationOutProviderClientOnly() {
>> >         Person person = new Person();
>> >
>> > -        client.saveValidateOut(person);
>> > +        try {
>> > +            disconnectedClient.saveValidateOut(person);
>> > +            fail("Expected exception");
>> > +        } catch (SOAPFaultException sfe) {
>> > +            // verify its client side outgoing
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> > +
>> > +        person.setFirstName(""); // empty string is valid
>> > +        try {
>> > +            disconnectedClient.saveValidateOut(person);
>> > +            fail("Expected exception");
>> > +        } catch (SOAPFaultException sfe) {
>> > +            // verify its client side outgoing
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> > +
>> > +        person.setLastName(""); // empty string is valid
>> > +
>> > +        // this confirms that we passed client validation as we then
>> got the connectivity error
>> > +        try {
>> > +            disconnectedClient.saveValidateOut(person);
>> > +            fail("Expected exception");
>> > +        } catch (WebServiceException e) {
>> > +            assertTrue(e.getMessage().contains("Could not send
>> Message"));
>> > +        }
>> > +    }
>> >
>> > +
>> > +    @Test
>> > +    public void testSaveValidationOutProvider() {
>> > +        Person person = new Person();
>> > +
>> > +        try {
>> > +            client.saveValidateOut(person);
>> > +        } catch (SOAPFaultException sfe) {
>> > +            // verify its server side outgoing
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> > +
>> >         person.setFirstName(""); // empty string is valid
>> > -        client.saveValidateOut(person);
>> > +        try {
>> > +            client.saveValidateOut(person);
>> > +        } catch (SOAPFaultException sfe) {
>> > +            // verify its server side outgoing
>> > +            String stackTrace = getStackTrace(sfe);
>> > +            assertTrue(stackTrace.contains("Marshalling Error"));
>> > +
>> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
>> > +        }
>> >
>> >         person.setLastName(""); // empty string is valid
>> >         client.saveValidateOut(person);
>> >     }
>> >
>> > -    private static <T> T createClient(Class<T> serviceClass) {
>> > +    private static <T> T createClient(String port, Class<T>
>> serviceClass, SchemaValidationType type) {
>> >         JaxWsProxyFactoryBean clientFactory = new
>> JaxWsProxyFactoryBean();
>> >         clientFactory.setServiceClass(serviceClass);
>> > -
>> > -        // ensure all client schema validation is disabled
>> > -        Map<String, Object> properties = new HashMap<String, Object>();
>> > -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
>> SchemaValidationType.NONE);
>> > -        clientFactory.setProperties(properties);
>> > -
>> > -        clientFactory.setAddress(getAddress(serviceClass));
>> > -
>> > +
>> > +
>> > +        clientFactory.setAddress(getAddress(port, serviceClass));
>> > +
>> > +
>> >         @SuppressWarnings("unchecked")
>> >         T newClient = (T)clientFactory.create();
>> >
>> > -        Client clientProxy = ClientProxy.getClient(newClient);
>> > -
>> > -        // ensure all client schema validation is disabled
>> > -        for (BindingOperationInfo bop :
>> clientProxy.getEndpoint().getEndpointInfo().getBinding()
>> > -            .getOperations()) {
>> > -
>> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
>> SchemaValidationType.NONE);
>> > +        Client proxy = ClientProxy.getClient(newClient);
>> > +
>> > +        if (type != null) {
>> > +
>> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED, type);
>> >         }
>> > -
>> > +
>> > +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
>> > +        // give me longer debug times
>> > +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
>> > +        clientPolicy.setConnectionTimeout(1000000);
>> > +        clientPolicy.setReceiveTimeout(1000000);
>> > +        conduit.setClient(clientPolicy);
>> > +
>> >         return newClient;
>> >     }
>> >
>> > @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest
>> extends Assert {
>> >         if (features != null) {
>> >             svrFactory.getFeatures().addAll(Arrays.asList(features));
>> >         }
>> > -        svrFactory.setAddress(getAddress(serviceInterface));
>> > +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
>> >         svrFactory.setServiceBean(serviceImpl);
>> >         Server server = svrFactory.create();
>> >         serverList.add(server);
>> >         return server;
>> >     }
>> > +
>> > +    private String getStackTrace(Exception e) {
>> > +        StringWriter sWriter = new StringWriter();
>> > +        PrintWriter writer = new PrintWriter(sWriter, true);
>> > +        e.printStackTrace(writer);
>> > +        return sWriter.toString();
>> > +    }
>> > }
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> > index e3ee10c..d594e4e 100644
>> > ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> > +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
>> > @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
>> >
>> > import javax.jws.WebMethod;
>> > import javax.jws.WebParam;
>> > +import javax.jws.WebResult;
>> > import javax.jws.WebService;
>> >
>> > import org.apache.cxf.annotations.SchemaValidation;
>> > @@ -30,14 +31,18 @@ import
>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>> > @SchemaValidation(type = SchemaValidationType.BOTH)
>> > public interface PersonService {
>> >     @WebMethod(operationName = "saveInheritEndpoint")
>> > -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
>> > +    @WebResult(name = "Person")
>> > +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
>> >
>> >     @WebMethod(operationName = "saveNoValidation")
>> > -    void saveNoValidation(@WebParam(name = "Person") Person data);
>> > +    @WebResult(name = "Person")
>> > +    Person saveNoValidation(@WebParam(name = "Person") Person data);
>> >
>> >     @WebMethod(operationName = "saveValidateIn")
>> > -    void saveValidateIn(@WebParam(name = "Person") Person data);
>> > +    @WebResult(name = "Person")
>> > +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>> >
>> >     @WebMethod(operationName = "saveValidateOut")
>> > -    void saveValidateOut(@WebParam(name = "Person") Person data);
>> > +    @WebResult(name = "Person")
>> > +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>> > }
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> > index 3e06576..a760f27 100644
>> > ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> > +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
>> > @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
>> >
>> > import javax.jws.WebMethod;
>> > import javax.jws.WebParam;
>> > +import javax.jws.WebResult;
>> > import javax.jws.WebService;
>> >
>> > import org.apache.cxf.annotations.SchemaValidation;
>> > @@ -30,17 +31,21 @@ import
>> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
>> > @SchemaValidation(type = SchemaValidationType.BOTH)
>> > public interface PersonServiceAnnotated {
>> >     @WebMethod(operationName = "saveInheritEndpoint")
>> > -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
>> > +    @WebResult(name = "Person")
>> > +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
>> >
>> >     @SchemaValidation(type = SchemaValidationType.NONE)
>> >     @WebMethod(operationName = "saveNoValidation")
>> > -    void saveNoValidation(@WebParam(name = "Person") Person data);
>> > +    @WebResult(name = "Person")
>> > +    Person saveNoValidation(@WebParam(name = "Person") Person data);
>> >
>> >     @SchemaValidation(type = SchemaValidationType.IN)
>> >     @WebMethod(operationName = "saveValidateIn")
>> > -    void saveValidateIn(@WebParam(name = "Person") Person data);
>> > +    @WebResult(name = "Person")
>> > +    Person saveValidateIn(@WebParam(name = "Person") Person data);
>> >
>> >     @SchemaValidation(type = SchemaValidationType.OUT)
>> >     @WebMethod(operationName = "saveValidateOut")
>> > -    void saveValidateOut(@WebParam(name = "Person") Person data);
>> > +    @WebResult(name = "Person")
>> > +    Person saveValidateOut(@WebParam(name = "Person") Person data);
>> > }
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> > index c7b8038..78973c9 100644
>> > ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> > +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
>> > @@ -26,18 +26,25 @@ import javax.jws.WebService;
>> >     targetNamespace = "
>> http://org.apache.cxf/service/PersonServiceAnnotated")
>> > public class PersonServiceAnnotatedImpl implements
>> PersonServiceAnnotated {
>> >     @Override
>> > -    public void saveNoValidation(Person data) {
>> > +    public Person saveNoValidation(Person data) {
>> > +        return data;
>> >     }
>> >
>> >     @Override
>> > -    public void saveInheritEndpoint(Person data) {
>> > +    public Person saveInheritEndpoint(Person data) {
>> > +        return data;
>> >     }
>> >
>> >     @Override
>> > -    public void saveValidateIn(Person data) {
>> > +    public Person saveValidateIn(Person data) {
>> > +        if ("InvalidResponse".equals(data.getFirstName())) {
>> > +            return new Person();
>> > +        }
>> > +        return data;
>> >     }
>> >
>> >     @Override
>> > -    public void saveValidateOut(Person data) {
>> > +    public Person saveValidateOut(Person data) {
>> > +        return data;
>> >     }
>> > }
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> > index fe1d656..9edec45 100644
>> > ---
>> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> > +++
>> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
>> > @@ -26,18 +26,22 @@ import javax.jws.WebService;
>> >     targetNamespace = "http://org.apache.cxf/service/PersonService")
>> > public class PersonServiceImpl implements PersonService {
>> >     @Override
>> > -    public void saveNoValidation(Person data) {
>> > +    public Person saveNoValidation(Person data) {
>> > +        return data;
>> >     }
>> >
>> >     @Override
>> > -    public void saveInheritEndpoint(Person data) {
>> > +    public Person saveInheritEndpoint(Person data) {
>> > +        return data;
>> >     }
>> >
>> >     @Override
>> > -    public void saveValidateIn(Person data) {
>> > +    public Person saveValidateIn(Person data) {
>> > +        return data;
>> >     }
>> >
>> >     @Override
>> > -    public void saveValidateOut(Person data) {
>> > +    public Person saveValidateOut(Person data) {
>> > +        return data;
>> >     }
>> > }
>> >
>> >
>> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> > ----------------------------------------------------------------------
>> > diff --git
>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> > deleted file mode 100644
>> > index 18e66ae..0000000
>> > ---
>> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
>> > +++ /dev/null
>> > @@ -1,69 +0,0 @@
>> > -/**
>> > - * Licensed to the Apache Software Foundation (ASF) under one
>> > - * or more contributor license agreements. See the NOTICE file
>> > - * distributed with this work for additional information
>> > - * regarding copyright ownership. The ASF licenses this file
>> > - * to you 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.cxf.systest.mtom_schema_validation;
>> > -
>> > -import java.io.File;
>> > -import java.net.URL;
>> > -
>> > -import javax.activation.DataHandler;
>> > -import javax.activation.FileDataSource;
>> > -import javax.xml.namespace.QName;
>> > -import javax.xml.ws.soap.MTOMFeature;
>> > -
>> > -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
>> > -
>> > -import org.junit.BeforeClass;
>> > -import org.junit.Test;
>> > -
>> > -public final class MTOMProviderSchemaValidationTest extends
>> AbstractBusClientServerTestBase {
>> > -    public static final String PORT = "9001";
>> > -        //Server.PORT;
>> > -
>> > -    private final QName serviceName = new QName("
>> http://cxf.apache.org/", "HelloWS");
>> > -
>> > -    @BeforeClass
>> > -    public static void startservers() throws Exception {
>> > -        //assertTrue("server did not launch correctly",
>> launchServer(Server.class, true));
>> > -    }
>> > -    @Test
>> > -    public void testSchemaValidation() throws Exception {
>> > -        HelloWS port = createService();
>> > -        Hello request = new Hello();
>> > -        request.setArg0("value");
>> > -        URL wsdl =
>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>> > -        File attachment = new File(wsdl.getFile());
>> > -        request.setFile(new DataHandler(new
>> FileDataSource(attachment)));
>> > -        HelloResponse response = port.hello(request);
>> > -        assertEquals("Hello CXF", response.getReturn());
>> > -    }
>> > -
>> > -    private HelloWS createService() throws Exception {
>> > -        URL wsdl =
>> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
>> > -        assertNotNull(wsdl);
>> > -
>> > -        HelloWSClient service = new HelloWSClient(wsdl, serviceName);
>> > -        assertNotNull(service);
>> > -
>> > -        HelloWS port = service.getHello(new MTOMFeature());
>> > -
>> > -        updateAddressPort(port, PORT);
>> > -
>> > -        return port;
>> > -    }
>> > -}
>> >
>>
>> --
>> Daniel Kulp
>> dkulp@apache.org - http://dankulp.com/blog
>> Talend Community Coder - http://coders.talend.com
>>
>>

Re: cxf git commit: CXF-6118 support overriding schema validation at jaxws endpoint and client level and applying the correct validation direction at client level

Posted by Jason Pell <jp...@apache.org>.
Its only reversing what's coming from the model. If you define IN in the
jaxws properties on the client it will continue to validate IN on the
client as before.

If I have IN defined for a operation using an annotation the old code would
actually validate the response coming back to the client. This does seem
counter intuitive especially as IN might have been specified because the
response may be incomplete and so can't be validated.

An IN for service is the OUT for client.

The previous code was just plain wrong for client side - my code by the way
:-)

This particular piece is only a few lines in ServiceUtils so I am happy to
remove it if you are still -1

The alternative is I will add a property to enable it but only if the
property is used.

Would that be OK?
On 29/11/2014 10:05 AM, "Daniel Kulp" <dk...@apache.org> wrote:

>
> I’m -1 on the part of this that changes the IN to an OUT on the client
> side.   The IN and OUT are specifically named that way as they apply to the
> messages that come IN to the client or IN to the server.   The “IN”
> validation should definitely not be applying to the messages going OUT.
> Plus, that would be a huge behavioral change that would break many peoples
> existing applications.
>
> Dan
>
>
>
>
> > On Nov 27, 2014, at 11:52 PM, jpell@apache.org wrote:
> >
> > Repository: cxf
> > Updated Branches:
> >  refs/heads/2.7.x-fixes e172a3ebf -> 27ce514bb
> >
> >
> > CXF-6118 support overriding schema validation at jaxws endpoint and
> client level and applying the correct validation direction at client level
> >
> >
> > Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
> > Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/27ce514b
> > Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/27ce514b
> > Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/27ce514b
> >
> > Branch: refs/heads/2.7.x-fixes
> > Commit: 27ce514bb97a7693fd78d1ca16685665bca64553
> > Parents: e172a3e
> > Author: Jason Pell <jp...@apache.org>
> > Authored: Thu Nov 27 16:54:01 2014 +1100
> > Committer: Jason Pell <jp...@apache.org>
> > Committed: Fri Nov 28 15:52:36 2014 +1100
> >
> > ----------------------------------------------------------------------
> > .../validation/SchemaValidationFeature.java     |   2 +-
> > .../org/apache/cxf/helpers/ServiceUtils.java    |  98 ++++++-
> > .../AbstractInDatabindingInterceptor.java       |  23 +-
> > .../AbstractOutDatabindingInterceptor.java      |  22 +-
> > .../java/org/apache/cxf/message/Message.java    |   9 +
> > .../soap/interceptor/RPCInInterceptor.java      |   2 +-
> > .../factory/AnnotationsFactoryBeanListener.java |   9 +-
> > .../JavaFirstSchemaValidationTest.java          | 256 ++++++++++++++-----
> > .../jaxws/schemavalidation/PersonService.java   |  13 +-
> > .../PersonServiceAnnotated.java                 |  13 +-
> > .../PersonServiceAnnotatedImpl.java             |  15 +-
> > .../schemavalidation/PersonServiceImpl.java     |  12 +-
> > .../MTOMProviderSchemaValidationTest.bak        |  69 -----
> > 13 files changed, 342 insertions(+), 201 deletions(-)
> > ----------------------------------------------------------------------
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> > ----------------------------------------------------------------------
> > diff --git
> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> > index 5eda79c..c314eaf 100644
> > ---
> a/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> > +++
> b/api/src/main/java/org/apache/cxf/feature/validation/SchemaValidationFeature.java
> > @@ -51,7 +51,7 @@ public class SchemaValidationFeature extends
> AbstractFeature {
> >         for (BindingOperationInfo bop :
> endpoint.getEndpointInfo().getBinding().getOperations()) {
> >             SchemaValidationType type =
> provider.getSchemaValidationType(bop.getOperationInfo());
> >             if (type != null) {
> > -
> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED, type);
> > +
> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE, type);
> >             }
> >         }
> >     }
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> > ----------------------------------------------------------------------
> > diff --git a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> > index 85d77d0..28c7ba2 100644
> > --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> > +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java
> > @@ -27,10 +27,16 @@ import java.util.StringTokenizer;
> > import javax.xml.namespace.QName;
> >
> > import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> > +import org.apache.cxf.endpoint.Endpoint;
> > +import org.apache.cxf.message.Exchange;
> > import org.apache.cxf.message.Message;
> > +import org.apache.cxf.message.MessageUtils;
> > +import org.apache.cxf.service.model.AbstractPropertiesHolder;
> > +import org.apache.cxf.service.model.BindingOperationInfo;
> > +import org.apache.cxf.service.model.EndpointInfo;
> > +import org.apache.cxf.service.model.OperationInfo;
> >
> > public final class ServiceUtils {
> > -
> >     private ServiceUtils() {
> >     }
> >
> > @@ -42,24 +48,94 @@ public final class ServiceUtils {
> >      * @param type
> >      */
> >     public static boolean isSchemaValidationEnabled(SchemaValidationType
> type, Message message) {
> > -        SchemaValidationType messageType =
> getSchemaValidationType(message);
> > +        SchemaValidationType validationType =
> getSchemaValidationType(message);
> >
> > -        return messageType.equals(type)
> > +        return validationType.equals(type)
> >             || ((SchemaValidationType.IN.equals(type) ||
> SchemaValidationType.OUT.equals(type))
> > -                && SchemaValidationType.BOTH.equals(messageType));
> > +                && SchemaValidationType.BOTH.equals(validationType));
> >     }
> > -
> > +
> >     /**
> > -     * Determines the appropriate SchemaValidationType to return based
> on either
> > -     * a Boolean (for backwards compatibility) or the selected Schema
> Validation Type.
> > -     *
> > -     * Package private as the isSchemaValidationEnabled method should
> be used instead.  Only
> > -     * visible for easier testing
> > +     * A convenience method to check for schema validation config in
> the message context, and then in the service model.
> > +     * Does not modify the Message context (other than what is done in
> the getContextualProperty itself)
> >      *
> >      * @param message
> > +     * @param type
> >      */
> > -    static SchemaValidationType getSchemaValidationType(Message
> message) {
> > +    public static SchemaValidationType getSchemaValidationType(Message
> message) {
> > +        SchemaValidationType validationType =
> getOverrideSchemaValidationType(message);
> > +        if (validationType == null) {
> > +            validationType = getSchemaValidationTypeFromModel(message);
> > +        }
> > +
> > +        if (validationType == null) {
> > +            validationType = SchemaValidationType.NONE;
> > +        }
> > +
> > +        return validationType;
> > +    }
> > +
> > +    private static SchemaValidationType
> getOverrideSchemaValidationType(Message message) {
> >         Object obj =
> message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
> > +        if (obj != null) {
> > +            // this method will transform the legacy enabled as well
> > +            return getSchemaValidationType(obj);
> > +        } else {
> > +            return null;
> > +        }
> > +    }
> > +
> > +    private static SchemaValidationType
> getSchemaValidationTypeFromModel(Message message) {
> > +        boolean isRequestor = MessageUtils.isRequestor(message);
> > +        Exchange exchange = message.getExchange();
> > +
> > +        if (exchange != null) {
> > +            BindingOperationInfo boi =
> exchange.getBindingOperationInfo();
> > +            Endpoint endpoint = exchange.getEndpoint();
> > +
> > +            if (boi != null && endpoint != null) {
> > +                SchemaValidationType validationType = null;
> > +                OperationInfo opInfo = boi.getOperationInfo();
> > +                EndpointInfo ep = endpoint.getEndpointInfo();
> > +
> > +                if (validationType == null && opInfo != null) {
> > +                    validationType =
> getSchemaValidationTypeFromModel(message, opInfo, isRequestor);
> > +
> > +                    if (validationType == null && ep != null) {
> > +                        validationType =
> getSchemaValidationTypeFromModel(message, ep, isRequestor);
> > +                    }
> > +                }
> > +
> > +                return validationType;
> > +            }
> > +        }
> > +
> > +        // else
> > +        return null;
> > +    }
> > +
> > +    private static SchemaValidationType
> getSchemaValidationTypeFromModel(
> > +            Message message, AbstractPropertiesHolder properties,
> boolean isRequestor) {
> > +        Object obj =
> properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
> > +        if (obj != null) {
> > +            SchemaValidationType validationType =
> getSchemaValidationType(obj);
> > +
> > +            // Reverse the direction of any IN / OUT for requestor
> (client)
> > +            if (isRequestor) {
> > +                if (SchemaValidationType.IN.equals(validationType)) {
> > +                    return SchemaValidationType.OUT;
> > +                } else if
> (SchemaValidationType.OUT.equals(validationType)) {
> > +                    return SchemaValidationType.IN;
> > +                }
> > +            }
> > +
> > +            return validationType;
> > +        } else {
> > +            return null;
> > +        }
> > +    }
> > +
> > +    public static SchemaValidationType getSchemaValidationType(Object
> obj) {
> >         if (obj instanceof SchemaValidationType) {
> >             return (SchemaValidationType)obj;
> >         } else if (obj != null) {
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> > ----------------------------------------------------------------------
> > diff --git
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> > index c47417a..ec8cf71 100644
> > ---
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> > +++
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java
> > @@ -125,24 +125,9 @@ public abstract class
> AbstractInDatabindingInterceptor extends AbstractPhaseInte
> >         }
> >     }
> >
> > -    /**
> > -     * Where an operation level validation type has been set, copy it
> to the message, so it can be interrogated
> > -     * by all downstream interceptors.  It is expected that sub classes
> will call setDataReaderValidation subsequent
> > -     * to this to ensure the DataReader schema reference is updated as
> appropriate.
> > -     *
> > -     * @param bop
> > -     * @param message
> > -     * @param reader
> > -     * @see #setDataReaderValidation(Service, Message, DataReader)
> > -     */
> > -    protected void setOperationSchemaValidation(OperationInfo opInfo,
> Message message) {
> > -        if (opInfo != null) {
> > -            SchemaValidationType validationType =
> > -                (SchemaValidationType)
> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> > -            if (validationType != null) {
> > -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
> validationType);
> > -            }
> > -        }
> > +    protected void setOperationSchemaValidation(Message message) {
> > +        SchemaValidationType validationType =
> ServiceUtils.getSchemaValidationType(message);
> > +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
> >     }
> >
> >     protected DepthXMLStreamReader getXMLStreamReader(Message message) {
> > @@ -247,7 +232,7 @@ public abstract class
> AbstractInDatabindingInterceptor extends AbstractPhaseInte
> >         }
> >
> >         // configure endpoint and operation level schema validation
> > -        setOperationSchemaValidation(operation.getOperationInfo(),
> message);
> > +        setOperationSchemaValidation(message);
> >
> >         QName serviceQName = si.getName();
> >         message.put(Message.WSDL_SERVICE, serviceQName);
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> > ----------------------------------------------------------------------
> > diff --git
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> > index db3ba6c..52d1cb1 100644
> > ---
> a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> > +++
> b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
> > @@ -43,7 +43,6 @@ import org.apache.cxf.service.Service;
> > import org.apache.cxf.service.model.BindingInfo;
> > import org.apache.cxf.service.model.BindingOperationInfo;
> > import org.apache.cxf.service.model.MessagePartInfo;
> > -import org.apache.cxf.service.model.OperationInfo;
> > import org.apache.cxf.staxutils.CachingXmlEventWriter;
> > import org.apache.cxf.staxutils.StaxUtils;
> > import org.apache.cxf.wsdl.EndpointReferenceUtils;
> > @@ -85,7 +84,7 @@ public abstract class
> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
> >         CachingXmlEventWriter cache = null;
> >
> >         // configure endpoint and operation level schema validation
> > -        setOperationSchemaValidation(operation.getOperationInfo(),
> message);
> > +        setOperationSchemaValidation(message);
> >
> >         // need to cache the events in case validation fails or
> buffering is enabled
> >         if (shouldBuffer(message)) {
> > @@ -159,22 +158,9 @@ public abstract class
> AbstractOutDatabindingInterceptor extends AbstractPhaseInt
> >         }
> >     }
> >
> > -    /**
> > -     * Where an operation level validation type has been set, copy it
> to the message, so it can be interrogated
> > -     * by all downstream interceptors
> > -     *
> > -     * @param bop
> > -     * @param message
> > -     * @param reader
> > -     */
> > -    private void setOperationSchemaValidation(OperationInfo opInfo,
> Message message) {
> > -        if (opInfo != null) {
> > -            SchemaValidationType validationType =
> > -                (SchemaValidationType)
> opInfo.getProperty(Message.SCHEMA_VALIDATION_ENABLED);
> > -            if (validationType != null) {
> > -                message.put(Message.SCHEMA_VALIDATION_ENABLED,
> validationType);
> > -            }
> > -        }
> > +    protected void setOperationSchemaValidation(Message message) {
> > +        SchemaValidationType validationType =
> ServiceUtils.getSchemaValidationType(message);
> > +        message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType);
> >     }
> >
> >     protected boolean shouldValidate(Message m) {
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/api/src/main/java/org/apache/cxf/message/Message.java
> > ----------------------------------------------------------------------
> > diff --git a/api/src/main/java/org/apache/cxf/message/Message.java
> b/api/src/main/java/org/apache/cxf/message/Message.java
> > index 35e94af..5854a18 100644
> > --- a/api/src/main/java/org/apache/cxf/message/Message.java
> > +++ b/api/src/main/java/org/apache/cxf/message/Message.java
> > @@ -105,7 +105,16 @@ public interface Message extends StringMap {
> >      */
> >     String MTOM_ENABLED = "mtom-enabled";
> >     String MTOM_THRESHOLD = "mtom-threshold";
> > +
> > +    /**
> > +     * Runtime schema validation property
> > +     */
> >     String SCHEMA_VALIDATION_ENABLED = "schema-validation-enabled";
> > +
> > +    /**
> > +     * The default values for schema validation will be set in the
> service model using this property
> > +     */
> > +    String SCHEMA_VALIDATION_TYPE = "schema-validation-type";
> >
> >     /**
> >      * Boolean property specifying if the Java stack trace is returned
> as a
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> > ----------------------------------------------------------------------
> > diff --git
> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> > index fafd0a9..d49f090 100644
> > ---
> a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> > +++
> b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/RPCInInterceptor.java
> > @@ -226,6 +226,6 @@ public class RPCInInterceptor extends
> AbstractInDatabindingInterceptor {
> >         message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
> >
> >         // configure endpoint and operation level schema validation
> > -        setOperationSchemaValidation(operation.getOperationInfo(),
> message);
> > +        setOperationSchemaValidation(message);
> >     }
> > }
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> > ----------------------------------------------------------------------
> > diff --git
> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> > index 7100f2c..9a7cbc8 100644
> > ---
> a/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> > +++
> b/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
> > @@ -297,9 +297,9 @@ public class AnnotationsFactoryBeanListener
> implements FactoryBeanListener {
> >             // if someone has gone to the effort of specifying
> enabled=false, then we need to
> >             // handle that, otherwise we use the new
> SchemaValidationType type only
> >             if (!annotation.enabled()) {
> > -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
> SchemaValidationType.NONE);
> > +
> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> SchemaValidationType.NONE);
> >             } else {
> > -                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED,
> annotation.type());
> > +
> endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_TYPE,
> annotation.type());
> >             }
> >         }
> >     }
> > @@ -359,11 +359,8 @@ public class AnnotationsFactoryBeanListener
> implements FactoryBeanListener {
> >     }
> >
> >     private void addSchemaValidationSupport(OperationInfo inf,
> SchemaValidation annotation) {
> > -        // Notice no support for deprecated enabled property here!
> > -        // TODO - should we check for the use of this property and at
> least log the fact we are
> > -        // ignoring it
> >         if (annotation != null) {
> > -            inf.setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> annotation.type());
> > +            inf.setProperty(Message.SCHEMA_VALIDATION_TYPE,
> annotation.type());
> >         }
> >     }
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> > ----------------------------------------------------------------------
> > diff --git
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> > index 888e5a8..9f08839 100644
> > ---
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> > +++
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/JavaFirstSchemaValidationTest.java
> > @@ -20,12 +20,15 @@
> > package org.apache.cxf.systest.jaxws.schemavalidation;
> >
> > import java.io.IOException;
> > +import java.io.PrintWriter;
> > +import java.io.StringWriter;
> > import java.util.ArrayList;
> > import java.util.Arrays;
> > import java.util.HashMap;
> > import java.util.List;
> > import java.util.Map;
> >
> > +import javax.xml.ws.WebServiceException;
> > import javax.xml.ws.soap.SOAPFaultException;
> >
> > import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> > @@ -39,24 +42,25 @@ import org.apache.cxf.frontend.ClientProxy;
> > import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
> > import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
> > import org.apache.cxf.message.Message;
> > -import org.apache.cxf.service.model.BindingOperationInfo;
> > import org.apache.cxf.testutil.common.TestUtil;
> > +import org.apache.cxf.transport.http.HTTPConduit;
> > +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
> > import org.junit.AfterClass;
> > import org.junit.Assert;
> > import org.junit.BeforeClass;
> > import org.junit.Test;
> >
> > -/**
> > - * TODO - test where the default is NONE at the service level test
> where the default is IN or OUT, and then
> > - * override at operation levels
> > - */
> > public class JavaFirstSchemaValidationTest extends Assert {
> > -    static final String PORT =
> TestUtil.getPortNumber(JavaFirstSchemaValidationTest.class);
> > +    static final String PORT =
> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> > +    static final String PORT_UNUSED =
> TestUtil.getNewPortNumber(JavaFirstSchemaValidationTest.class);
> >
> >     private static List<Server> serverList = new ArrayList<Server>();
> >     private static PersonServiceAnnotated annotatedClient;
> > +    private static PersonServiceAnnotated annotatedValidatingClient;
> >     private static PersonService client;
> >     private static PersonServiceRPC rpcClient;
> > +
> > +    private static PersonService disconnectedClient;
> >
> >     @BeforeClass
> >     public static void startServers() throws Exception {
> > @@ -75,9 +79,11 @@ public class JavaFirstSchemaValidationTest extends
> Assert {
> >
> >         createServer(PersonServiceRPC.class, new PersonServiceRPCImpl(),
> feature, new LoggingFeature());
> >
> > -        annotatedClient = createClient(PersonServiceAnnotated.class);
> > -        client = createClient(PersonService.class);
> > -        rpcClient = createClient(PersonServiceRPC.class);
> > +        annotatedClient = createClient(PORT,
> PersonServiceAnnotated.class, SchemaValidationType.NONE);
> > +        annotatedValidatingClient = createClient(PORT,
> PersonServiceAnnotated.class, null);
> > +        client = createClient(PORT, PersonService.class,
> SchemaValidationType.NONE);
> > +        disconnectedClient = createClient(PORT_UNUSED,
> PersonService.class, SchemaValidationType.OUT);
> > +        rpcClient = createClient(PORT, PersonServiceRPC.class,
> SchemaValidationType.NONE);
> >     }
> >
> >     @AfterClass
> > @@ -87,10 +93,9 @@ public class JavaFirstSchemaValidationTest extends
> Assert {
> >         }
> >     }
> >
> > -    static String getAddress(Class<?> sei) {
> > -        return "http://localhost:" + PORT + "/" + sei.getSimpleName();
> > +    static String getAddress(String port, Class<?> sei) {
> > +        return "http://localhost:" + port + "/" + sei.getSimpleName();
> >     }
> > -
> >
> >     @Test
> >     public void testRPCLit() throws Exception {
> > @@ -103,8 +108,8 @@ public class JavaFirstSchemaValidationTest extends
> Assert {
> >         try {
> >             person.setFirstName(null);
> >             rpcClient.saveValidateOut(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> >             assertTrue(sfe.getMessage().contains("Marshalling Error"));
> >             assertTrue(sfe.getMessage().contains("lastName"));
> >         }
> > @@ -119,40 +124,48 @@ public class JavaFirstSchemaValidationTest extends
> Assert {
> >
> >         try {
> >             annotatedClient.saveInheritEndpoint(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
> Error"));
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >         }
> >
> >         try {
> >             person.setFirstName(""); // empty string is valid
> >             annotatedClient.saveInheritEndpoint(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
> Error"));
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >         }
> >
> >         person.setLastName(""); // empty string is valid
> >         annotatedClient.saveInheritEndpoint(person);
> >     }
> > -
> > +
> >     @Test
> >     public void testSaveValidateInAnnotated() {
> >         Person person = new Person();
> >
> >         try {
> >             annotatedClient.saveValidateIn(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
> Error"));
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >         }
> >
> >         try {
> >             person.setFirstName(""); // empty string is valid
> >             annotatedClient.saveValidateIn(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
> Error"));
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >         }
> >
> >         person.setLastName(""); // empty string is valid
> > @@ -172,39 +185,100 @@ public class JavaFirstSchemaValidationTest
> extends Assert {
> >         annotatedClient.saveNoValidation(person);
> >     }
> >
> > -    // no validation is required for incoming
> >     @Test
> > -    public void testSaveValidationOutAnnotated() {
> > +    public void
> testSaveValidationOutAnnotatedWithClientValidationDisabled() {
> >         Person person = new Person();
> >
> > -        annotatedClient.saveValidateOut(person);
> > +        try {
> > +            annotatedClient.saveValidateOut(person);
> > +        } catch (SOAPFaultException sfe) {
> > +            // verify its server side and a schema validation
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> > +            // it's still a server side fault, because server side
> validation coming in failed
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> > +
> > +        person.setFirstName(""); // empty string is valid
> > +        try {
> > +            annotatedClient.saveValidateOut(person);
> > +        } catch (SOAPFaultException sfe) {
> > +            // verify its server side and a schema validation
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> > +            // it's still a server side fault, because server side
> validation coming in failed
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> >
> > +        person.setLastName(""); // empty string is valid
> > +        annotatedClient.saveValidateIn(person);
> > +    }
> > +
> > +    // this will still all be server side, as the OUT validation is
> turned into an IN validation for
> > +    // the client, but by then the server has already thrown the
> exception for the OUT
> > +    @Test
> > +    public void
> testSaveValidationOutAnnotatedWithClientValidationEnabled() {
> > +        Person person = new Person();
> > +
> > +        try {
> > +            annotatedValidatingClient.saveValidateIn(person);
> > +        } catch (SOAPFaultException sfe) {
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> > +
> >         person.setFirstName(""); // empty string is valid
> > -        annotatedClient.saveValidateOut(person);
> > +        try {
> > +            annotatedValidatingClient.saveValidateIn(person);
> > +        } catch (SOAPFaultException sfe) {
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> >
> >         person.setLastName(""); // empty string is valid
> > -        annotatedClient.saveValidateOut(person);
> > +        annotatedValidatingClient.saveValidateIn(person);
> > +    }
> > +
> > +    @Test
> > +    public void
> testSaveValidationInAnnotatedWithClientValidationEnabled() {
> > +        Person person = new Person();
> > +
> > +        try {
> > +            person.setFirstName("InvalidResponse");
> > +            person.setLastName("WhoCares");
> > +            annotatedValidatingClient.saveValidateOut(person);
> > +        } catch (SOAPFaultException sfe) {
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> >     }
> >
> > -    // so this is the default, we are inheriting from the service level
> SchemaValidation annotation
> > -    // which is set to BOTH
> >     @Test
> >     public void testEndpointSchemaValidationProvider() {
> >         Person person = new Person();
> >
> >         try {
> >             client.saveInheritEndpoint(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
> Error"));
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >         }
> > -
> > +
> >         try {
> >             person.setFirstName(""); // empty string is valid
> >             client.saveInheritEndpoint(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
> Error"));
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >         }
> >
> >         person.setLastName(""); // empty string is valid
> > @@ -217,24 +291,27 @@ public class JavaFirstSchemaValidationTest extends
> Assert {
> >
> >         try {
> >             client.saveValidateIn(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
> Error"));
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >         }
> >
> >         try {
> >             person.setFirstName(""); // empty string is valid
> >             client.saveValidateIn(person);
> > +            fail("Expected exception");
> >         } catch (SOAPFaultException sfe) {
> > -            // verify its server side and a schema validation
> > -            assertTrue(sfe.getMessage().contains("Unmarshalling
> Error"));
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Unmarshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> >         }
> >
> >         person.setLastName(""); // empty string is valid
> >         client.saveValidateIn(person);
> >     }
> >
> > -    // no validation at all is required
> >     @Test
> >     public void testSaveNoValidationProvider() {
> >         Person person = new Person();
> > @@ -247,42 +324,94 @@ public class JavaFirstSchemaValidationTest extends
> Assert {
> >         client.saveNoValidation(person);
> >     }
> >
> > -    // no validation is required for incoming
> >     @Test
> > -    public void testSaveValidationOutProvider() {
> > +    public void testSaveValidationOutProviderClientOnly() {
> >         Person person = new Person();
> >
> > -        client.saveValidateOut(person);
> > +        try {
> > +            disconnectedClient.saveValidateOut(person);
> > +            fail("Expected exception");
> > +        } catch (SOAPFaultException sfe) {
> > +            // verify its client side outgoing
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> > +
> > +        person.setFirstName(""); // empty string is valid
> > +        try {
> > +            disconnectedClient.saveValidateOut(person);
> > +            fail("Expected exception");
> > +        } catch (SOAPFaultException sfe) {
> > +            // verify its client side outgoing
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> assertFalse(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> > +
> > +        person.setLastName(""); // empty string is valid
> > +
> > +        // this confirms that we passed client validation as we then
> got the connectivity error
> > +        try {
> > +            disconnectedClient.saveValidateOut(person);
> > +            fail("Expected exception");
> > +        } catch (WebServiceException e) {
> > +            assertTrue(e.getMessage().contains("Could not send
> Message"));
> > +        }
> > +    }
> >
> > +
> > +    @Test
> > +    public void testSaveValidationOutProvider() {
> > +        Person person = new Person();
> > +
> > +        try {
> > +            client.saveValidateOut(person);
> > +        } catch (SOAPFaultException sfe) {
> > +            // verify its server side outgoing
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> > +
> >         person.setFirstName(""); // empty string is valid
> > -        client.saveValidateOut(person);
> > +        try {
> > +            client.saveValidateOut(person);
> > +        } catch (SOAPFaultException sfe) {
> > +            // verify its server side outgoing
> > +            String stackTrace = getStackTrace(sfe);
> > +            assertTrue(stackTrace.contains("Marshalling Error"));
> > +
> assertTrue(stackTrace.contains("org.apache.cxf.binding.soap.SoapFault"));
> > +        }
> >
> >         person.setLastName(""); // empty string is valid
> >         client.saveValidateOut(person);
> >     }
> >
> > -    private static <T> T createClient(Class<T> serviceClass) {
> > +    private static <T> T createClient(String port, Class<T>
> serviceClass, SchemaValidationType type) {
> >         JaxWsProxyFactoryBean clientFactory = new
> JaxWsProxyFactoryBean();
> >         clientFactory.setServiceClass(serviceClass);
> > -
> > -        // ensure all client schema validation is disabled
> > -        Map<String, Object> properties = new HashMap<String, Object>();
> > -        properties.put(Message.SCHEMA_VALIDATION_ENABLED,
> SchemaValidationType.NONE);
> > -        clientFactory.setProperties(properties);
> > -
> > -        clientFactory.setAddress(getAddress(serviceClass));
> > -
> > +
> > +
> > +        clientFactory.setAddress(getAddress(port, serviceClass));
> > +
> > +
> >         @SuppressWarnings("unchecked")
> >         T newClient = (T)clientFactory.create();
> >
> > -        Client clientProxy = ClientProxy.getClient(newClient);
> > -
> > -        // ensure all client schema validation is disabled
> > -        for (BindingOperationInfo bop :
> clientProxy.getEndpoint().getEndpointInfo().getBinding()
> > -            .getOperations()) {
> > -
> bop.getOperationInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED,
> SchemaValidationType.NONE);
> > +        Client proxy = ClientProxy.getClient(newClient);
> > +
> > +        if (type != null) {
> > +
> proxy.getRequestContext().put(Message.SCHEMA_VALIDATION_ENABLED, type);
> >         }
> > -
> > +
> > +        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
> > +        // give me longer debug times
> > +        HTTPClientPolicy clientPolicy = new HTTPClientPolicy();
> > +        clientPolicy.setConnectionTimeout(1000000);
> > +        clientPolicy.setReceiveTimeout(1000000);
> > +        conduit.setClient(clientPolicy);
> > +
> >         return newClient;
> >     }
> >
> > @@ -293,10 +422,17 @@ public class JavaFirstSchemaValidationTest extends
> Assert {
> >         if (features != null) {
> >             svrFactory.getFeatures().addAll(Arrays.asList(features));
> >         }
> > -        svrFactory.setAddress(getAddress(serviceInterface));
> > +        svrFactory.setAddress(getAddress(PORT, serviceInterface));
> >         svrFactory.setServiceBean(serviceImpl);
> >         Server server = svrFactory.create();
> >         serverList.add(server);
> >         return server;
> >     }
> > +
> > +    private String getStackTrace(Exception e) {
> > +        StringWriter sWriter = new StringWriter();
> > +        PrintWriter writer = new PrintWriter(sWriter, true);
> > +        e.printStackTrace(writer);
> > +        return sWriter.toString();
> > +    }
> > }
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> > ----------------------------------------------------------------------
> > diff --git
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> > index e3ee10c..d594e4e 100644
> > ---
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> > +++
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonService.java
> > @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
> >
> > import javax.jws.WebMethod;
> > import javax.jws.WebParam;
> > +import javax.jws.WebResult;
> > import javax.jws.WebService;
> >
> > import org.apache.cxf.annotations.SchemaValidation;
> > @@ -30,14 +31,18 @@ import
> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> > @SchemaValidation(type = SchemaValidationType.BOTH)
> > public interface PersonService {
> >     @WebMethod(operationName = "saveInheritEndpoint")
> > -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
> > +    @WebResult(name = "Person")
> > +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
> >
> >     @WebMethod(operationName = "saveNoValidation")
> > -    void saveNoValidation(@WebParam(name = "Person") Person data);
> > +    @WebResult(name = "Person")
> > +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> >
> >     @WebMethod(operationName = "saveValidateIn")
> > -    void saveValidateIn(@WebParam(name = "Person") Person data);
> > +    @WebResult(name = "Person")
> > +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> >
> >     @WebMethod(operationName = "saveValidateOut")
> > -    void saveValidateOut(@WebParam(name = "Person") Person data);
> > +    @WebResult(name = "Person")
> > +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> > }
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> > ----------------------------------------------------------------------
> > diff --git
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> > index 3e06576..a760f27 100644
> > ---
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> > +++
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotated.java
> > @@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxws.schemavalidation;
> >
> > import javax.jws.WebMethod;
> > import javax.jws.WebParam;
> > +import javax.jws.WebResult;
> > import javax.jws.WebService;
> >
> > import org.apache.cxf.annotations.SchemaValidation;
> > @@ -30,17 +31,21 @@ import
> org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
> > @SchemaValidation(type = SchemaValidationType.BOTH)
> > public interface PersonServiceAnnotated {
> >     @WebMethod(operationName = "saveInheritEndpoint")
> > -    void saveInheritEndpoint(@WebParam(name = "Person") Person data);
> > +    @WebResult(name = "Person")
> > +    Person saveInheritEndpoint(@WebParam(name = "Person") Person data);
> >
> >     @SchemaValidation(type = SchemaValidationType.NONE)
> >     @WebMethod(operationName = "saveNoValidation")
> > -    void saveNoValidation(@WebParam(name = "Person") Person data);
> > +    @WebResult(name = "Person")
> > +    Person saveNoValidation(@WebParam(name = "Person") Person data);
> >
> >     @SchemaValidation(type = SchemaValidationType.IN)
> >     @WebMethod(operationName = "saveValidateIn")
> > -    void saveValidateIn(@WebParam(name = "Person") Person data);
> > +    @WebResult(name = "Person")
> > +    Person saveValidateIn(@WebParam(name = "Person") Person data);
> >
> >     @SchemaValidation(type = SchemaValidationType.OUT)
> >     @WebMethod(operationName = "saveValidateOut")
> > -    void saveValidateOut(@WebParam(name = "Person") Person data);
> > +    @WebResult(name = "Person")
> > +    Person saveValidateOut(@WebParam(name = "Person") Person data);
> > }
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> > ----------------------------------------------------------------------
> > diff --git
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> > index c7b8038..78973c9 100644
> > ---
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> > +++
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceAnnotatedImpl.java
> > @@ -26,18 +26,25 @@ import javax.jws.WebService;
> >     targetNamespace = "
> http://org.apache.cxf/service/PersonServiceAnnotated")
> > public class PersonServiceAnnotatedImpl implements
> PersonServiceAnnotated {
> >     @Override
> > -    public void saveNoValidation(Person data) {
> > +    public Person saveNoValidation(Person data) {
> > +        return data;
> >     }
> >
> >     @Override
> > -    public void saveInheritEndpoint(Person data) {
> > +    public Person saveInheritEndpoint(Person data) {
> > +        return data;
> >     }
> >
> >     @Override
> > -    public void saveValidateIn(Person data) {
> > +    public Person saveValidateIn(Person data) {
> > +        if ("InvalidResponse".equals(data.getFirstName())) {
> > +            return new Person();
> > +        }
> > +        return data;
> >     }
> >
> >     @Override
> > -    public void saveValidateOut(Person data) {
> > +    public Person saveValidateOut(Person data) {
> > +        return data;
> >     }
> > }
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> > ----------------------------------------------------------------------
> > diff --git
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> > index fe1d656..9edec45 100644
> > ---
> a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> > +++
> b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/schemavalidation/PersonServiceImpl.java
> > @@ -26,18 +26,22 @@ import javax.jws.WebService;
> >     targetNamespace = "http://org.apache.cxf/service/PersonService")
> > public class PersonServiceImpl implements PersonService {
> >     @Override
> > -    public void saveNoValidation(Person data) {
> > +    public Person saveNoValidation(Person data) {
> > +        return data;
> >     }
> >
> >     @Override
> > -    public void saveInheritEndpoint(Person data) {
> > +    public Person saveInheritEndpoint(Person data) {
> > +        return data;
> >     }
> >
> >     @Override
> > -    public void saveValidateIn(Person data) {
> > +    public Person saveValidateIn(Person data) {
> > +        return data;
> >     }
> >
> >     @Override
> > -    public void saveValidateOut(Person data) {
> > +    public Person saveValidateOut(Person data) {
> > +        return data;
> >     }
> > }
> >
> >
> http://git-wip-us.apache.org/repos/asf/cxf/blob/27ce514b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> > ----------------------------------------------------------------------
> > diff --git
> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> b/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> > deleted file mode 100644
> > index 18e66ae..0000000
> > ---
> a/systests/uncategorized/src/test/java/org/apache/cxf/systest/mtom_schema_validation/MTOMProviderSchemaValidationTest.bak
> > +++ /dev/null
> > @@ -1,69 +0,0 @@
> > -/**
> > - * Licensed to the Apache Software Foundation (ASF) under one
> > - * or more contributor license agreements. See the NOTICE file
> > - * distributed with this work for additional information
> > - * regarding copyright ownership. The ASF licenses this file
> > - * to you 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.cxf.systest.mtom_schema_validation;
> > -
> > -import java.io.File;
> > -import java.net.URL;
> > -
> > -import javax.activation.DataHandler;
> > -import javax.activation.FileDataSource;
> > -import javax.xml.namespace.QName;
> > -import javax.xml.ws.soap.MTOMFeature;
> > -
> > -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> > -
> > -import org.junit.BeforeClass;
> > -import org.junit.Test;
> > -
> > -public final class MTOMProviderSchemaValidationTest extends
> AbstractBusClientServerTestBase {
> > -    public static final String PORT = "9001";
> > -        //Server.PORT;
> > -
> > -    private final QName serviceName = new QName("http://cxf.apache.org/",
> "HelloWS");
> > -
> > -    @BeforeClass
> > -    public static void startservers() throws Exception {
> > -        //assertTrue("server did not launch correctly",
> launchServer(Server.class, true));
> > -    }
> > -    @Test
> > -    public void testSchemaValidation() throws Exception {
> > -        HelloWS port = createService();
> > -        Hello request = new Hello();
> > -        request.setArg0("value");
> > -        URL wsdl =
> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> > -        File attachment = new File(wsdl.getFile());
> > -        request.setFile(new DataHandler(new
> FileDataSource(attachment)));
> > -        HelloResponse response = port.hello(request);
> > -        assertEquals("Hello CXF", response.getReturn());
> > -    }
> > -
> > -    private HelloWS createService() throws Exception {
> > -        URL wsdl =
> getClass().getResource("/wsdl_systest/mtom_provider_validate.wsdl");
> > -        assertNotNull(wsdl);
> > -
> > -        HelloWSClient service = new HelloWSClient(wsdl, serviceName);
> > -        assertNotNull(service);
> > -
> > -        HelloWS port = service.getHello(new MTOMFeature());
> > -
> > -        updateAddressPort(port, PORT);
> > -
> > -        return port;
> > -    }
> > -}
> >
>
> --
> Daniel Kulp
> dkulp@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
>
>