You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2009/07/31 22:14:23 UTC

svn commit: r799739 - in /cxf/branches/2.2.x-fixes: ./ rt/core/src/main/java/org/apache/cxf/interceptor/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ rt/transports/http/src/main/java/org/apache/cxf/transport/http/ systests/src/test/java...

Author: dkulp
Date: Fri Jul 31 20:14:22 2009
New Revision: 799739

URL: http://svn.apache.org/viewvc?rev=799739&view=rev
Log:
Merged revisions 799723 via svnmerge from 
https://svn.apache.org/repos/asf/cxf/trunk

........
  r799723 | dkulp | 2009-07-31 15:54:22 -0400 (Fri, 31 Jul 2009) | 2 lines
  
  [CXF-2373] Fix for some JAX-RS fault handling issues
  Patch from Eamonn Dwyer applied
........

Modified:
    cxf/branches/2.2.x-fixes/   (props changed)
    cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/InFaultChainInitiatorObserver.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
    cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
    cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java
    cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 31 20:14:22 2009
@@ -1 +1 @@
-/cxf/trunk:782728-782730,783097,783294,783396,784059,784181-784184,784893,784895,785279-785282,785468,785621,785624,785651,785734,785866,786142,786271-786272,786395,786512,786514,786582-786583,786638,786647,786850,787200,787269,787277-787279,787290-787291,787305,787323,787366,787849,788030,788060,788187,788444,788451,788703,788752,788774,788819-788820,789013,789371,789387,789420,789527-789530,789704-789705,789788,789811,789896-789901,790074,790094,790134,790188,790294,790553,790637-790644,790868,791301,791354,791538,791753,791947,792007,792096,792183,792261-792265,792271,792604,792683-792685,792975,792985,793059,793570,794297,794396,794680,794728,794771,794778-794780,794892,795044,795104,795160,795583,795907,796022-796023,796352,796593,796741,796780,796994-796997,797117,797159,797192,797194,797231-797233,797442,797505,797517,797534,797581-797583,797587,797640,797651,797699,797882-797883,798344-798346,798363,798461,798479,798533,798551,798557,798561-798562,798570,798573,79858
 4,798654,798748-798749,798891,798929-798930,799267,799439,799448,799637
+/cxf/trunk:782728-782730,783097,783294,783396,784059,784181-784184,784893,784895,785279-785282,785468,785621,785624,785651,785734,785866,786142,786271-786272,786395,786512,786514,786582-786583,786638,786647,786850,787200,787269,787277-787279,787290-787291,787305,787323,787366,787849,788030,788060,788187,788444,788451,788703,788752,788774,788819-788820,789013,789371,789387,789420,789527-789530,789704-789705,789788,789811,789896-789901,790074,790094,790134,790188,790294,790553,790637-790644,790868,791301,791354,791538,791753,791947,792007,792096,792183,792261-792265,792271,792604,792683-792685,792975,792985,793059,793570,794297,794396,794680,794728,794771,794778-794780,794892,795044,795104,795160,795583,795907,796022-796023,796352,796593,796741,796780,796994-796997,797117,797159,797192,797194,797231-797233,797442,797505,797517,797534,797581-797583,797587,797640,797651,797699,797882-797883,798344-798346,798363,798461,798479,798533,798551,798557,798561-798562,798570,798573,79858
 4,798654,798748-798749,798891,798929-798930,799267,799439,799448,799637,799723

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

Modified: cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/InFaultChainInitiatorObserver.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/InFaultChainInitiatorObserver.java?rev=799739&r1=799738&r2=799739&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/InFaultChainInitiatorObserver.java (original)
+++ cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/InFaultChainInitiatorObserver.java Fri Jul 31 20:14:22 2009
@@ -37,10 +37,13 @@
     protected void initializeInterceptors(Exchange ex, PhaseInterceptorChain chain) {
         Endpoint e = ex.get(Endpoint.class);
         Client c = ex.get(Client.class);
+        InterceptorProvider ip = ex.get(InterceptorProvider.class);
         
         chain.add(getBus().getInFaultInterceptors());
         if (c != null) {
             chain.add(c.getInFaultInterceptors());
+        } else if (ip != null) {
+            chain.add(ip.getInFaultInterceptors());
         }
         chain.add(e.getService().getInFaultInterceptors());
         chain.add(e.getInFaultInterceptors());

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=799739&r1=799738&r2=799739&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Fri Jul 31 20:14:22 2009
@@ -291,13 +291,22 @@
         currentBuilder = new UriBuilderImpl(uri);
     }
     
