You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2013/11/20 14:39:25 UTC

svn commit: r1543813 - in /cxf/trunk: core/src/main/java/org/apache/cxf/validation/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/

Author: sergeyb
Date: Wed Nov 20 13:39:24 2013
New Revision: 1543813

URL: http://svn.apache.org/r1543813
Log:
[CXF-5401] Response entity validation, patch from Andriy Redko applied, with few more updates

Modified:
    cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationInInterceptor.java
    cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationOutInterceptor.java
    cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInvoker.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationOutInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/ValidationUtils.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/BookStoreWithValidation.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSClientServerValidationTest.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSPerRequestValidationTest.java

Modified: cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationInInterceptor.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationInInterceptor.java (original)
+++ cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationInInterceptor.java Wed Nov 20 13:39:24 2013
@@ -36,7 +36,9 @@ public class ValidationInInterceptor ext
     protected void handleValidation(final Message message, final Object resourceInstance,
                                     final Method method, final List<Object> arguments) {
         ValidationProvider provider = getProvider(message);
-        provider.validateParameters(resourceInstance, method, arguments.toArray());
+        if (arguments.size() > 0) {
+            provider.validateParameters(resourceInstance, method, arguments.toArray());
+        }
         message.getExchange().put(ValidationProvider.class, provider);
     }
 }

Modified: cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationOutInterceptor.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationOutInterceptor.java (original)
+++ cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationOutInterceptor.java Wed Nov 20 13:39:24 2013
@@ -25,6 +25,7 @@ import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.Phase;
 
 public class ValidationOutInterceptor extends AbstractValidationInterceptor {
+    private boolean enforceOnlyBeanConstraints;
     public ValidationOutInterceptor() {
         super(Phase.PRE_MARSHAL);
     }
@@ -36,14 +37,31 @@ public class ValidationOutInterceptor ex
     protected void handleValidation(final Message message, final Object resourceInstance,
                                     final Method method, final List<Object> arguments) {  
         if (arguments.size() == 1) {
-            getOutProvider(message).validateReturnValue(resourceInstance, method, arguments.get(0));
+            Object entity = unwrapEntity(arguments.get(0));
+            ValidationProvider theProvider = getOutProvider(message);
+            if (isEnforceOnlyBeanConstraints()) {
+                theProvider.validateReturnValue(entity);    
+            } else {
+                theProvider.validateReturnValue(resourceInstance, method, entity);
+            }
         }        
     }
     
+    protected Object unwrapEntity(Object entity) {
+        return entity;
+    }
+    
     protected ValidationProvider getOutProvider(Message message) {
         ValidationProvider provider = message.getExchange().get(ValidationProvider.class);
         return provider == null ? getProvider(message) : provider;
     }
+    
+    public boolean isEnforceOnlyBeanConstraints() {
+        return enforceOnlyBeanConstraints;
+    }
+    public void setEnforceOnlyBeanConstraints(boolean enforceOnlyBeanConstraints) {
+        this.enforceOnlyBeanConstraints = enforceOnlyBeanConstraints;
+    }
         
     
 }

Modified: cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationProvider.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationProvider.java (original)
+++ cxf/trunk/core/src/main/java/org/apache/cxf/validation/ValidationProvider.java Wed Nov 20 13:39:24 2013
@@ -27,7 +27,6 @@ import javax.validation.Configuration;
 import javax.validation.ConstraintViolation;
 import javax.validation.ConstraintViolationException;
 import javax.validation.ParameterNameProvider;
-import javax.validation.Valid;
 import javax.validation.Validation;
 import javax.validation.ValidationException;
 import javax.validation.ValidationProviderResolver;
@@ -131,24 +130,13 @@ public class ValidationProvider {
         }                
     }
     
