Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E6875102BE for ; Tue, 12 Nov 2013 19:11:10 +0000 (UTC) Received: (qmail 66778 invoked by uid 500); 12 Nov 2013 19:11:10 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 66732 invoked by uid 500); 12 Nov 2013 19:11:10 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 66725 invoked by uid 99); 12 Nov 2013 19:11:10 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Nov 2013 19:11:10 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Nov 2013 19:11:07 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DA91F23888E2; Tue, 12 Nov 2013 19:10:45 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1541199 - in /cxf/trunk: rt/features/clustering/src/main/java/org/apache/cxf/clustering/ rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ rt/transports/http/src/main/java/org/apache/cxf/transport/http/ systests/jaxrs/src/test/java/o... Date: Tue, 12 Nov 2013 19:10:45 -0000 To: commits@cxf.apache.org From: sergeyb@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131112191045.DA91F23888E2@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: sergeyb Date: Tue Nov 12 19:10:45 2013 New Revision: 1541199 URL: http://svn.apache.org/r1541199 Log: [CXF-5378] Optional support for the failover feature reacting to HTTP errors Modified: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/FailoverTest.java Modified: cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java?rev=1541199&r1=1541198&r2=1541199&view=diff ============================================================================== --- cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java (original) +++ cxf/trunk/rt/features/clustering/src/main/java/org/apache/cxf/clustering/FailoverTargetSelector.java Tue Nov 12 19:10:45 2013 @@ -26,6 +26,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.PropertyUtils; import org.apache.cxf.endpoint.AbstractConduitSelector; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.Endpoint; @@ -51,7 +52,7 @@ public class FailoverTargetSelector exte protected ConcurrentHashMap inProgress = new ConcurrentHashMap();; protected FailoverStrategy failoverStrategy; - + private boolean supportNotAvailableErrorsOnly; /** * Normal constructor. */ @@ -78,6 +79,8 @@ public class FailoverTargetSelector exte return; } Exchange exchange = message.getExchange(); + setupExchangeExceptionProperties(exchange); + InvocationKey key = new InvocationKey(exchange); if (!inProgress.containsKey(key)) { Endpoint endpoint = exchange.get(Endpoint.class); @@ -95,6 +98,10 @@ public class FailoverTargetSelector exte } } + protected void setupExchangeExceptionProperties(Exchange ex) { + ex.remove("org.apache.cxf.transport.no_io_exceptions"); + } + /** * Called when a Conduit is actually required. * @@ -121,7 +128,7 @@ public class FailoverTargetSelector exte invocation = inProgress.get(key); } boolean failover = false; - if (requiresFailover(exchange)) { + if (invocation != null && requiresFailover(exchange)) { Conduit old = (Conduit)exchange.getOutMessage().remove(Conduit.class.getName()); Endpoint failoverTarget = getFailoverTarget(exchange, invocation); @@ -242,6 +249,12 @@ public class FailoverTargetSelector exte "CHECK_FAILURE_IN_TRANSPORT", new Object[] {ex, failover}); } + if (failover + && isSupportNotAvailableErrorsOnly() + && exchange.get(Message.RESPONSE_CODE) != null + && !PropertyUtils.isTrue(exchange.get("org.apache.cxf.transport.service_not_available"))) { + failover = false; + } return failover; } @@ -342,6 +355,14 @@ public class FailoverTargetSelector exte return false; } + public boolean isSupportNotAvailableErrorsOnly() { + return supportNotAvailableErrorsOnly; + } + + public void setSupportNotAvailableErrorsOnly(boolean support) { + this.supportNotAvailableErrorsOnly = support; + } + /** * Used to wrap an Exchange for usage as a Map key. The raw Exchange * is not a suitable key type, as the hashCode is computed from its Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=1541199&r1=1541198&r2=1541199&view=diff ============================================================================== --- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original) +++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Tue Nov 12 19:10:45 2013 @@ -944,7 +944,7 @@ public abstract class AbstractClient imp exchange.put(Bus.class, cfg.getBus()); exchange.put(MessageObserver.class, new ClientMessageObserver(cfg)); exchange.put(Endpoint.class, cfg.getConduitSelector().getEndpoint()); - exchange.put("org.apache.cxf.http.no_io_exceptions", true); + exchange.put("org.apache.cxf.transport.no_io_exceptions", true); //REVISIT - when response handling is actually put onto the in chain, this will likely not be needed exchange.put(StaxInEndingInterceptor.STAX_IN_NOCLOSE, Boolean.TRUE); m.setExchange(exchange); Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java?rev=1541199&r1=1541198&r2=1541199&view=diff ============================================================================== --- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java (original) +++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java Tue Nov 12 19:10:45 2013 @@ -1551,8 +1551,13 @@ public abstract class HTTPConduit // This property should be set in case the exceptions should not be handled here // For example jax rs uses this boolean noExceptions = MessageUtils.isTrue(outMessage.getContextualProperty( - "org.apache.cxf.http.no_io_exceptions")); + "org.apache.cxf.transport.no_io_exceptions")); + if (responseCode >= 400 && responseCode != 500 && !noExceptions) { + + if (responseCode == 404 || responseCode == 503) { + exchange.put("org.apache.cxf.transport.service_not_available", true); + } throw new HTTPException(responseCode, getResponseMessage(), url.toURL()); } Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java?rev=1541199&r1=1541198&r2=1541199&view=diff ============================================================================== --- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java (original) +++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java Tue Nov 12 19:10:45 2013 @@ -911,7 +911,7 @@ public class JAXRSSoapBookTest extends A features.add(testFeature); bean.setFeatures(features); BookStoreJaxrsJaxws proxy = (BookStoreJaxrsJaxws)bean.create(); - WebClient.getConfig(proxy).getRequestContext().put("org.apache.cxf.http.no_io_exceptions", false); + WebClient.getConfig(proxy).getRequestContext().put("org.apache.cxf.transport.no_io_exceptions", false); try { //321 is special case - causes error code of 525 proxy.getBook(new Long(param)); Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/FailoverTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/FailoverTest.java?rev=1541199&r1=1541198&r2=1541199&view=diff ============================================================================== --- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/FailoverTest.java (original) +++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/failover/FailoverTest.java Tue Nov 12 19:10:45 2013 @@ -111,6 +111,26 @@ public class FailoverTest extends Abstra } @Test + public void testSequentialStrategyWith404() throws Exception { + FailoverFeature feature = getFeature(false, false, Server.ADDRESS3); + feature.getTargetSelector().setSupportNotAvailableErrorsOnly(true); + strategyTestWebClient(Server.ADDRESS2 + "/new", feature, Server.ADDRESS3, null, false, false); + } + + @Test + public void testSequentialStrategyWith406() throws Exception { + FailoverFeature feature = getFeature(false, false, Server.ADDRESS3); + strategyTestWebClientHttpError(Server.ADDRESS2, feature, Server.ADDRESS3, false); + } + + @Test + public void testSequentialStrategyWith406NoFailover() throws Exception { + FailoverFeature feature = getFeature(false, false, Server.ADDRESS3); + feature.getTargetSelector().setSupportNotAvailableErrorsOnly(true); + strategyTestWebClientHttpError(Server.ADDRESS2, feature, Server.ADDRESS3, true); + } + + @Test public void testRandomStrategyWebClient() throws Exception { FailoverFeature feature = getFeature(false, true, Server.ADDRESS3, Server.ADDRESS2); @@ -341,6 +361,23 @@ public class FailoverTest extends Abstra expectRandom, randomized); } + + protected void strategyTestWebClientHttpError(String currentReplica, + FailoverFeature feature, + String newReplica, + boolean notAvailableOnly) throws Exception { + WebClient bookStore = getWebClient(currentReplica, feature); + verifyStrategy(bookStore, SequentialStrategy.class); + bookStore.path("bookstore/webappexceptionXML"); + Response r = bookStore.get(); + assertEquals(406, r.getStatus()); + String currEndpoint = getCurrentEndpointAddress(bookStore); + if (notAvailableOnly) { + assertTrue(currEndpoint.equals(currentReplica)); + } else { + assertTrue(currEndpoint.equals(newReplica)); + } + } protected String getCurrentEndpointAddress(Object client) {