Repository: cxf Updated Branches: refs/heads/cxf6118 [created] 70c3c88f4
CXF-6118 initial set of changes to 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/70c3c88f Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/70c3c88f Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/70c3c88f Branch: refs/heads/cxf6118 Commit: 70c3c88f42a45dbc45bf5a7b30445e733fc4415c Parents: fa881b5 Author: Jason Pell <[email protected]> Authored: Thu Nov 27 16:54:01 2014 +1100 Committer: Jason Pell <[email protected]> Committed: Thu Nov 27 16:54:01 2014 +1100 ---------------------------------------------------------------------- .../org/apache/cxf/helpers/ServiceUtils.java | 20 +++++++++--- .../AbstractInDatabindingInterceptor.java | 32 +++++++++++++------- .../AbstractOutDatabindingInterceptor.java | 28 ++++++++++++----- .../cxf/transport/ChainInitiationObserver.java | 7 +++++ .../soap/interceptor/RPCInInterceptor.java | 2 +- .../factory/AnnotationsFactoryBeanListener.java | 4 +-- .../JavaFirstSchemaValidationTest.java | 17 ++++++----- 7 files changed, 75 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/70c3c88f/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..db44af9 100644 --- a/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java +++ b/api/src/main/java/org/apache/cxf/helpers/ServiceUtils.java @@ -28,9 +28,9 @@ import javax.xml.namespace.QName; import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType; import org.apache.cxf.message.Message; +import org.apache.cxf.service.model.AbstractPropertiesHolder; public final class ServiceUtils { - private ServiceUtils() { } @@ -49,6 +49,10 @@ public final class ServiceUtils { && SchemaValidationType.BOTH.equals(messageType)); } + public static SchemaValidationType getSchemaValidationType(Message message) { + return getSchemaValidationType(message, SchemaValidationType.BOTH); + } + /** * Determines the appropriate SchemaValidationType to return based on either * a Boolean (for backwards compatibility) or the selected Schema Validation Type. @@ -58,8 +62,10 @@ public final class ServiceUtils { * * @param message */ - static SchemaValidationType getSchemaValidationType(Message message) { - Object obj = message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED); + public static SchemaValidationType getSchemaValidationType(Message message, SchemaValidationType defaultType) { + // we don't actually want to use the getContextualProperty, as that will load up properties from + // the endpoint info, which will override any values set as jaxws:properties + Object obj = message.get(Message.SCHEMA_VALIDATION_ENABLED); if (obj instanceof SchemaValidationType) { return (SchemaValidationType)obj; } else if (obj != null) { @@ -73,8 +79,12 @@ public final class ServiceUtils { } } - // fall through default value - return SchemaValidationType.NONE; + // FIXME - will need to deal with null here now + return defaultType; + } + + public static SchemaValidationType getSchemaValidationType(AbstractPropertiesHolder properties) { + return (SchemaValidationType) properties.getProperty(Message.SCHEMA_VALIDATION_ENABLED); } /** http://git-wip-us.apache.org/repos/asf/cxf/blob/70c3c88f/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..6f09ef8 100644 --- a/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java +++ b/api/src/main/java/org/apache/cxf/interceptor/AbstractInDatabindingInterceptor.java @@ -103,8 +103,9 @@ public abstract class AbstractInDatabindingInterceptor extends AbstractPhaseInte return getDataReader(message, Node.class); } - protected boolean shouldValidate(Message message) { - return ServiceUtils.isSchemaValidationEnabled(SchemaValidationType.IN, message); + protected boolean shouldValidate(Message m) { + SchemaValidationType requiredType = isRequestor(m) ? SchemaValidationType.OUT : SchemaValidationType.IN; + return ServiceUtils.isSchemaValidationEnabled(requiredType, m); } /** @@ -135,12 +136,20 @@ public abstract class AbstractInDatabindingInterceptor extends AbstractPhaseInte * @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(EndpointInfo ep, OperationInfo opInfo, Message message) { + SchemaValidationType validationType = ServiceUtils.getSchemaValidationType(message, null); + if (validationType == null) { + if (opInfo != null) { + validationType = ServiceUtils.getSchemaValidationType(opInfo); + + // else fall back to endpoint level schema validation + if (validationType == null) { + validationType = ServiceUtils.getSchemaValidationType(ep); + } + + if (validationType != null) { + message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType); + } } } } @@ -235,7 +244,6 @@ public abstract class AbstractInDatabindingInterceptor extends AbstractPhaseInte message.put(MessageInfo.class, msgInfo); Exchange ex = message.getExchange(); - ex.put(BindingOperationInfo.class, operation); ex.put(OperationInfo.class, operation.getOperationInfo()); ex.setOneWay(operation.getOperationInfo().isOneWay()); @@ -246,8 +254,10 @@ public abstract class AbstractInDatabindingInterceptor extends AbstractPhaseInte message.put(Message.WSDL_OPERATION, operation.getName()); } + EndpointInfo endpointInfo = ex.getEndpoint().getEndpointInfo(); + // configure endpoint and operation level schema validation - setOperationSchemaValidation(operation.getOperationInfo(), message); + setOperationSchemaValidation(endpointInfo, operation.getOperationInfo(), message); QName serviceQName = si.getName(); message.put(Message.WSDL_SERVICE, serviceQName); @@ -255,7 +265,7 @@ public abstract class AbstractInDatabindingInterceptor extends AbstractPhaseInte QName interfaceQName = si.getInterface().getName(); message.put(Message.WSDL_INTERFACE, interfaceQName); - EndpointInfo endpointInfo = ex.getEndpoint().getEndpointInfo(); + QName portQName = endpointInfo.getName(); message.put(Message.WSDL_PORT, portQName); http://git-wip-us.apache.org/repos/asf/cxf/blob/70c3c88f/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..3dab1b8 100644 --- a/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java +++ b/api/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java @@ -42,6 +42,7 @@ import org.apache.cxf.phase.AbstractPhaseInterceptor; 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.EndpointInfo; import org.apache.cxf.service.model.MessagePartInfo; import org.apache.cxf.service.model.OperationInfo; import org.apache.cxf.staxutils.CachingXmlEventWriter; @@ -84,8 +85,10 @@ public abstract class AbstractOutDatabindingInterceptor extends AbstractPhaseInt XMLStreamWriter xmlWriter = origXmlWriter; CachingXmlEventWriter cache = null; + EndpointInfo endpointInfo = exchange.getEndpoint().getEndpointInfo(); + // configure endpoint and operation level schema validation - setOperationSchemaValidation(operation.getOperationInfo(), message); + setOperationSchemaValidation(endpointInfo, operation.getOperationInfo(), message); // need to cache the events in case validation fails or buffering is enabled if (shouldBuffer(message)) { @@ -167,18 +170,27 @@ public abstract class AbstractOutDatabindingInterceptor extends AbstractPhaseInt * @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); + private void setOperationSchemaValidation(EndpointInfo ep, OperationInfo opInfo, Message message) { + SchemaValidationType validationType = ServiceUtils.getSchemaValidationType(message, null); + if (validationType == null) { + if (opInfo != null) { + validationType = ServiceUtils.getSchemaValidationType(opInfo); + + // else fall back to endpoint level schema validation + if (validationType == null) { + validationType = ServiceUtils.getSchemaValidationType(ep); + } + + if (validationType != null) { + message.put(Message.SCHEMA_VALIDATION_ENABLED, validationType); + } } } } protected boolean shouldValidate(Message m) { - return ServiceUtils.isSchemaValidationEnabled(SchemaValidationType.OUT, m); + SchemaValidationType requiredType = isRequestor(m) ? SchemaValidationType.IN : SchemaValidationType.OUT; + return ServiceUtils.isSchemaValidationEnabled(requiredType, m); } protected boolean writeToOutputStream(Message m, BindingInfo info, Service s) { http://git-wip-us.apache.org/repos/asf/cxf/blob/70c3c88f/api/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java b/api/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java index 74a2af1..ab991c4 100644 --- a/api/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java +++ b/api/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java @@ -28,11 +28,13 @@ import javax.xml.namespace.QName; import org.apache.cxf.Bus; import org.apache.cxf.BusFactory; +import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType; import org.apache.cxf.binding.Binding; import org.apache.cxf.common.classloader.ClassLoaderUtils; import org.apache.cxf.common.classloader.ClassLoaderUtils.ClassLoaderHolder; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.helpers.ServiceUtils; import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.interceptor.InterceptorChain; import org.apache.cxf.interceptor.InterceptorProvider; @@ -88,6 +90,7 @@ public class ChainInitiationObserver implements MessageObserver { m.setExchange(exchange); } exchange.setInMessage(message); + setExchangeProperties(exchange, message); InterceptorProvider dbp = null; @@ -153,11 +156,15 @@ public class ChainInitiationObserver implements MessageObserver { protected void setExchangeProperties(Exchange exchange, Message m) { exchange.put(Endpoint.class, endpoint); + + SchemaValidationType validationType = ServiceUtils.getSchemaValidationType(m); + exchange.put(Binding.class, getBinding()); exchange.put(Bus.class, bus); if (exchange.getDestination() == null) { exchange.setDestination(m.getDestination()); } + if (endpoint != null && endpoint.getService() != null) { exchange.put(Service.class, endpoint.getService()); http://git-wip-us.apache.org/repos/asf/cxf/blob/70c3c88f/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..20225ff 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(endpointInfo, operation.getOperationInfo(), message); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/70c3c88f/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..4541134 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_ENABLED, SchemaValidationType.NONE); } else { - endpoint.put(Message.SCHEMA_VALIDATION_ENABLED, annotation.type()); + endpoint.getEndpointInfo().setProperty(Message.SCHEMA_VALIDATION_ENABLED, annotation.type()); } } } http://git-wip-us.apache.org/repos/asf/cxf/blob/70c3c88f/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..c0babd9 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 @@ -39,7 +39,6 @@ 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.junit.AfterClass; import org.junit.Assert; @@ -103,6 +102,7 @@ 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")); @@ -119,6 +119,7 @@ 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")); @@ -127,6 +128,7 @@ public class JavaFirstSchemaValidationTest extends Assert { 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")); @@ -142,6 +144,7 @@ public class JavaFirstSchemaValidationTest extends Assert { try { annotatedClient.saveValidateIn(person); + fail("Expected exception"); } catch (SOAPFaultException sfe) { // verify its server side and a schema validation assertTrue(sfe.getMessage().contains("Unmarshalling Error")); @@ -150,6 +153,7 @@ public class JavaFirstSchemaValidationTest extends Assert { 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")); @@ -194,6 +198,7 @@ public class JavaFirstSchemaValidationTest extends Assert { try { client.saveInheritEndpoint(person); + fail("Expected exception"); } catch (SOAPFaultException sfe) { // verify its server side and a schema validation assertTrue(sfe.getMessage().contains("Unmarshalling Error")); @@ -202,6 +207,7 @@ public class JavaFirstSchemaValidationTest extends Assert { 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")); @@ -217,6 +223,7 @@ 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")); @@ -225,6 +232,7 @@ public class JavaFirstSchemaValidationTest extends Assert { 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")); @@ -276,13 +284,6 @@ public class JavaFirstSchemaValidationTest extends Assert { 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); - } - return newClient; }