-    public< T > void validateReturnValue(final T returnValue) {
-        final Set<ConstraintViolation< T > > violations = doValidateBean(returnValue);
+    public< T > void validateReturnValue(final T bean) {
+        final Set<ConstraintViolation< T > > violations = doValidateBean(bean);
         if (!violations.isEmpty()) {
             throw new ResponseConstraintViolationException(violations);
         }                
     }
     
-    public< T > void validateReturnValue(Method m, final T returnValue) {
-        if (m.getAnnotation(Valid.class) == null) {
-            return;
-        }
-        //TODO: check Method annotations for Constraints
-        
-        if (returnValue != null) {
-            validateReturnValue(returnValue);
-        } 
-    }
-    
     public< T > void validateBean(final T bean) {
         final Set<ConstraintViolation< T > > violations = doValidateBean(bean);
         if (!violations.isEmpty()) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInInterceptor.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInInterceptor.java Wed Nov 20 13:39:24 2013
@@ -20,7 +20,9 @@ package org.apache.cxf.jaxrs.validation;
 
 import java.io.IOException;
 import java.lang.reflect.Method;
+import java.util.List;
 
+import javax.validation.ValidationException;
 import javax.ws.rs.container.ContainerRequestContext;
 import javax.ws.rs.container.ContainerRequestFilter;
 
@@ -29,8 +31,8 @@ import org.apache.cxf.phase.PhaseInterce
 import org.apache.cxf.validation.ValidationInInterceptor;
 
 
-public class JAXRSValidationInInterceptor extends ValidationInInterceptor 
-    implements ContainerRequestFilter {
+public class JAXRSValidationInInterceptor extends ValidationInInterceptor implements ContainerRequestFilter {
+    static final String INPUT_VALIDATION_FAILED = "input.validation.failed";
     public JAXRSValidationInInterceptor() {
     }
     public JAXRSValidationInInterceptor(String phase) {
@@ -43,13 +45,17 @@ public class JAXRSValidationInIntercepto
     }
     
     @Override
-    protected Method getServiceMethod(Message message) {
-        if (!ValidationUtils.isAnnotatedMethodAvailable(message)) {
-            return null;
-        } else {
-            return super.getServiceMethod(message);
+    protected void handleValidation(final Message message, final Object resourceInstance,
+                                    final Method method, final List<Object> arguments) {
+        try {
+            super.handleValidation(message, resourceInstance, method, arguments);
+        } catch (ValidationException ex) {
+            message.getExchange().put(INPUT_VALIDATION_FAILED, true);
+            throw ex;
         }
     }
+    
+    
     @Override
     public void filter(ContainerRequestContext context) throws IOException {
         super.handleMessage(PhaseInterceptorChain.getCurrentMessage());

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInvoker.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInvoker.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInvoker.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationInvoker.java Wed Nov 20 13:39:24 2013
@@ -20,12 +20,9 @@ package org.apache.cxf.jaxrs.validation;
 
 import java.lang.reflect.Method;
 import java.util.List;
-import java.util.logging.Logger;
 
-import javax.validation.ValidationException;
 import javax.ws.rs.core.Response;
 
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.jaxrs.JAXRSInvoker;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.message.Exchange;
@@ -35,7 +32,6 @@ import org.apache.cxf.validation.Validat
 
 
 public class JAXRSValidationInvoker extends JAXRSInvoker {
-    private static final Logger LOG = LogUtils.getL7dLogger(JAXRSValidationInvoker.class);
     private volatile ValidationProvider provider;
     private boolean validateServiceObject = true;
     
@@ -43,12 +39,6 @@ public class JAXRSValidationInvoker exte
     public Object invoke(Exchange exchange, final Object serviceObject, Method m, List<Object> params) {
         Message message = JAXRSUtils.getCurrentMessage();
         
-        if (!ValidationUtils.isAnnotatedMethodAvailable(message)) {
-            String error = "Resource method is not available";
-            LOG.severe(error);
-            throw new ValidationException(error);
-        }
-        
         ValidationProvider theProvider = getProvider(message);
         
         if (isValidateServiceObject()) {
@@ -65,7 +55,7 @@ public class JAXRSValidationInvoker exte
                 Object entity = ((MessageContentsList)list).get(0);
                 
                 if (entity instanceof Response) {
-                    theProvider.validateReturnValue(m, ((Response)entity).getEntity());    
+                    theProvider.validateReturnValue(serviceObject, m, ((Response)entity).getEntity());    
                 } else {                
                     theProvider.validateReturnValue(serviceObject, m, entity);
                 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationOutInterceptor.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationOutInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/JAXRSValidationOutInterceptor.java Wed Nov 20 13:39:24 2013
@@ -27,6 +27,7 @@ import javax.ws.rs.container.ContainerRe
 import javax.ws.rs.container.ContainerResponseFilter;
 import javax.ws.rs.core.Response;
 
+import org.apache.cxf.common.util.PropertyUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.validation.ValidationOutInterceptor;
@@ -41,30 +42,23 @@ public class JAXRSValidationOutIntercept
     }
     
     @Override
-    protected Object getServiceObject(Message message) {
-        return ValidationUtils.getResourceInstance(message);
+    protected void handleValidation(final Message message, final Object resourceInstance,
+                                    final Method method, final List<Object> arguments) {
+        if (!PropertyUtils.isTrue(message.getExchange().get(JAXRSValidationInInterceptor.INPUT_VALIDATION_FAILED))) {
+            super.handleValidation(message, resourceInstance, method, arguments);
+        }
     }
     
     @Override
-    protected Method getServiceMethod(Message message) {
-        if (!ValidationUtils.isAnnotatedMethodAvailable(message)) {
-            return null;
-        } else {
-            return super.getServiceMethod(message);
-        }
+    protected Object getServiceObject(Message message) {
+        return ValidationUtils.getResourceInstance(message);
     }
     
     @Override
-    protected void handleValidation(final Message message, final Object resourceInstance,
-                                    final Method method, final List<Object> arguments) {  
-        if (arguments.size() == 1) {
-            if (arguments.get(0) instanceof Response) {
-                getOutProvider(message).validateReturnValue(method, ((Response)arguments.get(0)).getEntity());    
-            } else {
-                super.handleValidation(message, resourceInstance, method, arguments);
-            }
-        }        
+    protected Object unwrapEntity(Object entity) {
+        return entity instanceof Response ? ((Response)entity).getEntity() : entity;
     }
+    
     @Override
     public void filter(ContainerRequestContext in, ContainerResponseContext out) throws IOException {
         super.handleMessage(PhaseInterceptorChain.getCurrentMessage());

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/ValidationUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/ValidationUtils.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/ValidationUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/validation/ValidationUtils.java Wed Nov 20 13:39:24 2013
@@ -42,13 +42,5 @@ public final class ValidationUtils {
         }
     }
     
-    public static boolean isAnnotatedMethodAvailable(Message message) {
-        final OperationResourceInfo ori = message.getExchange().get(OperationResourceInfo.class);
-        
-        // If this is a user-model resource then no validation is possible
-        return ori.getAnnotatedMethod() != null;
-        
-    }
-    
     
 }

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/BookStoreWithValidation.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/BookStoreWithValidation.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/BookStoreWithValidation.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/BookStoreWithValidation.java Wed Nov 20 13:39:24 2013
@@ -48,19 +48,25 @@ public class BookStoreWithValidation ext
 
     @GET
     @Path("/books/{bookId}")
-    @Override
-    @NotNull 
+    @Override    
+    @NotNull
     public BookWithValidation getBook(@PathParam("bookId") String id) {
         return books.get(id);
     }
     
     @GET
     @Path("/booksResponse/{bookId}")
-    @Valid
+    @Valid @NotNull
     public Response getBookResponse(@PathParam("bookId") String id) {
         return Response.ok(books.get(id)).build();
     }
     
+    @GET
+    @Path("/booksResponseNoValidation/{bookId}")
+    public Response getBookResponseNoValidation(@PathParam("bookId") String id) {
+        return Response.ok(books.get(id)).build();
+    }
+    
     @POST
     @Path("/books")
     public Response addBook(@Context final UriInfo uriInfo, 

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSClientServerValidationTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSClientServerValidationTest.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSClientServerValidationTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSClientServerValidationTest.java Wed Nov 20 13:39:24 2013
@@ -86,7 +86,7 @@ public class JAXRSClientServerValidation
     public static void startServers() throws Exception {
         AbstractResourceInfo.clearAllMaps();
         //keep out of process due to stack traces testing failures
-        assertTrue("server did not launch correctly", launchServer(Server.class));
+        assertTrue("server did not launch correctly", launchServer(Server.class, true));
         createStaticBus();
     }
     
@@ -182,12 +182,28 @@ public class JAXRSClientServerValidation
     
     @Test
     public void testThatResponseValidationForOneResponseBookFails()  {
-        Response r = createWebClient("/bookstore/books").post(new Form().param("id", "1234"));
+        Response r = createWebClient("/bookstore/booksResponse/1234").get();
+        assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), r.getStatus());
+
+        r = createWebClient("/bookstore/books").post(new Form().param("id", "1234"));
         assertEquals(Status.CREATED.getStatusCode(), r.getStatus());
 
         r = createWebClient("/bookstore/booksResponse/1234").get();
         assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), r.getStatus());
     }
+    
+
+    @Test
+    public void testThatResponseValidationForBookPassesWhenNoConstraintsAreDefined()  {
+        Response r = createWebClient("/bookstore/booksResponseNoValidation/1234").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+        
+        r = createWebClient("/bookstore/books").post(new Form().param("id", "1234"));
+        assertEquals(Status.CREATED.getStatusCode(), r.getStatus());
+
+        r = createWebClient("/bookstore/booksResponseNoValidation/1234").get();
+        assertEquals(Status.OK.getStatusCode(), r.getStatus());
+    }
 
     @Test
     public void testThatResponseValidationForAllBooksFails()  {

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSPerRequestValidationTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSPerRequestValidationTest.java?rev=1543813&r1=1543812&r2=1543813&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSPerRequestValidationTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSPerRequestValidationTest.java Wed Nov 20 13:39:24 2013
@@ -85,8 +85,8 @@ public class JAXRSPerRequestValidationTe
         final Response r = createWebClient("/bookstore/book").query("id", "3333").get();
         assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), r.getStatus());
     }
-    @Test
-    @Ignore
+    
+    @Test    
     public void testThatValidationConstraintsAreViolatedWhenBookDoesNotExistResponse()  {
         final Response r = createWebClient("/bookstore/bookResponse").query("id", "3333").get();
         assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), r.getStatus());