cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1469001 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ systests/jaxrs/src/test/java/org/apa...
Date Wed, 17 Apr 2013 17:14:33 GMT
Author: sergeyb
Date: Wed Apr 17 17:14:32 2013
New Revision: 1469001

URL: http://svn.apache.org/r1469001
Log:
[CXF-4969] Mapping exceptions thrown from per-request root resource constructors, parameter
or context setters

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java?rev=1469001&r1=1469000&r2=1469001&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java Wed Apr
17 17:14:32 2013
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.ResourceBundle;
 import java.util.logging.Logger;
 
+import javax.ws.rs.InternalServerErrorException;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.container.AsyncResponse;
@@ -78,28 +79,31 @@ public class JAXRSInvoker extends Abstra
     }
 
     public Object invoke(Exchange exchange, Object request) {
-        Response response = exchange.get(Response.class);
-        if (response == null) {
-            AsyncResponse asyncResp = exchange.get(AsyncResponse.class);
-            if (asyncResp != null) {
-                AsyncResponseImpl asyncImpl = (AsyncResponseImpl)asyncResp;
-                asyncImpl.prepareContinuation();
-                asyncImpl.handleTimeout();
-                return handleAsyncResponse(exchange, asyncImpl);
-            }
-        }
-        if (response != null) {
-            return new MessageContentsList(response);
+        MessageContentsList responseList = checkExchangeForResponse(exchange);
+        if (responseList != null) {
+            return responseList; 
+        }
+        AsyncResponse asyncResp = exchange.get(AsyncResponse.class);
+        if (asyncResp != null) {
+            AsyncResponseImpl asyncImpl = (AsyncResponseImpl)asyncResp;
+            asyncImpl.prepareContinuation();
+            asyncImpl.handleTimeout();
+            return handleAsyncResponse(exchange, asyncImpl);
         }
         
-        
-        
         ResourceProvider provider = getResourceProvider(exchange);
-        Object rootInstance = getServiceObject(exchange);
-        Object serviceObject = getActualServiceObject(exchange, rootInstance);
-        
+        Object rootInstance = null;
         try {
+            rootInstance = getServiceObject(exchange);
+            Object serviceObject = getActualServiceObject(exchange, rootInstance);
+            
             return invoke(exchange, request, serviceObject);
+        } catch (InternalServerErrorException ex) {
+            responseList = checkExchangeForResponse(exchange);
+            if (responseList != null) {
+                return responseList; 
+            }
+            return handleFault(ex, exchange.getInMessage());
         } finally {
             boolean suspended = exchange.getInMessage().getInterceptorChain().getState()
== State.SUSPENDED;
             if (!suspended) {
@@ -281,15 +285,27 @@ public class JAXRSInvoker extends Abstra
         return result;
     }
     
+    private MessageContentsList checkExchangeForResponse(Exchange exchange) {
+        Response r = exchange.get(Response.class);
+        if (r != null) {
+            JAXRSUtils.setMessageContentType(exchange.getInMessage(), r);
+            return new MessageContentsList(r);
+        } else {
+            return null;
+        }
+    }
+    
     private void setResponseContentTypeIfNeeded(Message inMessage, Object response) {
         if (response instanceof Response) {
             JAXRSUtils.setMessageContentType(inMessage, (Response)response);
         }
     }
-    
+    private Object handleFault(Throwable ex, Message inMessage) {
+        return handleFault(new Fault(ex), inMessage, null, null);
+    }
     private Object handleFault(Fault ex, Message inMessage, 
                                ClassResourceInfo cri, Method methodToInvoke) {
-        String errorMessage = ex.getCause().getMessage();
+        String errorMessage = ex.getMessage();
         if (errorMessage != null && cri != null 
             && errorMessage.contains(PROXY_INVOCATION_ERROR_FRAGMENT)) {
             org.apache.cxf.common.i18n.Message errorM =

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java?rev=1469001&r1=1469000&r2=1469001&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
Wed Apr 17 17:14:32 2013
@@ -27,6 +27,7 @@ import javax.ws.rs.InternalServerErrorEx
 import javax.ws.rs.core.Response;
 
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.jaxrs.utils.ResourceUtils;
 import org.apache.cxf.message.Message;
 
@@ -78,6 +79,11 @@ public class PerRequestResourceProvider 
                 + " due to IllegalAccessException";
             throw new InternalServerErrorException(Response.serverError().entity(msg).build());
         } catch (InvocationTargetException ex) {
+            Response r = JAXRSUtils.convertFaultToResponse(ex.getCause(), m);
+            if (r != null) {
+                m.getExchange().put(Response.class, r);
+                throw new InternalServerErrorException();
+            }
             String msg = "Resource class "
                 + c.getDeclaringClass().getName() + " can not be instantiated"
                 + " due to InvocationTargetException";

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=1469001&r1=1469000&r2=1469001&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
Wed Apr 17 17:14:32 2013
@@ -259,13 +259,27 @@ public final class InjectionUtils {
     }
     
     public static void injectThroughMethod(Object requestObject,
-                                           Method method,
-                                           Object parameterValue) {
+                                               Method method,
+                                               Object parameterValue) {
+        injectThroughMethod(requestObject, method, parameterValue, null);
+    }
+    
+    public static void injectThroughMethod(Object requestObject,
+                                               Method method,
+                                               Object parameterValue,
+                                               Message inMessage) {
         try {
             Method methodToInvoke = checkProxy(method, requestObject);
             methodToInvoke.invoke(requestObject, new Object[]{parameterValue});
         } catch (IllegalAccessException ex) {
             reportServerError("METHOD_ACCESS_FAILURE", method.getName());
+        } catch (InvocationTargetException ex) {
+            Response r = JAXRSUtils.convertFaultToResponse(ex.getCause(), inMessage);
+            if (r != null) {
+                inMessage.getExchange().put(Response.class, r);
+                throw new InternalServerErrorException();
+            }
+            reportServerError("METHOD_ACCESS_FAILURE", method.getName());
         } catch (Exception ex) {
             reportServerError("METHOD_INJECTION_FAILURE", method.getName());
         }
@@ -968,7 +982,7 @@ public final class InjectionUtils {
             
             if (o != null) {
                 if (!cri.isSingleton()) {
-                    InjectionUtils.injectThroughMethod(requestObject, method, o);
+                    InjectionUtils.injectThroughMethod(requestObject, method, o, message);
                 } else {
                     ThreadLocalProxy<Object> proxy 
                         = (ThreadLocalProxy<Object>)cri.getContextSetterProxy(method);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=1469001&r1=1469000&r2=1469001&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Wed
Apr 17 17:14:32 2013
@@ -290,7 +290,7 @@ public final class JAXRSUtils {
                                                 values,
                                                 ori);
             }
-            InjectionUtils.injectThroughMethod(requestObject, m, o);
+            InjectionUtils.injectThroughMethod(requestObject, m, o, message);
         }
         // Param fields
         for (Field f : bri.getParameterFields()) {
@@ -311,7 +311,6 @@ public final class JAXRSUtils {
             }
             InjectionUtils.injectFieldValue(f, requestObject, o);
         }
-        
     }
     
     public static Map<ClassResourceInfo, MultivaluedMap<String, String>> selectResourceClass(
@@ -1610,6 +1609,9 @@ public final class JAXRSUtils {
     }
     
     public static <T extends Throwable> Response convertFaultToResponse(T ex, Message
currentMessage) {
+        if (ex == null || currentMessage == null) {
+            return null;
+        }
         Message inMessage = currentMessage.getExchange().getInMessage();
         Response response = null;
         if (ex.getClass() == WebApplicationException.class) {

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java?rev=1469001&r1=1469000&r2=1469001&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java
(original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java
Wed Apr 17 17:14:32 2013
@@ -24,11 +24,13 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.ws.rs.ClientErrorException;
 import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
 
 @Path("/bookstore2")
 public class BookStorePerRequest {
@@ -36,6 +38,7 @@ public class BookStorePerRequest {
     private HttpHeaders httpHeaders;
     private Map<Long, Book> books = new HashMap<Long, Book>();
     private List<String> bookIds;
+    private List<String> setterBookIds;
     
     public BookStorePerRequest() {
         throw new RuntimeException();
@@ -51,11 +54,33 @@ public class BookStorePerRequest {
     
     public BookStorePerRequest(@Context HttpHeaders headers,
                                @HeaderParam("BOOK") List<String> bookIds) {
+        if (!bookIds.contains("3")) {
+            throw new ClientErrorException(Response.status(400).type("text/plain")
+                                           .entity("Constructor: Header value 3 is required").build());
+        }
         httpHeaders = headers;
         this.bookIds = bookIds;
         init();
     }
     
+    @HeaderParam("Book")
+    public void setBook(List<String> ids) {
+        if (!ids.equals(bookIds) || ids.size() != 3) {
+            throw new ClientErrorException(Response.status(400).type("text/plain")
+                                           .entity("Param setter: 3 header values are required").build());
+        }
+        setterBookIds = ids;
+    }
+    
+    @Context
+    public void setHttpHeaders(HttpHeaders headers) {
+        List<String> ids = httpHeaders.getRequestHeader("BOOK");
+        if (ids.contains("4")) {
+            throw new ClientErrorException(Response.status(400).type("text/plain")
+                                           .entity("Context setter: unexpected header value").build());
+        }
+    }
+    
     @GET
     @Path("/bookheaders/")
     public Book getBookByHeader() throws Exception {
@@ -67,6 +92,13 @@ public class BookStorePerRequest {
         return doGetBook(ids.get(0) + ids.get(1) + ids.get(2));
     }
     
+    @GET
+    @Path("/bookheaders/injected")
+    public Book getBookByHeaderInjected() throws Exception {
+        
+        return doGetBook(setterBookIds.get(0) + setterBookIds.get(1) + setterBookIds.get(2));
+    }
+    
     private Book doGetBook(String id) throws BookNotFoundFault {
         Book book = books.get(Long.parseLong(id));
         if (book != null) {

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=1469001&r1=1469000&r2=1469001&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
(original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
Wed Apr 17 17:14:32 2013
@@ -1443,6 +1443,50 @@ public class JAXRSClientServerBookTest e
     }
     
     @Test
+    public void testGetBookByHeaderPerRequestInjected() throws Exception {
+        String address = "http://localhost:" + PORT + "/bookstore2/bookheaders/injected";
+        WebClient wc = WebClient.create(address);
+        wc.accept("application/xml");
+        wc.header("BOOK", "1", "2", "3");
+        Book b = wc.get(Book.class);
+        assertEquals(123L, b.getId());
+    }
+    
+    @Test
+    public void testGetBookByHeaderPerRequestInjectedFault() throws Exception {
+        String address = "http://localhost:" + PORT + "/bookstore2/bookheaders/injected";
+        WebClient wc = WebClient.create(address);
+        wc.accept("application/xml");
+        wc.header("BOOK", "2", "3");
+        Response r = wc.get();
+        assertEquals(400, r.getStatus());
+        assertEquals("Param setter: 3 header values are required", r.readEntity(String.class));
+    }
+    
+    @Test
+    public void testGetBookByHeaderPerRequestConstructorFault() throws Exception {
+        String address = "http://localhost:" + PORT + "/bookstore2/bookheaders";
+        WebClient wc = WebClient.create(address);
+        wc.accept("application/xml");
+        wc.header("BOOK", "1", "2", "4");
+        Response r = wc.get();
+        assertEquals(400, r.getStatus());
+        assertEquals("Constructor: Header value 3 is required", r.readEntity(String.class));
+    }
+    
+    @Test
+    public void testGetBookByHeaderPerRequestContextFault() throws Exception {
+        String address = "http://localhost:" + PORT + "/bookstore2/bookheaders";
+        WebClient wc = WebClient.create(address);
+        WebClient.getConfig(wc).getHttpConduit().getClient().setReceiveTimeout(1000000);
+        wc.accept("application/xml");
+        wc.header("BOOK", "1", "3", "4");
+        Response r = wc.get();
+        assertEquals(400, r.getStatus());
+        assertEquals("Context setter: unexpected header value", r.readEntity(String.class));
+    }
+    
+    @Test
     public void testGetBookByHeaderDefault() throws Exception {
         getAndCompareAsStrings("http://localhost:" + PORT + "/bookstore/bookheaders2",
                                "resources/expected_get_book123.txt",



Mime
View raw message