Author: davsclaus Date: Sun May 17 07:56:14 2009 New Revision: 775596 URL: http://svn.apache.org/viewvc?rev=775596&view=rev Log: CAMEL-1620: Improved failover loadbalancer. Handling multiple exceptions and being able to look in hiearachy.
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailoverLoadBalancerDefinition.java (contents, props changed) - copied, changed from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailOverLoadBalanceStrategy.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalancerDefinition.java (contents, props changed) - copied, changed from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalanceStrategy.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalancerDefinition.java (contents, props changed) - copied, changed from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalanceStrategy.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalancerDefinition.java (contents, props changed) - copied, changed from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalanceStrategy.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalancerDefinition.java (contents, props changed) - copied, changed from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalanceStrategy.java camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceMultipleExceptionTest.java (with props) camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionNoLuckTest.java (with props) camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionTest.java - copied, changed from r775468, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverNotCatchedExceptionTest.java (with props) Removed: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailOverLoadBalanceStrategy.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalanceStrategy.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalanceStrategy.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalanceStrategy.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalanceStrategy.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoadBalanceDefinition.java camel/trunk/camel-core/src/main/java/org/apache/camel/processor/loadbalancer/FailOverLoadBalancer.java camel/trunk/camel-core/src/main/resources/org/apache/camel/model/loadbalancer/jaxb.index camel/trunk/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncRouteNoWaitTest.java camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/failOverLoadBalance.xml Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoadBalanceDefinition.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoadBalanceDefinition.java?rev=775596&r1=775595&r2=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoadBalanceDefinition.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoadBalanceDefinition.java Sun May 17 07:56:14 2009 @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Arrays; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -30,12 +31,12 @@ import org.apache.camel.Expression; import org.apache.camel.Processor; -import org.apache.camel.model.loadbalancer.FailOverLoadBalanceStrategy; +import org.apache.camel.model.loadbalancer.FailoverLoadBalancerDefinition; import org.apache.camel.model.loadbalancer.LoadBalancerDefinition; -import org.apache.camel.model.loadbalancer.RandomLoadBalanceStrategy; -import org.apache.camel.model.loadbalancer.RoundRobinLoadBalanceStrategy; -import org.apache.camel.model.loadbalancer.StickyLoadBalanceStrategy; -import org.apache.camel.model.loadbalancer.TopicLoadBalanceStrategy; +import org.apache.camel.model.loadbalancer.RandomLoadBalancerDefinition; +import org.apache.camel.model.loadbalancer.RoundRobinLoadBalancerDefinition; +import org.apache.camel.model.loadbalancer.StickyLoadBalancerDefinition; +import org.apache.camel.model.loadbalancer.TopicLoadBalancerDefinition; import org.apache.camel.processor.SendProcessor; import org.apache.camel.processor.loadbalancer.FailOverLoadBalancer; import org.apache.camel.processor.loadbalancer.LoadBalancer; @@ -56,11 +57,11 @@ private String ref; @XmlElements({ - @XmlElement(required = false, name = "failOver", type = FailOverLoadBalanceStrategy.class), - @XmlElement(required = false, name = "roundRobin", type = RoundRobinLoadBalanceStrategy.class), - @XmlElement(required = false, name = "random", type = RandomLoadBalanceStrategy.class), - @XmlElement(required = false, name = "sticky", type = StickyLoadBalanceStrategy.class), - @XmlElement(required = false, name = "topic", type = TopicLoadBalanceStrategy.class)} + @XmlElement(required = false, name = "failOver", type = FailoverLoadBalancerDefinition.class), + @XmlElement(required = false, name = "roundRobin", type = RoundRobinLoadBalancerDefinition.class), + @XmlElement(required = false, name = "random", type = RandomLoadBalancerDefinition.class), + @XmlElement(required = false, name = "sticky", type = StickyLoadBalancerDefinition.class), + @XmlElement(required = false, name = "topic", type = TopicLoadBalancerDefinition.class)} ) private LoadBalancerDefinition loadBalancerType; @@ -154,11 +155,11 @@ /** * Uses fail over load balancer * - * @param throwable exception Class which we want to catch + * @param exceptions exception classes which we want to failover if one of them was thrown * @return the builder */ - public LoadBalanceDefinition failOver(Class throwable) { - loadBalancerType = new LoadBalancerDefinition(new FailOverLoadBalancer(throwable)); + public LoadBalanceDefinition failOver(Class... exceptions) { + loadBalancerType = new LoadBalancerDefinition(new FailOverLoadBalancer(Arrays.asList(exceptions))); return this; } Copied: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailoverLoadBalancerDefinition.java (from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailOverLoadBalanceStrategy.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailoverLoadBalancerDefinition.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailoverLoadBalancerDefinition.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailOverLoadBalanceStrategy.java&r1=775579&r2=775596&rev=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailOverLoadBalanceStrategy.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailoverLoadBalancerDefinition.java Sun May 17 07:56:14 2009 @@ -16,46 +16,51 @@ */ package org.apache.camel.model.loadbalancer; +import java.util.ArrayList; +import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import org.apache.camel.processor.loadbalancer.FailOverLoadBalancer; import org.apache.camel.processor.loadbalancer.LoadBalancer; import org.apache.camel.spi.RouteContext; -import org.apache.camel.util.ObjectHelper; -...@xmlrootelement(name = "failOver") +...@xmlrootelement(name = "failover") @XmlAccessorType(XmlAccessType.FIELD) -public class FailOverLoadBalanceStrategy extends LoadBalancerDefinition { +public class FailoverLoadBalancerDefinition extends LoadBalancerDefinition { + + @XmlElement(name = "exception") + private List<String> exceptions = new ArrayList<String>(); - @XmlAttribute (name = "exception", required = false) - private String failedException; - @Override protected LoadBalancer createLoadBalancer(RouteContext routeContext) { - if (ObjectHelper.isNotEmpty(failedException)) { - Class type = routeContext.getCamelContext().getClassResolver().resolveClass(failedException); - if (type == null) { - throw new IllegalArgumentException("Cannot find class: " + failedException + " in the classpath"); + if (!exceptions.isEmpty()) { + List<Class> classes = new ArrayList<Class>(); + for (String name : exceptions) { + Class type = routeContext.getCamelContext().getClassResolver().resolveClass(name); + if (type == null) { + throw new IllegalArgumentException("Cannot find class: " + name + " in the classpath"); + } + classes.add(type); } - return new FailOverLoadBalancer(type); + return new FailOverLoadBalancer(classes); } else { return new FailOverLoadBalancer(); } } - - public void setFailedException(String exceptionName) { - failedException = exceptionName; + + public List<String> getExceptions() { + return exceptions; } - - public String getFailedException() { - return failedException; + + public void setExceptions(List<String> exceptions) { + this.exceptions = exceptions; } @Override public String toString() { - return "FailOverLoadBalancer"; + return "FailoverLoadBalancer"; } } Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailoverLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/FailoverLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Copied: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalancerDefinition.java (from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalanceStrategy.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalancerDefinition.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalancerDefinition.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalanceStrategy.java&r1=775579&r2=775596&rev=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalanceStrategy.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalancerDefinition.java Sun May 17 07:56:14 2009 @@ -26,7 +26,7 @@ * Represents an XML <random/> element */ @XmlRootElement(name = "random") -public class RandomLoadBalanceStrategy extends LoadBalancerDefinition { +public class RandomLoadBalancerDefinition extends LoadBalancerDefinition { @Override protected LoadBalancer createLoadBalancer(RouteContext routeContext) { Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RandomLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Copied: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalancerDefinition.java (from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalanceStrategy.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalancerDefinition.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalancerDefinition.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalanceStrategy.java&r1=775579&r2=775596&rev=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalanceStrategy.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalancerDefinition.java Sun May 17 07:56:14 2009 @@ -25,7 +25,7 @@ * Represents an XML <roundRobin/> element */ @XmlRootElement(name = "roundRobin") -public class RoundRobinLoadBalanceStrategy extends LoadBalancerDefinition { +public class RoundRobinLoadBalancerDefinition extends LoadBalancerDefinition { @Override protected LoadBalancer createLoadBalancer(RouteContext routeContext) { Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/RoundRobinLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Copied: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalancerDefinition.java (from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalanceStrategy.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalancerDefinition.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalancerDefinition.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalanceStrategy.java&r1=775579&r2=775596&rev=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalanceStrategy.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalancerDefinition.java Sun May 17 07:56:14 2009 @@ -31,7 +31,7 @@ */ @XmlRootElement(name = "sticky") @XmlAccessorType(XmlAccessType.FIELD) -public class StickyLoadBalanceStrategy extends LoadBalancerDefinition { +public class StickyLoadBalancerDefinition extends LoadBalancerDefinition { @XmlElement(name = "correlationExpression", required = false) private ExpressionSubElementDefinition correlationExpression; Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/StickyLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Copied: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalancerDefinition.java (from r775579, camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalanceStrategy.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalancerDefinition.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalancerDefinition.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalanceStrategy.java&r1=775579&r2=775596&rev=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalanceStrategy.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalancerDefinition.java Sun May 17 07:56:14 2009 @@ -26,7 +26,7 @@ * */ @XmlRootElement(name = "topic") -public class TopicLoadBalanceStrategy extends LoadBalancerDefinition { +public class TopicLoadBalancerDefinition extends LoadBalancerDefinition { @Override protected LoadBalancer createLoadBalancer(RouteContext routeContext) { Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/model/loadbalancer/TopicLoadBalancerDefinition.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/loadbalancer/FailOverLoadBalancer.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/loadbalancer/FailOverLoadBalancer.java?rev=775596&r1=775595&r2=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/loadbalancer/FailOverLoadBalancer.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/loadbalancer/FailOverLoadBalancer.java Sun May 17 07:56:14 2009 @@ -16,6 +16,8 @@ */ package org.apache.camel.processor.loadbalancer; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import org.apache.camel.Exchange; @@ -27,26 +29,47 @@ */ public class FailOverLoadBalancer extends LoadBalancerSupport { - private final Class failException; + private final List<Class> exceptions; - public FailOverLoadBalancer(Class throwable) { - if (ObjectHelper.isAssignableFrom(Throwable.class, throwable)) { - failException = throwable; - } else { - throw new IllegalArgumentException("Class is not an instance of Trowable: " + throwable); - } + public FailOverLoadBalancer() { + this.exceptions = null; } - public FailOverLoadBalancer() { - this(Throwable.class); + public FailOverLoadBalancer(List<Class> exceptions) { + this.exceptions = exceptions; + for (Class type : exceptions) { + if (!ObjectHelper.isAssignableFrom(Throwable.class, type)) { + throw new IllegalArgumentException("Class is not an instance of Trowable: " + type); + } + } } - protected boolean isCheckedException(Exchange exchange) { + /** + * Should the given failed Exchange failover? + * + * @param exchange the exchange that failed + * @return <tt>true</tt> to failover + */ + protected boolean shouldFailOver(Exchange exchange) { if (exchange.getException() != null) { - if (failException.isAssignableFrom(exchange.getException().getClass())) { + + if (exceptions == null || exceptions.isEmpty()) { + // always failover if no exceptions defined return true; } + + for (Class exception : exceptions) { + // use exception iterator to walk the hieracy tree as the exception is possibly wrapped + Iterator<Throwable> it = ObjectHelper.createExceptionIterator(exchange.getException()); + while (it.hasNext()) { + Throwable e = it.next(); + if (exception.isInstance(e)) { + return true; + } + } + } } + return false; } @@ -55,16 +78,23 @@ if (list.isEmpty()) { throw new IllegalStateException("No processors available to process " + exchange); } + int index = 0; Processor processor = list.get(index); + + // process the first time processExchange(processor, exchange); - while (isCheckedException(exchange)) { - exchange.setException(null); + + // loop while we should fail over + while (shouldFailOver(exchange)) { index++; if (index < list.size()) { + // try again but reset exception first + exchange.setException(null); processor = list.get(index); processExchange(processor, exchange); } else { + // no more processors to try break; } } Modified: camel/trunk/camel-core/src/main/resources/org/apache/camel/model/loadbalancer/jaxb.index URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/resources/org/apache/camel/model/loadbalancer/jaxb.index?rev=775596&r1=775595&r2=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/resources/org/apache/camel/model/loadbalancer/jaxb.index (original) +++ camel/trunk/camel-core/src/main/resources/org/apache/camel/model/loadbalancer/jaxb.index Sun May 17 07:56:14 2009 @@ -14,9 +14,9 @@ ## See the License for the specific language governing permissions and ## limitations under the License. ## ------------------------------------------------------------------------ -FailOverLoadBalanceStrategy +FailoverLoadBalancerDefinition LoadBalancerDefinition -RandomLoadBalanceStrategy -RoundRobinLoadBalanceStrategy -StickyLoadBalanceStrategy -TopicLoadBalanceStrategy \ No newline at end of file +RandomLoadBalancerDefinition +RoundRobinLoadBalancerDefinition +StickyLoadBalancerDefinition +TopicLoadBalancerDefinition \ No newline at end of file Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java?rev=775596&r1=775595&r2=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java Sun May 17 07:56:14 2009 @@ -20,8 +20,8 @@ import javax.xml.bind.JAXBException; import org.apache.camel.model.language.ExpressionDefinition; -import org.apache.camel.model.loadbalancer.RoundRobinLoadBalanceStrategy; -import org.apache.camel.model.loadbalancer.StickyLoadBalanceStrategy; +import org.apache.camel.model.loadbalancer.RoundRobinLoadBalancerDefinition; +import org.apache.camel.model.loadbalancer.StickyLoadBalancerDefinition; /** * @version $Revision$ @@ -194,7 +194,7 @@ assertFrom(route, "seda:a"); LoadBalanceDefinition loadBalance = assertOneProcessorInstanceOf(LoadBalanceDefinition.class, route); assertEquals("Here should have 3 output here", 3, loadBalance.getOutputs().size()); - assertTrue("The loadBalancer shoud be RoundRobinLoadBalanceStrategy", loadBalance.getLoadBalancerType() instanceof RoundRobinLoadBalanceStrategy); + assertTrue("The loadBalancer shoud be RoundRobinLoadBalancerDefinition", loadBalance.getLoadBalancerType() instanceof RoundRobinLoadBalancerDefinition); } public void testParseStickyLoadBalance() throws Exception { @@ -202,8 +202,8 @@ assertFrom(route, "seda:a"); LoadBalanceDefinition loadBalance = assertOneProcessorInstanceOf(LoadBalanceDefinition.class, route); assertEquals("Here should have 3 output here", 3, loadBalance.getOutputs().size()); - assertTrue("The loadBalancer shoud be StickyLoadBalanceStrategy", loadBalance.getLoadBalancerType() instanceof StickyLoadBalanceStrategy); - StickyLoadBalanceStrategy strategy = (StickyLoadBalanceStrategy)loadBalance.getLoadBalancerType(); + assertTrue("The loadBalancer shoud be StickyLoadBalancerDefinition", loadBalance.getLoadBalancerType() instanceof StickyLoadBalancerDefinition); + StickyLoadBalancerDefinition strategy = (StickyLoadBalancerDefinition)loadBalance.getLoadBalancerType(); assertNotNull("the expression should not be null ", strategy.getCorrelationExpression()); } Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceMultipleExceptionTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceMultipleExceptionTest.java?rev=775596&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceMultipleExceptionTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceMultipleExceptionTest.java Sun May 17 07:56:14 2009 @@ -0,0 +1,78 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.processor; + +import java.io.IOException; + +import org.apache.camel.CamelException; +import org.apache.camel.CamelExchangeException; +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; + +public class FailOverLoadBalanceMultipleExceptionTest extends ContextTestSupport { + + protected MockEndpoint x; + protected MockEndpoint y; + protected MockEndpoint z; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + x = getMockEndpoint("mock:x"); + y = getMockEndpoint("mock:y"); + z = getMockEndpoint("mock:z"); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("direct:start").loadBalance() + .failOver(IllegalArgumentException.class, IOException.class, CamelException.class) + .to("direct:x", "direct:y", "direct:z"); + + from("direct:x").to("mock:x").process(new Processor() { + public void process(Exchange exchange) throws Exception { + throw new CamelExchangeException("Forced", exchange); + } + }); + + from("direct:y").to("mock:y").process(new Processor() { + public void process(Exchange exchange) throws Exception { + throw new IOException("Forced"); + } + }); + + from("direct:z").to("mock:z"); + } + }; + } + + public void testMultipledException() throws Exception { + x.expectedMessageCount(1); + y.expectedMessageCount(1); + z.expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + +} \ No newline at end of file Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceMultipleExceptionTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceMultipleExceptionTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionNoLuckTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionNoLuckTest.java?rev=775596&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionNoLuckTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionNoLuckTest.java Sun May 17 07:56:14 2009 @@ -0,0 +1,77 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.processor; + +import java.io.IOException; +import java.net.SocketException; + +import org.apache.camel.CamelExecutionException; +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; + +public class FailOverLoadBalanceWrappedExceptionNoLuckTest extends ContextTestSupport { + + protected MockEndpoint x; + protected MockEndpoint y; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + x = getMockEndpoint("mock:x"); + y = getMockEndpoint("mock:y"); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("direct:start").loadBalance() + .failOver(IOException.class).to("direct:x", "direct:y"); + + from("direct:x").to("mock:x").process(new Processor() { + public void process(Exchange exchange) throws Exception { + throw new SocketException("Forced"); + } + }); + + from("direct:y").to("mock:y").process(new Processor() { + public void process(Exchange exchange) throws Exception { + throw new IOException("Forced"); + } + }); + } + }; + } + + public void testWrappedException() throws Exception { + x.expectedMessageCount(1); + y.expectedMessageCount(1); + + try { + template.sendBody("direct:start", "Hello World"); + } catch (CamelExecutionException e) { + assertEquals("Forced", e.getCause().getMessage()); + assertIsInstanceOf(IOException.class, e.getCause()); + } + + assertMockEndpointsSatisfied(); + } + +} \ No newline at end of file Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionNoLuckTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionNoLuckTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionTest.java (from r775468, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceTest.java&r1=775468&r2=775596&rev=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverLoadBalanceWrappedExceptionTest.java Sun May 17 07:56:14 2009 @@ -16,17 +16,17 @@ */ package org.apache.camel.processor; +import java.io.IOException; +import java.net.SocketException; + import org.apache.camel.ContextTestSupport; import org.apache.camel.Exchange; import org.apache.camel.Processor; -import org.apache.camel.RuntimeCamelException; -import org.apache.camel.builder.NoErrorHandlerBuilder; +import org.apache.camel.CamelExchangeException; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; -import static org.apache.camel.component.mock.MockEndpoint.expectsMessageCount; - -public class FailOverLoadBalanceTest extends ContextTestSupport { +public class FailOverLoadBalanceWrappedExceptionTest extends ContextTestSupport { protected MockEndpoint x; protected MockEndpoint y; @@ -40,72 +40,39 @@ y = getMockEndpoint("mock:y"); z = getMockEndpoint("mock:z"); } - - public static class MyException extends Exception { - - } - - public static class MyAnotherException extends Exception { - - } - - public static class MyExceptionProcessor implements Processor { - public void process(Exchange exchange) throws Exception { - throw new MyException(); - } - } - - public static class MyAnotherExceptionProcessor implements Processor { - public void process(Exchange exchange) throws Exception { - throw new MyAnotherException(); - } - } protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { - // First we need to turn off the default error handler - errorHandler(new NoErrorHandlerBuilder()); - - from("direct:exception").loadBalance() - // catch all the exception here - .failOver().to("direct:x", "direct:y", "direct:z"); - - from("direct:customerException").loadBalance() - .failOver(MyException.class).to("direct:x", "direct:y", "direct:z"); - - from("direct:x").process(new MyExceptionProcessor()).to("mock:x"); - - from("direct:y").process(new MyAnotherExceptionProcessor()).to("mock:y"); - + from("direct:start").loadBalance() + .failOver(IOException.class).to("direct:x", "direct:y", "direct:z"); + + from("direct:x").to("mock:x").process(new Processor() { + public void process(Exchange exchange) throws Exception { + // socket exception is an io exception + throw new CamelExchangeException("foo", exchange, new SocketException("Forced")); + } + }); + + from("direct:y").to("mock:y").process(new Processor() { + public void process(Exchange exchange) throws Exception { + throw new IOException("Forced"); + } + }); + from("direct:z").to("mock:z"); - } }; } - public void testThrowable() throws Exception { - String body = "<one/>"; - expectsMessageCount(0, x, y); - z.expectedBodiesReceived(body); - sendMessage("direct:exception", "bar", body); - assertMockEndpointsSatisfied(); - } - - public void testMyException() throws Exception { - String body = "<two/>"; - expectsMessageCount(0, x, y, z); - try { - sendMessage("direct:customerException", "bar", body); - fail("There should get the MyAnotherException"); - } catch (RuntimeCamelException ex) { - // expect the exception here - assertTrue("The cause should be MyAnotherException", ex.getCause() instanceof MyAnotherException); - } + public void testWrappedException() throws Exception { + x.expectedMessageCount(1); + y.expectedMessageCount(1); + z.expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + assertMockEndpointsSatisfied(); } - protected void sendMessage(final String endpoint, final Object headerValue, final Object body) throws Exception { - template.sendBodyAndHeader(endpoint, body, "foo", headerValue); - } -} +} \ No newline at end of file Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverNotCatchedExceptionTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverNotCatchedExceptionTest.java?rev=775596&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverNotCatchedExceptionTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverNotCatchedExceptionTest.java Sun May 17 07:56:14 2009 @@ -0,0 +1,85 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.processor; + +import java.io.IOException; +import java.net.SocketException; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.CamelExecutionException; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; + +public class FailOverNotCatchedExceptionTest extends ContextTestSupport { + + protected MockEndpoint x; + protected MockEndpoint y; + protected MockEndpoint z; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + x = getMockEndpoint("mock:x"); + y = getMockEndpoint("mock:y"); + z = getMockEndpoint("mock:z"); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("direct:start").loadBalance() + .failOver(IOException.class).to("direct:x", "direct:y", "direct:z"); + + from("direct:x").to("mock:x").process(new Processor() { + public void process(Exchange exchange) throws Exception { + throw new SocketException("Forced"); + } + }); + + from("direct:y").to("mock:y").process(new Processor() { + public void process(Exchange exchange) throws Exception { + throw new IllegalArgumentException("Illegal"); + } + }); + + from("direct:z").to("mock:z"); + } + }; + } + + public void testExceptionNotCatched() throws Exception { + x.expectedMessageCount(1); + y.expectedMessageCount(1); + z.expectedMessageCount(0); + + // to test that if a processor throw an exception that the failover loadbalancer + // do not catch then the exception is propagated back + + try { + template.sendBody("direct:start", "Hello World"); + } catch (CamelExecutionException e) { + assertEquals("Illegal", e.getCause().getMessage()); + assertIsInstanceOf(IllegalArgumentException.class, e.getCause()); + } + + assertMockEndpointsSatisfied(); + } + +} \ No newline at end of file Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverNotCatchedExceptionTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/FailOverNotCatchedExceptionTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncRouteNoWaitTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncRouteNoWaitTest.java?rev=775596&r1=775595&r2=775596&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncRouteNoWaitTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncRouteNoWaitTest.java Sun May 17 07:56:14 2009 @@ -60,8 +60,6 @@ // cast to future Future future = (Future) out; - assertFalse("Should not be done", future.isDone()); - assertMockEndpointsSatisfied(); assertEquals("AB", route); @@ -87,8 +85,6 @@ // cast to future Future future = (Future) out; - assertFalse("Should not be done", future.isDone()); - assertMockEndpointsSatisfied(); assertEquals("AB", route); Modified: camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java?rev=775596&r1=775595&r2=775596&view=diff ============================================================================== --- camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java (original) +++ camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java Sun May 17 07:56:14 2009 @@ -36,11 +36,11 @@ import org.apache.camel.model.dataformat.JaxbDataFormat; import org.apache.camel.model.dataformat.SerializationDataFormat; import org.apache.camel.model.dataformat.XMLBeansDataFormat; -import org.apache.camel.model.loadbalancer.RandomLoadBalanceStrategy; -import org.apache.camel.model.loadbalancer.RoundRobinLoadBalanceStrategy; -import org.apache.camel.model.loadbalancer.StickyLoadBalanceStrategy; -import org.apache.camel.model.loadbalancer.TopicLoadBalanceStrategy; -import org.apache.camel.processor.loadbalancer.FailOverLoadBalancer; +import org.apache.camel.model.loadbalancer.FailoverLoadBalancerDefinition; +import org.apache.camel.model.loadbalancer.RandomLoadBalancerDefinition; +import org.apache.camel.model.loadbalancer.RoundRobinLoadBalancerDefinition; +import org.apache.camel.model.loadbalancer.StickyLoadBalancerDefinition; +import org.apache.camel.model.loadbalancer.TopicLoadBalancerDefinition; import org.apache.camel.spi.NamespaceAware; import org.apache.camel.spring.CamelBeanPostProcessor; import org.apache.camel.spring.CamelConsumerTemplateFactoryBean; @@ -91,11 +91,11 @@ addBeanDefinitionParser("xmlBeans", XMLBeansDataFormat.class); // load balancers - addBeanDefinitionParser("roundRobin", RoundRobinLoadBalanceStrategy.class); - addBeanDefinitionParser("random", RandomLoadBalanceStrategy.class); - addBeanDefinitionParser("sticky", StickyLoadBalanceStrategy.class); - addBeanDefinitionParser("topic", TopicLoadBalanceStrategy.class); - addBeanDefinitionParser("failover", FailOverLoadBalancer.class); + addBeanDefinitionParser("roundRobin", RoundRobinLoadBalancerDefinition.class); + addBeanDefinitionParser("random", RandomLoadBalancerDefinition.class); + addBeanDefinitionParser("sticky", StickyLoadBalancerDefinition.class); + addBeanDefinitionParser("topic", TopicLoadBalancerDefinition.class); + addBeanDefinitionParser("failover", FailoverLoadBalancerDefinition.class); // jmx agent addBeanDefinitionParser("jmxAgent", CamelJMXAgentDefinition.class); Modified: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/failOverLoadBalance.xml URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/failOverLoadBalance.xml?rev=775596&r1=775595&r2=775596&view=diff ============================================================================== --- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/failOverLoadBalance.xml (original) +++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/failOverLoadBalance.xml Sun May 17 07:56:14 2009 @@ -38,7 +38,9 @@ <route errorHandlerRef="noErrorHandler"> <from uri="direct:customerException"/> <loadBalance> - <failOver exception="org.apache.camel.processor.FailOverLoadBalanceTest$MyException"/> + <failOver> + <exception>org.apache.camel.processor.FailOverLoadBalanceTest$MyException</exception> + </failOver> <to uri="direct:x"/> <to uri="direct:y"/> <to uri="direct:z"/>