Author: davsclaus Date: Wed Apr 11 07:14:11 2012 New Revision: 1324598 URL: http://svn.apache.org/viewvc?rev=1324598&view=rev Log: CAMEL-5162: OnException handled/continued predicates should only be evaluate once per exception, instead of twice.
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinuePredicateTest.java - copied, changed from r1312081, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoPredicateTest.java - copied, changed from r1312081, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java?rev=1324598&r1=1324597&r2=1324598&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java Wed Apr 11 07:14:11 2012 @@ -712,9 +712,12 @@ public abstract class RedeliveryErrorHan // clear exception as we let the failure processor handle it exchange.setException(null); - boolean handled = false; + final boolean shouldHandle = shouldHandled(exchange, data); + final boolean shouldContinue = shouldContinue(exchange, data); // regard both handled or continued as being handled - if (shouldHandled(exchange, data) || shouldContinue(exchange, data)) { + boolean handled = false; + + if (shouldHandle || shouldContinue) { // its handled then remove traces of redelivery attempted exchange.getIn().removeHeader(Exchange.REDELIVERED); exchange.getIn().removeHeader(Exchange.REDELIVERY_COUNTER); @@ -759,7 +762,7 @@ public abstract class RedeliveryErrorHan public void done(boolean sync) { log.trace("Failure processor done: {} processing Exchange: {}", processor, exchange); try { - prepareExchangeAfterFailure(exchange, data); + prepareExchangeAfterFailure(exchange, data, shouldHandle, shouldContinue); // fire event as we had a failure processor to handle it, which there is a event for boolean deadLetterChannel = processor == data.deadLetterProcessor && data.deadLetterProcessor != null; EventHelper.notifyExchangeFailureHandled(exchange.getContext(), exchange, processor, deadLetterChannel); @@ -773,7 +776,7 @@ public abstract class RedeliveryErrorHan } else { try { // no processor but we need to prepare after failure as well - prepareExchangeAfterFailure(exchange, data); + prepareExchangeAfterFailure(exchange, data, shouldHandle, shouldContinue); } finally { // callback we are done callback.done(data.sync); @@ -793,7 +796,8 @@ public abstract class RedeliveryErrorHan return sync; } - protected void prepareExchangeAfterFailure(final Exchange exchange, final RedeliveryData data) { + protected void prepareExchangeAfterFailure(final Exchange exchange, final RedeliveryData data, + final boolean shouldHandle, final boolean shouldContinue) { // we could not process the exchange so we let the failure processor handled it ExchangeHelper.setFailureHandled(exchange); @@ -813,10 +817,10 @@ public abstract class RedeliveryErrorHan return; } - if (shouldHandled(exchange, data)) { + if (shouldHandle) { log.trace("This exchange is handled so its marked as not failed: {}", exchange); exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, Boolean.TRUE); - } else if (shouldContinue(exchange, data)) { + } else if (shouldContinue) { log.trace("This exchange is continued: {}", exchange); // okay we want to continue then prepare the exchange for that as well prepareExchangeForContinue(exchange, data); Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinuePredicateTest.java (from r1312081, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinuePredicateTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinuePredicateTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTest.java&r1=1312081&r2=1324598&rev=1324598&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinuePredicateTest.java Wed Apr 11 07:14:11 2012 @@ -16,44 +16,61 @@ */ package org.apache.camel.processor.onexception; -import org.apache.camel.ContextTestSupport; +import java.util.concurrent.atomic.AtomicInteger; + import org.apache.camel.Exchange; +import org.apache.camel.Predicate; +import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.component.mock.MockEndpoint; /** * @version */ -public class OnExceptionContinueTest extends ContextTestSupport { +public class OnExceptionContinuePredicateTest extends OnExceptionContinueTest { - public void testContinued() throws Exception { - getMockEndpoint("mock:start").expectedMessageCount(1); + private final AtomicInteger predicateInvoked = new AtomicInteger(); + private final AtomicInteger processorInvoked = new AtomicInteger(); - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedBodiesReceived("Hello World"); - // and we should keep the exception so we know what caused the failure - mock.message(0).property(Exchange.EXCEPTION_CAUGHT).isInstanceOf(IllegalArgumentException.class); + @Override + public void testContinued() throws Exception { + getMockEndpoint("mock:me").expectedMessageCount(1); - template.sendBody("direct:start", "Hello World"); + super.testContinued(); - assertMockEndpointsSatisfied(); + assertEquals(1, predicateInvoked.get()); + assertEquals(1, processorInvoked.get()); } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override - // START SNIPPET: e1 public void configure() throws Exception { + // use a predicate instance + Predicate predicate = new Predicate() { + @Override + public boolean matches(Exchange exchange) { + predicateInvoked.incrementAndGet(); + return true; + } + }; + // tell Camel to handle and continue when this exception is thrown - onException(IllegalArgumentException.class).continued(true); + onException(IllegalArgumentException.class) + .continued(predicate) + .process(new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + processorInvoked.incrementAndGet(); + } + }) + .to("mock:me"); from("direct:start") .to("mock:start") .throwException(new IllegalArgumentException("Forced")) .to("mock:result"); } - // END SNIPPET: e1 }; } } \ No newline at end of file Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoPredicateTest.java (from r1312081, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoPredicateTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoPredicateTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoTest.java&r1=1312081&r2=1324598&rev=1324598&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionContinueTwoPredicateTest.java Wed Apr 11 07:14:11 2012 @@ -16,31 +16,29 @@ */ package org.apache.camel.processor.onexception; -import org.apache.camel.ContextTestSupport; +import java.util.concurrent.atomic.AtomicInteger; + import org.apache.camel.Exchange; +import org.apache.camel.Predicate; +import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.component.mock.MockEndpoint; /** - * @version + * @version */ -public class OnExceptionContinueTwoTest extends ContextTestSupport { - - public void testContinuedTwo() throws Exception { - getMockEndpoint("mock:start").expectedMessageCount(1); - getMockEndpoint("mock:middle").expectedMessageCount(1); +public class OnExceptionContinueTwoPredicateTest extends OnExceptionContinueTwoTest { - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedBodiesReceived("Hello World"); - // and we should keep the exception so we know what caused the failure - mock.message(0).property(Exchange.EXCEPTION_CAUGHT).isInstanceOf(IllegalArgumentException.class); + private final AtomicInteger predicateInvoked = new AtomicInteger(); + private final AtomicInteger processorInvoked = new AtomicInteger(); - template.sendBody("direct:start", "Hello World"); + @Override + public void testContinuedTwo() throws Exception { + getMockEndpoint("mock:me").expectedMessageCount(2); - assertMockEndpointsSatisfied(); + super.testContinuedTwo(); - Exception cause = mock.getReceivedExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class); - assertEquals("Forced Again", cause.getMessage()); + assertEquals(2, predicateInvoked.get()); + assertEquals(2, processorInvoked.get()); } @Override @@ -48,16 +46,33 @@ public class OnExceptionContinueTwoTest return new RouteBuilder() { @Override public void configure() throws Exception { + // use a predicate instance + Predicate predicate = new Predicate() { + @Override + public boolean matches(Exchange exchange) { + predicateInvoked.incrementAndGet(); + return true; + } + }; + // tell Camel to handle and continue when this exception is thrown - onException(IllegalArgumentException.class).continued(true); + onException(IllegalArgumentException.class) + .continued(predicate) + .process(new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + processorInvoked.incrementAndGet(); + } + }) + .to("mock:me"); from("direct:start") - .to("mock:start") - .throwException(new IllegalArgumentException("Forced")) - .to("mock:middle") - //throw a second time to validate that the exchange is reset appropriately - .throwException(new IllegalArgumentException("Forced Again")) - .to("mock:result"); + .to("mock:start") + .throwException(new IllegalArgumentException("Forced")) + .to("mock:middle") + //throw a second time to validate that the exchange is reset appropriately + .throwException(new IllegalArgumentException("Forced Again")) + .to("mock:result"); } }; }