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/04/17 19:36:02 UTC

svn commit: r1469003 - in /cxf/branches/2.7.x-fixes: ./ 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...

Author: sergeyb
Date: Wed Apr 17 17:36:02 2013
New Revision: 1469003

URL: http://svn.apache.org/r1469003
Log:
Merged revisions 1469001 via svnmerge from 
https://svn.apache.org/repos/asf/cxf/trunk

........
  r1469001 | sergeyb | 2013-04-17 18:14:32 +0100 (Wed, 17 Apr 2013) | 1 line
  
  [CXF-4969] Mapping exceptions thrown from per-request root resource constructors, parameter or context setters
........

Modified:
    cxf/branches/2.7.x-fixes/   (props changed)
    cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
    cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
    cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
    cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
    cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java
    cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java

Propchange: cxf/branches/2.7.x-fixes/
------------------------------------------------------------------------------
    svn:mergeinfo = /cxf/trunk:1469001

Propchange: cxf/branches/2.7.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java?rev=1469003&r1=1469002&r2=1469003&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java (original)
+++ cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java Wed Apr 17 17:36:02 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.getResponseObject());
-            }
-        }
-        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.getResponseObject());
         }
         
-        
-        
         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) {
@@ -276,15 +280,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/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java?rev=1469003&r1=1469002&r2=1469003&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java (original)
+++ cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java Wed Apr 17 17:36:02 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/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=1469003&r1=1469002&r2=1469003&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java (original)
+++ cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java Wed Apr 17 17:36:02 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/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=1469003&r1=1469002&r2=1469003&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Wed Apr 17 17:36:02 2013
@@ -283,7 +283,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()) {
@@ -304,7 +304,6 @@ public final class JAXRSUtils {
             }
             InjectionUtils.injectFieldValue(f, requestObject, o);
         }
-        
     }
     
     public static ClassResourceInfo selectResourceClass(List<ClassResourceInfo> resources,
@@ -1560,6 +1559,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/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java?rev=1469003&r1=1469002&r2=1469003&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java (original)
+++ cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStorePerRequest.java Wed Apr 17 17:36:02 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/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=1469003&r1=1469002&r2=1469003&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java (original)
+++ cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java Wed Apr 17 17:36:02 2013
@@ -1442,6 +1442,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",