-    protected ResponseBuilder setResponseBuilder(HttpURLConnection conn, Message inMessage) throws Throwable {
-        
+    protected ResponseBuilder setResponseBuilder(HttpURLConnection conn, Exchange exchange) throws Throwable {
+        Message inMessage = exchange.getInMessage();
         if (conn == null) {
             throw new WebApplicationException(); 
         }
-        
-        int status = conn.getResponseCode();
+        Integer responseCode = (Integer)exchange.get(Message.RESPONSE_CODE);
+        if (responseCode == null) {
+            //Invocation was never made to server, something stopped the outbound 
+            //interceptor chain, we dont have a response code.
+            //Do not call conn.getResponseCode() as that will
+            //result in a call to the server when we have already decided not to.
+            //Throw an exception if we have one
+            Exception ex = exchange.getOutMessage().getContent(Exception.class);
+            throw ex;
+        } 
+        int status = responseCode.intValue(); //conn.getResponseCode();
         responseBuilder = Response.status(status);
         for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
             if (null == entry.getKey()) {

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java?rev=799739&r1=799738&r2=799739&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java Fri Jul 31 20:14:22 2009
@@ -43,8 +43,10 @@
 
 import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
 import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.InterceptorProvider;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.model.OperationResourceInfo;
@@ -199,25 +201,41 @@
         return index;
     }
     
-    private static void checkResponse(Method m, Response r, Message message) throws Throwable {
-        
+    private void checkResponse(Method m, Response r, Message inMessage) throws Throwable {
+        Throwable t = null;
         int status = r.getStatus();
         
         if (status >= 400) {
-            
             if (m.getReturnType() == Response.class && m.getExceptionTypes().length == 0) {
                 return;
-            }
-            
-            ResponseExceptionMapper<?> mapper = findExceptionMapper(m, message);
+            }            
+            ResponseExceptionMapper<?> mapper = findExceptionMapper(m, inMessage);
             if (mapper != null) {
-                Throwable t = mapper.fromResponse(r);
+                t = mapper.fromResponse(r);
                 if (t != null) {
                     throw t;
                 }
+            } 
+                        
+            if (t == null) {
+                t = new WebApplicationException(r);
+            }
+
+            
+            if (inMessage.getExchange().get(Message.RESPONSE_CODE) == null) {
+                throw t;
             }
             
-            throw new WebApplicationException(r);
+            Endpoint ep = inMessage.getExchange().get(Endpoint.class);
+            inMessage.getExchange().put(InterceptorProvider.class, getConfiguration());
+            inMessage.setContent(Exception.class, new Fault(t));
+            inMessage.getInterceptorChain().abort();
+            if (ep.getInFaultObserver() != null) {
+                ep.getInFaultObserver().onMessage(inMessage);
+            }
+            
+            throw t;
+            
         }
     }
     
@@ -392,7 +410,7 @@
             m.getInterceptorChain().add(new BodyWriter());
         }
         
-        // execute chain        
+        // execute chain    
         try {
             m.getInterceptorChain().doIntercept(m);
         } catch (Throwable ex) {
@@ -407,7 +425,7 @@
     
     protected Object handleResponse(HttpURLConnection connect, Message outMessage, OperationResourceInfo ori) 
         throws Throwable {
-        Response r = setResponseBuilder(connect, outMessage.getExchange().getInMessage()).clone().build();
+        Response r = setResponseBuilder(connect, outMessage.getExchange()).clone().build();
         Method method = ori.getMethodToInvoke();
         checkResponse(method, r, outMessage);
         if (method.getReturnType() == Void.class) { 

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=799739&r1=799738&r2=799739&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java Fri Jul 31 20:14:22 2009
@@ -538,7 +538,7 @@
     
     protected Response handleResponse(HttpURLConnection conn, Message outMessage, Class<?> responseClass) {
         try {
-            ResponseBuilder rb = setResponseBuilder(conn, outMessage.getExchange().getInMessage()).clone();
+            ResponseBuilder rb = setResponseBuilder(conn, outMessage.getExchange()).clone();
             Response currentResponse = rb.clone().build();
             
             Object entity = readBody(currentResponse, conn, outMessage, responseClass, responseClass,

Modified: cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java?rev=799739&r1=799738&r2=799739&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java (original)
+++ cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java Fri Jul 31 20:14:22 2009
@@ -1422,6 +1422,9 @@
     ) throws IOException {
 
         int responseCode = connection.getResponseCode();
+        if ((message != null) && (message.getExchange() != null)) {
+            message.getExchange().put(Message.RESPONSE_CODE, responseCode);
+        }
         
         // Process Redirects first.
         switch(responseCode) {
@@ -2044,6 +2047,9 @@
         }
         protected void handleResponseInternal() throws IOException {
             int responseCode = connection.getResponseCode();
+            if ((outMessage != null) && (outMessage.getExchange() != null)) {
+                outMessage.getExchange().put(Message.RESPONSE_CODE, responseCode);
+            }
             
             if (LOG.isLoggable(Level.FINE)) {
                 LOG.fine("Response Code: " 
@@ -2137,6 +2143,7 @@
             
             
             incomingObserver.onMessage(inMessage);
+            
         }
 
 

Modified: cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java?rev=799739&r1=799738&r2=799739&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java (original)
+++ cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSoapRestImpl.java Fri Jul 31 20:14:22 2009
@@ -77,7 +77,15 @@
                     throw new RuntimeException();
                 }
             }
-            Response r = Response.status(404).header("BOOK-HEADER", 
+            int returnCode = 404;
+            if (id == 321) {
+                returnCode = 525;
+            } else if (id == 322) {
+                BookNotFoundDetails details = new BookNotFoundDetails();
+                details.setId(id);
+                throw new BookNotFoundFault(details);
+            }
+            Response r = Response.status(returnCode).header("BOOK-HEADER", 
                 "No Book with id " + id + " is available").build();
             throw new WebApplicationException(r);
         }

Modified: cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java?rev=799739&r1=799738&r2=799739&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java (original)
+++ cxf/branches/2.2.x-fixes/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java Fri Jul 31 20:14:22 2009
@@ -412,10 +412,74 @@
         bean.setFeatures(features);
         BookStoreJaxrsJaxws proxy = (BookStoreJaxrsJaxws)bean.create();
         Book b = proxy.getBook(new Long("123"));
-        assertTrue("Interceptor not invoked", testFeature.handleMessageCalled());
+        assertTrue("Out Interceptor not invoked", testFeature.handleMessageOnOutInterceptorCalled());
+        assertTrue("In Interceptor not invoked", testFeature.handleMessageOnInInterceptorCalled());    
         assertEquals(123, b.getId());
         assertEquals("CXF in Action", b.getName());
     }
+    
+    @Test
+    public void testServerFaultInInterceptor() throws Exception {
+        //testing faults created by server handled correctly
+        serverFaultInInterceptorTest("321");
+        //999 causes error code of 404, 404 has a different code path so need to test too
+        serverFaultInInterceptorTest("999");
+        //322 causes a checked exception to be thrown so need to 
+        serverFaultInInterceptorTest("322");
+    }
+    
+    @Test
+    public void testClientFaultOutInterceptor() throws Exception {
+        //testing faults created by client out interceptor chain handled correctly 
+        String baseAddress = "http://localhost:9092/test/services/rest";
+        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+        bean.setAddress(baseAddress);
+        bean.setResourceClass(BookStoreJaxrsJaxws.class);
+        final boolean addBadOutInterceptor = true;
+        TestFeature testFeature = new TestFeature(addBadOutInterceptor);
+        List<AbstractFeature> features = new ArrayList<AbstractFeature>();
+        features.add((AbstractFeature)testFeature);
+        bean.setFeatures(features);
+        BookStoreJaxrsJaxws proxy = (BookStoreJaxrsJaxws)bean.create();
+        try {
+            //321 is special case - causes error code of 525
+            proxy.getBook(new Long("123"));
+            fail("Method should have thrown an exception");
+        } catch (Exception e) {
+            assertTrue("Out Interceptor not invoked", testFeature.handleMessageOnOutInterceptorCalled());
+            assertTrue("In Interceptor not invoked", !testFeature.handleMessageOnInInterceptorCalled());
+            assertTrue("Wrong exception caught", "fault from bad interceptor".equals(e.getMessage()));
+            assertTrue("Client In Fault In Interceptor was invoked", 
+                    !testFeature.faultInInterceptorCalled());
+        }
+    }
+    
+    private void serverFaultInInterceptorTest(String param) {
+        String baseAddress = "http://localhost:9092/test/services/rest";
+        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+        bean.setAddress(baseAddress);
+        bean.setResourceClass(BookStoreJaxrsJaxws.class);
+        TestFeature testFeature = new TestFeature();
+        List<AbstractFeature> features = new ArrayList<AbstractFeature>();
+        features.add((AbstractFeature)testFeature);
+        bean.setFeatures(features);
+        BookStoreJaxrsJaxws proxy = (BookStoreJaxrsJaxws)bean.create();
+        try {
+            //321 is special case - causes error code of 525
+            proxy.getBook(new Long(param));
+            fail("Method should have thrown an exception");
+        } catch (Exception e) {
+            assertTrue("Out Interceptor not invoked", testFeature.handleMessageOnOutInterceptorCalled());
+            if ("322".equals(param)) {
+                //In interecptors not called when checked exception thrown from server
+                assertTrue("In Interceptor not invoked", testFeature.handleMessageOnInInterceptorCalled());
+            } else {
+                assertTrue("In Interceptor not invoked", !testFeature.handleMessageOnInInterceptorCalled());
+            }
+            assertTrue("Client In Fault In Interceptor not invoked", 
+                    testFeature.faultInInterceptorCalled());
+        }
+    }
 
     private String getStringFromInputStream(InputStream in) throws Exception {        
         CachedOutputStream bos = new CachedOutputStream();
@@ -483,27 +547,52 @@
     
     @Ignore
     public class TestFeature extends AbstractFeature {
-        private TestInterceptor testInterceptor;
+        private TestOutInterceptor testOutInterceptor;
+        private TestInInterceptor testInInterceptor;
+        private TestFaultInInterceptor testFaultInInterceptor;
+        private boolean addBadOutInterceptor;
+        
+        public TestFeature() {
+        }
+        
+        public TestFeature(boolean addBadOutInterceptor) {
+            this.addBadOutInterceptor = addBadOutInterceptor;
+        }
 
         @Override
         protected void initializeProvider(InterceptorProvider provider, Bus bus) {
-            testInterceptor = new TestInterceptor();
-            provider.getOutInterceptors().add(testInterceptor);
+            testOutInterceptor = new TestOutInterceptor(addBadOutInterceptor);
+            testInInterceptor = new TestInInterceptor();
+            testFaultInInterceptor = new TestFaultInInterceptor();
+            provider.getOutInterceptors().add(testOutInterceptor);
+            provider.getInInterceptors().add(testInInterceptor);
+            provider.getInFaultInterceptors().add(testFaultInInterceptor);
+
+            
         }
 
-        protected boolean handleMessageCalled() {
-            return testInterceptor.handleMessageCalled();
+        protected boolean handleMessageOnOutInterceptorCalled() {
+            return testOutInterceptor.handleMessageCalled();
+        }
+        
+        protected boolean handleMessageOnInInterceptorCalled() {
+            return testInInterceptor.handleMessageCalled();
+        }
+        
+        protected boolean faultInInterceptorCalled() {
+            return testFaultInInterceptor.handleMessageCalled();
         }
     }
  
     @Ignore
-    public class TestInterceptor extends AbstractPhaseInterceptor<Message> {
+    public class TestInInterceptor extends AbstractPhaseInterceptor<Message> {
         private boolean handleMessageCalled;
-        public TestInterceptor() {
+        
+        public TestInInterceptor() {
             this(Phase.PRE_STREAM);
         }
 
-        public TestInterceptor(String s) {
+        public TestInInterceptor(String s) {
             super(Phase.PRE_STREAM);
             
         } 
@@ -517,4 +606,56 @@
         }
 
     }
+    
+    @Ignore
+    public class TestOutInterceptor extends AbstractPhaseInterceptor<Message> {
+        private boolean handleMessageCalled;
+        private boolean isBadOutInterceptor;
+        
+        
+        public TestOutInterceptor(boolean isBadOutInterceptor) {
+            this(Phase.PRE_MARSHAL);
+            this.isBadOutInterceptor = isBadOutInterceptor;
+        }
+
+        public TestOutInterceptor(String s) {
+            super(Phase.PRE_MARSHAL);
+            
+        } 
+
+        public void handleMessage(Message message) throws Fault {
+            handleMessageCalled = true;
+            if (isBadOutInterceptor) {
+                throw new Fault(new Exception("fault from bad interceptor"));
+            }
+        }
+
+        protected boolean handleMessageCalled() {
+            return handleMessageCalled;
+        }
+
+    }
+    
+    @Ignore
+    public class TestFaultInInterceptor extends AbstractPhaseInterceptor<Message> {
+        private boolean handleMessageCalled;
+        public TestFaultInInterceptor() {
+            this(Phase.PRE_STREAM);
+        }
+
+        public TestFaultInInterceptor(String s) {
+            super(Phase.PRE_STREAM);
+            
+        } 
+
+        public void handleMessage(Message message) throws Fault {
+            handleMessageCalled = true;
+        }
+
+        protected boolean handleMessageCalled() {
+            return handleMessageCalled;
+        }
+
+    }
+    
 }