You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2015/01/19 09:53:47 UTC
[01/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Repository: camel
Updated Branches:
refs/heads/master f98e86be1 -> 9461db295
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b05668f7
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b05668f7
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b05668f7
Branch: refs/heads/master
Commit: b05668f78d83086181a5be6b3430b868089e4a93
Parents: f98e86b
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 14:05:54 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 14:05:54 2015 +0100
----------------------------------------------------------------------
.../camel/builder/DeadLetterChannelBuilder.java | 17 ++--
.../builder/DefaultErrorHandlerBuilder.java | 33 +++++++-
.../camel/model/RedeliveryPolicyDefinition.java | 40 +++++++++
.../camel/processor/DeadLetterChannel.java | 8 +-
.../camel/processor/DefaultErrorHandler.java | 2 +-
.../processor/FatalFallbackErrorHandler.java | 37 +++++++--
.../camel/processor/RedeliveryErrorHandler.java | 87 +++++++++++++++-----
.../camel/processor/RedeliveryPolicy.java | 21 +++++
.../apache/camel/processor/SendProcessor.java | 18 ----
.../camel/component/jms/CamelJmsTestHelper.java | 9 +-
...msDeadLetterChannelHandlerExceptionTest.java | 77 -----------------
...erChannelHandlerRollbackOnExceptionTest.java | 84 +++++++++++++++++++
...hannelNotHandlerRollbackOnExceptionTest.java | 39 +++++++++
...actedOnExceptionRollbackOnExceptionTest.java | 77 +++++++++++++++++
.../src/test/resources/log4j.properties | 2 +-
15 files changed, 410 insertions(+), 141 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java
index 4ea7f1d..e1e417d 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java
@@ -22,6 +22,7 @@ import org.apache.camel.LoggingLevel;
import org.apache.camel.NoSuchEndpointException;
import org.apache.camel.Processor;
import org.apache.camel.processor.DeadLetterChannel;
+import org.apache.camel.processor.FatalFallbackErrorHandler;
import org.apache.camel.processor.RedeliveryPolicy;
import org.apache.camel.processor.SendProcessor;
import org.apache.camel.spi.RouteContext;
@@ -37,7 +38,6 @@ import org.slf4j.LoggerFactory;
* @version
*/
public class DeadLetterChannelBuilder extends DefaultErrorHandlerBuilder {
- boolean checkException;
public DeadLetterChannelBuilder() {
// no-arg constructor used by Spring DSL
@@ -51,17 +51,12 @@ public class DeadLetterChannelBuilder extends DefaultErrorHandlerBuilder {
setDeadLetterUri(uri);
}
- public DeadLetterChannelBuilder checkException() {
- checkException = true;
- return this;
- }
-
public Processor createErrorHandler(RouteContext routeContext, Processor processor) throws Exception {
validateDeadLetterUri(routeContext);
DeadLetterChannel answer = new DeadLetterChannel(routeContext.getCamelContext(), processor, getLogger(), getOnRedelivery(),
- getRedeliveryPolicy(), getExceptionPolicyStrategy(), getFailureProcessor(), getDeadLetterUri(), isUseOriginalMessage(),
- getRetryWhilePolicy(routeContext.getCamelContext()), getExecutorService(routeContext.getCamelContext()));
+ getRedeliveryPolicy(), getExceptionPolicyStrategy(), getFailureProcessor(), getDeadLetterUri(), isDeadLetterHandleNewException(),
+ isUseOriginalMessage(), getRetryWhilePolicy(routeContext.getCamelContext()), getExecutorService(routeContext.getCamelContext()));
// configure error handler before we can use it
configure(routeContext, answer);
return answer;
@@ -83,10 +78,10 @@ public class DeadLetterChannelBuilder extends DefaultErrorHandlerBuilder {
public Processor getFailureProcessor() {
if (failureProcessor == null) {
+ // wrap in our special safe fallback error handler if sending to dead letter channel fails
+ Processor child = new SendProcessor(deadLetter, ExchangePattern.InOnly);
// force MEP to be InOnly so when sending to DLQ we would not expect a reply if the MEP was InOut
- // If the checkException is true, sendProcessor will checkException
- // and mark the exchange ERRORHANDLER_HANDLED property to false
- failureProcessor = new SendProcessor(deadLetter, ExchangePattern.InOnly, checkException);
+ failureProcessor = new FatalFallbackErrorHandler(child, true);
}
return failureProcessor;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
index 9e641cf..d57f110 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
@@ -49,6 +49,7 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
protected Processor failureProcessor;
protected Endpoint deadLetter;
protected String deadLetterUri;
+ protected boolean deadLetterHandleNewException = true;
protected boolean useOriginalMessage;
protected boolean asyncDelayedRedelivery;
protected String executorServiceRef;
@@ -103,6 +104,7 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
if (deadLetterUri != null) {
other.setDeadLetterUri(deadLetterUri);
}
+ other.setDeadLetterHandleNewException(deadLetterHandleNewException);
other.setUseOriginalMessage(useOriginalMessage);
other.setAsyncDelayedRedelivery(asyncDelayedRedelivery);
other.setExecutorServiceRef(executorServiceRef);
@@ -204,7 +206,6 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
return this;
}
-
/**
* Will allow asynchronous delayed redeliveries.
*
@@ -340,8 +341,26 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
setUseOriginalMessage(true);
return this;
}
-
-
+
+ /**
+ * Whether the dead letter channel should handle (and ignore) any new exception that may been thrown during sending the
+ * message to the dead letter endpoint.
+ * <p/>
+ * The default value is <tt>true</tt> which means any such kind of exception is handled and ignored. Set this to <tt>false</tt>
+ * to let the exception be propagated back on the {@link org.apache.camel.Exchange}. This can be used in situations
+ * where you use transactions, and want to use Camel's dead letter channel to deal with exceptions during routing,
+ * but if the dead letter channel itself fails because of a new exception being thrown, then by setting this to <tt>false</tt>
+ * the new exceptions is propagated back and set on the {@link org.apache.camel.Exchange}, which allows the transaction
+ * to detect the exception, and rollback.
+ *
+ * @param handleNewException <tt>true</tt> to handle (and ignore), <tt>false</tt> to catch and propagated the exception on the {@link org.apache.camel.Exchange}
+ * @return the builder
+ */
+ public DefaultErrorHandlerBuilder deadLetterHandleNewException(boolean handleNewException) {
+ setDeadLetterHandleNewException(handleNewException);
+ return this;
+ }
+
// Properties
// -------------------------------------------------------------------------
@@ -432,6 +451,14 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
this.deadLetterUri = deadLetter.getEndpointUri();
}
+ public boolean isDeadLetterHandleNewException() {
+ return deadLetterHandleNewException;
+ }
+
+ public void setDeadLetterHandleNewException(boolean deadLetterHandleNewException) {
+ this.deadLetterHandleNewException = deadLetterHandleNewException;
+ }
+
public boolean isUseOriginalMessage() {
return useOriginalMessage;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java b/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java
index 0fb68ff..5501246 100644
--- a/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java
@@ -66,6 +66,8 @@ public class RedeliveryPolicyDefinition {
@XmlAttribute
private String logHandled;
@XmlAttribute
+ private String logNewException;
+ @XmlAttribute
private String logContinued;
@XmlAttribute
private String logExhausted;
@@ -133,6 +135,9 @@ public class RedeliveryPolicyDefinition {
if (logHandled != null) {
answer.setLogHandled(CamelContextHelper.parseBoolean(context, logHandled));
}
+ if (logNewException != null) {
+ answer.setLogNewException(CamelContextHelper.parseBoolean(context, logNewException));
+ }
if (logContinued != null) {
answer.setLogContinued(CamelContextHelper.parseBoolean(context, logContinued));
}
@@ -394,6 +399,33 @@ public class RedeliveryPolicyDefinition {
}
/**
+ * Sets whether new exceptions should be logged or not.
+ * Can be used to include or reduce verbose.
+ * <p/>
+ * A new exception is an exception that was thrown while handling a previous exception.
+ *
+ * @param logNewException whether new exceptions should be logged or not
+ * @return the builder
+ */
+ public RedeliveryPolicyDefinition logNewException(boolean logNewException) {
+ return logNewException(Boolean.toString(logNewException));
+ }
+
+ /**
+ * Sets whether new exceptions should be logged or not (supports property placeholders).
+ * Can be used to include or reduce verbose.
+ * <p/>
+ * A new exception is an exception that was thrown while handling a previous exception.
+ *
+ * @param logNewException whether new exceptions should be logged or not
+ * @return the builder
+ */
+ public RedeliveryPolicyDefinition logNewException(String logNewException) {
+ logNewException(logNewException);
+ return this;
+ }
+
+ /**
* Sets whether continued exceptions should be logged or not.
* Can be used to include or reduce verbose.
*
@@ -684,6 +716,14 @@ public class RedeliveryPolicyDefinition {
this.logHandled = logHandled;
}
+ public String getLogNewException() {
+ return logNewException;
+ }
+
+ public void setLogNewException(String logNewException) {
+ this.logNewException = logNewException;
+ }
+
public String getLogContinued() {
return logContinued;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java b/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
index 7e5863c..c7545ee 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
@@ -48,15 +48,17 @@ public class DeadLetterChannel extends RedeliveryErrorHandler {
* @param exceptionPolicyStrategy strategy for onException handling
* @param deadLetter the failure processor to send failed exchanges to
* @param deadLetterUri an optional uri for logging purpose
+ * @param deadLetterHandleException whether dead letter channel should handle (and ignore) exceptions which may be thrown during sending the message to the dead letter endpoint
* @param useOriginalBodyPolicy should the original IN body be moved to the dead letter queue or the current exchange IN body?
* @param retryWhile retry while
* @param executorService the {@link java.util.concurrent.ScheduledExecutorService} to be used for redelivery thread pool. Can be <tt>null</tt>.
*/
public DeadLetterChannel(CamelContext camelContext, Processor output, CamelLogger logger, Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy,
- ExceptionPolicyStrategy exceptionPolicyStrategy, Processor deadLetter, String deadLetterUri, boolean useOriginalBodyPolicy, Predicate retryWhile,
- ScheduledExecutorService executorService) {
+ ExceptionPolicyStrategy exceptionPolicyStrategy, Processor deadLetter, String deadLetterUri, boolean deadLetterHandleException,
+ boolean useOriginalBodyPolicy, Predicate retryWhile, ScheduledExecutorService executorService) {
- super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, deadLetter, deadLetterUri, useOriginalBodyPolicy, retryWhile, executorService);
+ super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, deadLetter, deadLetterUri, deadLetterHandleException,
+ useOriginalBodyPolicy, retryWhile, executorService);
setExceptionPolicy(exceptionPolicyStrategy);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java
index 5b5a0aa..8f1c931 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java
@@ -47,7 +47,7 @@ public class DefaultErrorHandler extends RedeliveryErrorHandler {
public DefaultErrorHandler(CamelContext camelContext, Processor output, CamelLogger logger, Processor redeliveryProcessor,
RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy exceptionPolicyStrategy, Predicate retryWhile, ScheduledExecutorService executorService) {
- super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, false, retryWhile, executorService);
+ super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, true, false, retryWhile, executorService);
setExceptionPolicy(exceptionPolicyStrategy);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
index b9feb8b..8d03d78 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
@@ -32,8 +32,15 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
private static final Logger LOG = LoggerFactory.getLogger(FatalFallbackErrorHandler.class);
+ private boolean logWarn;
+
public FatalFallbackErrorHandler(Processor processor) {
+ this(processor, false);
+ }
+
+ public FatalFallbackErrorHandler(Processor processor, boolean logWarn) {
super(processor);
+ this.logWarn = logWarn;
}
@Override
@@ -50,12 +57,12 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
+ exchange.getExchangeId() + " using: [" + processor + "].";
if (previous != null) {
msg += " The previous and the new exception will be logged in the following.";
- LOG.error(msg);
- LOG.error("\\--> Previous exception on exchangeId: " + exchange.getExchangeId() , previous);
- LOG.error("\\--> New exception on exchangeId: " + exchange.getExchangeId(), exchange.getException());
+ log(msg);
+ log("\\--> Previous exception on exchangeId: " + exchange.getExchangeId(), previous);
+ log("\\--> New exception on exchangeId: " + exchange.getExchangeId(), exchange.getException());
} else {
- LOG.error(msg);
- LOG.error("\\--> New exception on exchangeId: " + exchange.getExchangeId(), exchange.getException());
+ log(msg);
+ log("\\--> New exception on exchangeId: " + exchange.getExchangeId(), exchange.getException());
}
// we can propagated that exception to the caught property on the exchange
@@ -75,6 +82,26 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
return sync;
}
+ private void log(String message) {
+ log(message, null);
+ }
+
+ private void log(String message, Throwable t) {
+ if (logWarn) {
+ if (t != null) {
+ LOG.warn(message, t);
+ } else {
+ LOG.warn(message);
+ }
+ } else {
+ if (t != null) {
+ LOG.error(message, t);
+ } else {
+ LOG.error(message);
+ }
+ }
+ }
+
@Override
public String toString() {
return "FatalFallbackErrorHandler[" + processor + "]";
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
index 1ea0fd3..c0a8c4f 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
@@ -62,6 +62,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
protected final CamelContext camelContext;
protected final Processor deadLetter;
protected final String deadLetterUri;
+ protected final boolean deadLetterHandleNewException;
protected final Processor output;
protected final AsyncProcessor outputAsync;
protected final Processor redeliveryProcessor;
@@ -81,17 +82,29 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
boolean sync = true;
int redeliveryCounter;
long redeliveryDelay;
- Predicate retryWhilePredicate = retryWhilePolicy;
+ Predicate retryWhilePredicate;
boolean redeliverFromSync;
// default behavior which can be overloaded on a per exception basis
- RedeliveryPolicy currentRedeliveryPolicy = redeliveryPolicy;
- Processor deadLetterProcessor = deadLetter;
+ RedeliveryPolicy currentRedeliveryPolicy;
+ Processor deadLetterProcessor;
Processor failureProcessor;
- Processor onRedeliveryProcessor = redeliveryProcessor;
- Predicate handledPredicate = getDefaultHandledPredicate();
+ Processor onRedeliveryProcessor;
+ Predicate handledPredicate;
Predicate continuedPredicate;
- boolean useOriginalInMessage = useOriginalMessagePolicy;
+ boolean useOriginalInMessage;
+ boolean handleNewException;
+
+ public RedeliveryData() {
+ // init with values from the error handler
+ this.retryWhilePredicate = retryWhilePolicy;
+ this.currentRedeliveryPolicy = redeliveryPolicy;
+ this.deadLetterProcessor = deadLetter;
+ this.onRedeliveryProcessor = redeliveryProcessor;
+ this.handledPredicate = getDefaultHandledPredicate();
+ this.useOriginalInMessage = useOriginalMessagePolicy;
+ this.handleNewException = deadLetterHandleNewException;
+ }
}
/**
@@ -182,7 +195,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
public RedeliveryErrorHandler(CamelContext camelContext, Processor output, CamelLogger logger,
Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy, Processor deadLetter,
- String deadLetterUri, boolean useOriginalMessagePolicy, Predicate retryWhile, ScheduledExecutorService executorService) {
+ String deadLetterUri, boolean deadLetterHandleNewException, boolean useOriginalMessagePolicy, Predicate retryWhile, ScheduledExecutorService executorService) {
ObjectHelper.notNull(camelContext, "CamelContext", this);
ObjectHelper.notNull(redeliveryPolicy, "RedeliveryPolicy", this);
@@ -195,6 +208,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
this.redeliveryPolicy = redeliveryPolicy;
this.logger = logger;
this.deadLetterUri = deadLetterUri;
+ this.deadLetterHandleNewException = deadLetterHandleNewException;
this.useOriginalMessagePolicy = useOriginalMessagePolicy;
this.retryWhilePolicy = retryWhile;
this.executorService = executorService;
@@ -693,7 +707,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
msg = msg + ". Handled and continue routing.";
// log that we failed but want to continue
- logFailedDelivery(false, false, true, exchange, msg, data, null);
+ logFailedDelivery(false, false, false, true, exchange, msg, data, null);
}
protected void prepareExchangeForRedelivery(Exchange exchange, RedeliveryData data) {
@@ -777,7 +791,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
if (!ExchangeHelper.isFailureHandled(exchange) && !ExchangeHelper.isUnitOfWorkExhausted(exchange)) {
String msg = "Failed delivery for " + ExchangeHelper.logIds(exchange)
+ ". On delivery attempt: " + data.redeliveryCounter + " caught: " + e;
- logFailedDelivery(true, false, false, exchange, msg, data, e);
+ logFailedDelivery(true, false, false, false, exchange, msg, data, e);
}
data.redeliveryCounter = incrementRedeliveryCounter(exchange, e, data);
@@ -876,9 +890,9 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
public void done(boolean sync) {
log.trace("Failure processor done: {} processing Exchange: {}", processor, exchange);
try {
- prepareExchangeAfterFailure(exchange, data, shouldHandle, shouldContinue);
+ prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, 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;
+ boolean deadLetterChannel = processor == data.deadLetterProcessor;
EventHelper.notifyExchangeFailureHandled(exchange.getContext(), exchange, processor, deadLetterChannel);
} finally {
// if the fault was handled asynchronously, this should be reflected in the callback as well
@@ -890,7 +904,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
} else {
try {
// no processor but we need to prepare after failure as well
- prepareExchangeAfterFailure(exchange, data, shouldHandle, shouldContinue);
+ prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
} finally {
// callback we are done
callback.done(data.sync);
@@ -905,24 +919,40 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
}
// log that we failed delivery as we are exhausted
- logFailedDelivery(false, handled, false, exchange, msg, data, null);
+ logFailedDelivery(false, false, handled, false, exchange, msg, data, null);
return sync;
}
protected void prepareExchangeAfterFailure(final Exchange exchange, final RedeliveryData data,
- final boolean shouldHandle, final boolean shouldContinue) {
+ final boolean isDeadLetterChannel, final boolean shouldHandle, final boolean shouldContinue) {
+
+ Exception newException = exchange.getException();
+
// we could not process the exchange so we let the failure processor handled it
ExchangeHelper.setFailureHandled(exchange);
+ if (isDeadLetterChannel && shouldHandle) {
+ if (data.handleNewException) {
+ // if there is a new exception then log a warning about that
+ String msg = "DeadLetterChannel failed processing exchange due new exception: " + newException.getMessage()
+ + ". This new exception is handled and ignored. The option deadLetterChannelHandleNewException can be turned off to not handle new exceptions";
+ logFailedDelivery(false, true, false, false, exchange, msg, data, newException);
+ } else {
+ // exception not handled, put exception back in the exchange
+ exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
+ // and put failure endpoint back as well
+ exchange.setProperty(Exchange.FAILURE_ENDPOINT, exchange.getProperty(Exchange.TO_ENDPOINT));
+ }
+ return;
+ }
+
// honor if already set a handling
boolean alreadySet = exchange.getProperty(Exchange.ERRORHANDLER_HANDLED) != null;
if (alreadySet) {
boolean handled = exchange.getProperty(Exchange.ERRORHANDLER_HANDLED, Boolean.class);
log.trace("This exchange has already been marked for handling: {}", handled);
- if (handled) {
- exchange.setException(null);
- } else {
+ if (!handled) {
// exception not handled, put exception back in the exchange
exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
// and put failure endpoint back as well
@@ -953,12 +983,23 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
}
}
- private void logFailedDelivery(boolean shouldRedeliver, boolean handled, boolean continued, Exchange exchange, String message, RedeliveryData data, Throwable e) {
+ private void logFailedDelivery(boolean shouldRedeliver, boolean newException, boolean handled, boolean continued, Exchange exchange, String message, RedeliveryData data, Throwable e) {
if (logger == null) {
return;
}
if (!exchange.isRollbackOnly()) {
+ if (newException && !data.currentRedeliveryPolicy.isLogNewException()) {
+ // do not log new exception
+ return;
+ }
+
+ // if we should not rollback, then check whether logging is enabled
+ if (handled && !data.currentRedeliveryPolicy.isLogHandled()) {
+ // do not log handled
+ return;
+ }
+
// if we should not rollback, then check whether logging is enabled
if (handled && !data.currentRedeliveryPolicy.isLogHandled()) {
// do not log handled
@@ -997,7 +1038,15 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
e = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
}
- if (exchange.isRollbackOnly()) {
+ if (newException) {
+ // special for logging the new exception
+ String msg = message + " " + ExchangeHelper.logIds(exchange);
+ if (e != null && logStackTrace) {
+ logger.log(msg, e, newLogLevel);
+ } else {
+ logger.log(msg, newLogLevel);
+ }
+ } else if (exchange.isRollbackOnly()) {
String msg = "Rollback " + ExchangeHelper.logIds(exchange);
Throwable cause = exchange.getException() != null ? exchange.getException() : exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
if (cause != null) {
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
index ab25bf2..7a62d5c 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
@@ -94,6 +94,7 @@ public class RedeliveryPolicy implements Cloneable, Serializable {
protected boolean logHandled;
protected boolean logContinued;
protected boolean logExhausted = true;
+ protected boolean logNewException = true;
protected boolean logExhaustedMessageHistory = true;
protected boolean logRetryAttempted = true;
protected String delayPattern;
@@ -119,6 +120,7 @@ public class RedeliveryPolicy implements Cloneable, Serializable {
+ ", logHandled=" + logHandled
+ ", logContinued=" + logContinued
+ ", logExhausted=" + logExhausted
+ + ", logNewException=" + logNewException
+ ", logExhaustedMessageHistory=" + logExhaustedMessageHistory
+ ", useExponentialBackOff=" + useExponentialBackOff
+ ", backOffMultiplier=" + backOffMultiplier
@@ -377,6 +379,14 @@ public class RedeliveryPolicy implements Cloneable, Serializable {
}
/**
+ * Sets whether errors should be logged when a new exception occurred during handling a previous exception
+ */
+ public RedeliveryPolicy logNewException(boolean logNewException) {
+ setLogNewException(logNewException);
+ return this;
+ }
+
+ /**
* Sets whether to log exhausted errors
*/
public RedeliveryPolicy logExhausted(boolean logExhausted) {
@@ -630,6 +640,17 @@ public class RedeliveryPolicy implements Cloneable, Serializable {
this.logHandled = logHandled;
}
+ public boolean isLogNewException() {
+ return logNewException;
+ }
+
+ /**
+ * Sets whether errors should be logged when a new exception occurred during handling a previous exception
+ */
+ public void setLogNewException(boolean logNewException) {
+ this.logNewException = logNewException;
+ }
+
public boolean isLogContinued() {
return logContinued;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java b/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
index 59ceb85..9b9e0d3 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
@@ -57,22 +57,16 @@ public class SendProcessor extends ServiceSupport implements AsyncProcessor, Tra
protected AsyncProcessor producer;
protected Endpoint destination;
protected ExchangePattern destinationExchangePattern;
- protected final boolean unhandleException;
public SendProcessor(Endpoint destination) {
this(destination, null);
}
public SendProcessor(Endpoint destination, ExchangePattern pattern) {
- this(destination, pattern, false);
- }
-
- public SendProcessor(Endpoint destination, ExchangePattern pattern, boolean unhandleException) {
ObjectHelper.notNull(destination, "destination");
this.destination = destination;
this.camelContext = destination.getCamelContext();
this.pattern = pattern;
- this.unhandleException = unhandleException;
try {
this.destinationExchangePattern = null;
this.destinationExchangePattern = EndpointHelper.resolveExchangePatternFromUrl(destination.getEndpointUri());
@@ -142,14 +136,12 @@ public class SendProcessor extends ServiceSupport implements AsyncProcessor, Tra
long timeTaken = watch.stop();
EventHelper.notifyExchangeSent(target.getContext(), target, destination, timeTaken);
} finally {
- checkException(target);
callback.done(doneSync);
}
}
});
} catch (Throwable throwable) {
exchange.setException(throwable);
- checkException(exchange);
callback.done(sync);
}
@@ -166,7 +158,6 @@ public class SendProcessor extends ServiceSupport implements AsyncProcessor, Tra
public void done(boolean doneSync) {
// restore previous MEP
target.setPattern(existingPattern);
- checkException(target);
// signal we are done
callback.done(doneSync);
}
@@ -175,15 +166,6 @@ public class SendProcessor extends ServiceSupport implements AsyncProcessor, Tra
});
}
- protected void checkException(Exchange exchange) {
- if (unhandleException && exchange.getException() != null) {
- // Override the default setting of DeadLetterChannel
- exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, "false");
- // just override the exception with the new added
- exchange.setProperty(Exchange.EXCEPTION_CAUGHT, exchange.getException());
- }
- }
-
public Endpoint getDestination() {
return destination;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java
index e8d1b3a..121f905 100644
--- a/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java
@@ -37,7 +37,7 @@ public final class CamelJmsTestHelper {
}
public static PooledConnectionFactory createPooledConnectionFactory() {
- ConnectionFactory cf = createConnectionFactory(null);
+ ConnectionFactory cf = createConnectionFactory(null, null);
PooledConnectionFactory pooled = new PooledConnectionFactory();
pooled.setConnectionFactory(cf);
pooled.setMaxConnections(8);
@@ -45,10 +45,10 @@ public final class CamelJmsTestHelper {
}
public static ConnectionFactory createConnectionFactory() {
- return createConnectionFactory(null);
+ return createConnectionFactory(null, null);
}
- public static ConnectionFactory createConnectionFactory(String options) {
+ public static ConnectionFactory createConnectionFactory(String options, Integer maximumRedeliveries) {
// using a unique broker name improves testing when running the entire test suite in the same JVM
int id = counter.incrementAndGet();
String url = "vm://test-broker-" + id + "?broker.persistent=false&broker.useJmx=false";
@@ -65,6 +65,9 @@ public final class CamelJmsTestHelper {
// Another way of guaranteeing order is to use persistent messages or transactions.
connectionFactory.setUseAsyncSend(false);
connectionFactory.setAlwaysSessionAsync(false);
+ if (maximumRedeliveries != null) {
+ connectionFactory.getRedeliveryPolicy().setMaximumRedeliveries(maximumRedeliveries);
+ }
return connectionFactory;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsDeadLetterChannelHandlerExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsDeadLetterChannelHandlerExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsDeadLetterChannelHandlerExceptionTest.java
deleted file mode 100644
index 8604e87..0000000
--- a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsDeadLetterChannelHandlerExceptionTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * 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.component.jms.issues;
-
-
-import java.util.UUID;
-
-import javax.jms.ConnectionFactory;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.Handler;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.jms.CamelJmsTestHelper;
-import org.apache.camel.test.junit4.CamelTestSupport;
-import org.junit.Test;
-
-import static org.apache.camel.component.jms.JmsComponent.jmsComponentTransacted;
-
-public class JmsDeadLetterChannelHandlerExceptionTest extends CamelTestSupport {
-
- public static class BadErrorHandler {
- @Handler
- public void onException(Exchange exchange, Exception exception) throws Exception {
-
- throw new RuntimeException("error in errorhandler");
- }
- }
-
- private final String testingEndpoint = "activemq:test." + getClass().getName();
-
- @Override
- protected RouteBuilder createRouteBuilder() throws Exception {
- return new RouteBuilder() {
- @Override
- public void configure() throws Exception {
-
- errorHandler(deadLetterChannel("bean:" + BadErrorHandler.class.getName()).checkException());
-
- from(testingEndpoint).throwException(new RuntimeException("bad error"));
-
-
- }
- };
- }
-
- @Test
- public void shouldNotLoseMessagesOnExceptionInErrorHandler() throws Exception {
- UUID message = UUID.randomUUID();
- template.sendBody(testingEndpoint, message);
-
- Object dlqBody = consumer.receiveBody("activemq:ActiveMQ.DLQ", 3000);
-
- assertEquals(message, dlqBody);
- }
-
- protected CamelContext createCamelContext() throws Exception {
- CamelContext camelContext = super.createCamelContext();
- ConnectionFactory connectionFactory = CamelJmsTestHelper.createConnectionFactory();
- camelContext.addComponent("activemq", jmsComponentTransacted(connectionFactory));
- return camelContext;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
new file mode 100644
index 0000000..9052144
--- /dev/null
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
@@ -0,0 +1,84 @@
+/**
+ * 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.component.jms.issues;
+
+import javax.jms.ConnectionFactory;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Handler;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jms.CamelJmsTestHelper;
+import org.apache.camel.component.jms.JmsComponent;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+import static org.apache.camel.component.jms.JmsComponent.jmsComponentTransacted;
+
+public class JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest extends CamelTestSupport {
+
+ public static class BadErrorHandler {
+ @Handler
+ public void onException(Exchange exchange, Exception exception) throws Exception {
+ throw new RuntimeException("error in errorhandler");
+ }
+ }
+
+ protected final String testingEndpoint = "activemq:test." + getClass().getName();
+
+ protected boolean isHandleNew() {
+ return true;
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ // we use DLC to handle the exception but if it throw a new exception
+ // then the DLC handles that too (the transaction will always commit)
+ errorHandler(deadLetterChannel("bean:" + BadErrorHandler.class.getName())
+ .deadLetterHandleNewException(isHandleNew()));
+
+ from(testingEndpoint)
+ .log("Incoming JMS message ${body}")
+ .throwException(new RuntimeException("bad error"));
+ }
+ };
+ }
+
+ @Test
+ public void shouldNotLoseMessagesOnExceptionInErrorHandler() throws Exception {
+ template.sendBody(testingEndpoint, "Hello World");
+
+ // as we handle new exception, then the exception is ignored
+ // and causes the transaction to commit, so there is no message in the ActiveMQ DLQ queue
+ Object dlqBody = consumer.receiveBody("activemq:ActiveMQ.DLQ", 2000);
+ assertNull("Should not rollback the transaction", dlqBody);
+ }
+
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext camelContext = super.createCamelContext();
+
+ // no redeliveries
+ ConnectionFactory connectionFactory = CamelJmsTestHelper.createConnectionFactory(null, 0);
+ JmsComponent component = jmsComponentTransacted(connectionFactory);
+ camelContext.addComponent("activemq", component);
+ return camelContext;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest.java
new file mode 100644
index 0000000..5701a71
--- /dev/null
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest.java
@@ -0,0 +1,39 @@
+/**
+ * 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.component.jms.issues;
+
+import org.junit.Test;
+
+public class JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest extends JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest {
+
+ @Override
+ protected boolean isHandleNew() {
+ return false;
+ }
+
+ @Test
+ public void shouldNotLoseMessagesOnExceptionInErrorHandler() throws Exception {
+ template.sendBody(testingEndpoint, "Hello World");
+
+ // as we do not handle new exception, then the exception propagates back
+ // and causes the transaction to rollback, and we can find the message in the ActiveMQ DLQ
+ Object dlqBody = consumer.receiveBody("activemq:ActiveMQ.DLQ", 2000);
+ assertEquals("Hello World", dlqBody);
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedOnExceptionRollbackOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedOnExceptionRollbackOnExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedOnExceptionRollbackOnExceptionTest.java
new file mode 100644
index 0000000..4360436
--- /dev/null
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedOnExceptionRollbackOnExceptionTest.java
@@ -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.component.jms.issues;
+
+import javax.jms.ConnectionFactory;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Handler;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jms.CamelJmsTestHelper;
+import org.apache.camel.component.jms.JmsComponent;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+import static org.apache.camel.component.jms.JmsComponent.jmsComponentTransacted;
+
+public class JmsTransactedOnExceptionRollbackOnExceptionTest extends CamelTestSupport {
+
+ public static class BadErrorHandler {
+ @Handler
+ public void onException(Exchange exchange, Exception exception) throws Exception {
+ throw new RuntimeException("error in errorhandler");
+ }
+ }
+
+ protected final String testingEndpoint = "activemq:test." + getClass().getName();
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ // we attempt to handle the exception but if it throw a new exception
+ // then it causes the JMS transaction to rollback
+ onException(Exception.class).handled(true).bean(BadErrorHandler.class);
+
+ from(testingEndpoint)
+ .log("Incoming JMS message ${body}")
+ .throwException(new RuntimeException("bad error"));
+ }
+ };
+ }
+
+ @Test
+ public void shouldNotLoseMessagesOnExceptionInErrorHandler() throws Exception {
+ template.sendBody(testingEndpoint, "Hello World");
+
+ Object dlqBody = consumer.receiveBody("activemq:ActiveMQ.DLQ", 2000);
+ assertEquals("Hello World", dlqBody);
+ }
+
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext camelContext = super.createCamelContext();
+
+ // no redeliveries
+ ConnectionFactory connectionFactory = CamelJmsTestHelper.createConnectionFactory(null, 0);
+ JmsComponent component = jmsComponentTransacted(connectionFactory);
+ camelContext.addComponent("activemq", component);
+ return camelContext;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/resources/log4j.properties b/components/camel-jms/src/test/resources/log4j.properties
index 4732904..14beeb0 100644
--- a/components/camel-jms/src/test/resources/log4j.properties
+++ b/components/camel-jms/src/test/resources/log4j.properties
@@ -18,7 +18,7 @@
#
# The logging properties used
#
-log4j.rootLogger=INFO, out
+log4j.rootLogger=INFO, stdout
#log4j.logger.org.apache.activemq.spring=WARN
#log4j.logger.org.apache.camel.component.jms=DEBUG
[09/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Posted by da...@apache.org.
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/1a668e86
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/1a668e86
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/1a668e86
Branch: refs/heads/master
Commit: 1a668e867144493423ba80557fb6a1e82a1082a2
Parents: fb120df
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 17:27:43 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 17:27:43 2015 +0100
----------------------------------------------------------------------
.../mbean/ManagedErrorHandlerMBean.java | 9 ++++++
.../management/mbean/ManagedErrorHandler.java | 29 ++++++++++++++++++++
.../camel/processor/RedeliveryErrorHandler.java | 4 +++
.../ManagedErrorHandlerOptionsTest.java | 3 ++
4 files changed, 45 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/1a668e86/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedErrorHandlerMBean.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedErrorHandlerMBean.java b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedErrorHandlerMBean.java
index 56ed78d..9ba5c74 100644
--- a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedErrorHandlerMBean.java
+++ b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedErrorHandlerMBean.java
@@ -35,6 +35,9 @@ public interface ManagedErrorHandlerMBean {
@ManagedAttribute(description = "When a message is moved to dead letter channel is it the original message or recent message")
boolean isDeadLetterUseOriginalMessage();
+ @ManagedAttribute(description = "Does this error handler handle new exceptions which may occur during error handling")
+ boolean isDeadLetterHandleNewException();
+
@ManagedAttribute(description = "Does this error handler support transactions")
boolean isSupportTransactions();
@@ -113,6 +116,12 @@ public interface ManagedErrorHandlerMBean {
@ManagedAttribute(description = "RedeliveryPolicy for logging handled exceptions")
void setLogHandled(Boolean log);
+ @ManagedAttribute(description = "RedeliveryPolicy for logging new exceptions")
+ Boolean getLogNewException();
+
+ @ManagedAttribute(description = "RedeliveryPolicy for logging new exceptions")
+ void setLogNewException(Boolean log);
+
@ManagedAttribute(description = "RedeliveryPolicy for logging handled and continued exceptions")
Boolean getLogContinued();
http://git-wip-us.apache.org/repos/asf/camel/blob/1a668e86/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedErrorHandler.java b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedErrorHandler.java
index d4fe005..3bf076b 100644
--- a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedErrorHandler.java
@@ -21,6 +21,7 @@ import org.apache.camel.LoggingLevel;
import org.apache.camel.Processor;
import org.apache.camel.api.management.ManagedResource;
import org.apache.camel.api.management.mbean.ManagedErrorHandlerMBean;
+import org.apache.camel.builder.DefaultErrorHandlerBuilder;
import org.apache.camel.processor.ErrorHandlerSupport;
import org.apache.camel.processor.RedeliveryErrorHandler;
import org.apache.camel.spi.ManagementStrategy;
@@ -87,6 +88,16 @@ public class ManagedErrorHandler implements ManagedErrorHandlerMBean {
return redelivery.isUseOriginalMessagePolicy();
}
+ public boolean isDeadLetterHandleNewException() {
+ if (!isSupportRedelivery()) {
+ return false;
+ }
+
+ // must be a dead letter channel
+ RedeliveryErrorHandler redelivery = (RedeliveryErrorHandler) errorHandler;
+ return isDeadLetterChannel() && redelivery.isDeadLetterHandleNewException();
+ }
+
public boolean isSupportTransactions() {
if (errorHandler instanceof ErrorHandlerSupport) {
ErrorHandlerSupport ehs = (ErrorHandlerSupport) errorHandler;
@@ -321,6 +332,24 @@ public class ManagedErrorHandler implements ManagedErrorHandlerMBean {
redelivery.getRedeliveryPolicy().setLogHandled(log);
}
+ public Boolean getLogNewException() {
+ if (!isSupportRedelivery()) {
+ return null;
+ }
+
+ RedeliveryErrorHandler redelivery = (RedeliveryErrorHandler) errorHandler;
+ return redelivery.getRedeliveryPolicy().isLogNewException();
+ }
+
+ public void setLogNewException(Boolean log) {
+ if (!isSupportRedelivery()) {
+ throw new IllegalArgumentException("This error handler does not support redelivery");
+ }
+
+ RedeliveryErrorHandler redelivery = (RedeliveryErrorHandler) errorHandler;
+ redelivery.getRedeliveryPolicy().setLogNewException(log);
+ }
+
public Boolean getLogContinued() {
if (!isSupportRedelivery()) {
return null;
http://git-wip-us.apache.org/repos/asf/camel/blob/1a668e86/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
index 9fcfc0f..98757e9 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
@@ -672,6 +672,10 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
return useOriginalMessagePolicy;
}
+ public boolean isDeadLetterHandleNewException() {
+ return deadLetterHandleNewException;
+ }
+
public RedeliveryPolicy getRedeliveryPolicy() {
return redeliveryPolicy;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/1a668e86/camel-core/src/test/java/org/apache/camel/management/ManagedErrorHandlerOptionsTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedErrorHandlerOptionsTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedErrorHandlerOptionsTest.java
index 8182f51..f479095 100644
--- a/camel-core/src/test/java/org/apache/camel/management/ManagedErrorHandlerOptionsTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedErrorHandlerOptionsTest.java
@@ -100,6 +100,9 @@ public class ManagedErrorHandlerOptionsTest extends ManagementTestSupport {
Boolean uebf = (Boolean) mbeanServer.getAttribute(on, "UseExponentialBackOff");
assertEquals(true, uebf.booleanValue());
+ Boolean ne = (Boolean) mbeanServer.getAttribute(on, "DeadLetterHandleNewException");
+ assertEquals(false, ne.booleanValue());
+
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedMessageCount(1);
[05/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Posted by da...@apache.org.
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4136f927
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4136f927
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4136f927
Branch: refs/heads/master
Commit: 4136f9272e1cc646aa69d6af93d6ca42b79ccc1e
Parents: 42ded87
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 14:53:54 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 14:53:54 2015 +0100
----------------------------------------------------------------------
.../apache/camel/blueprint/CamelErrorHandlerFactoryBean.java | 5 +++++
.../java/org/apache/camel/spring/ErrorHandlerDefinition.java | 2 ++
.../camel/spring/handler/ErrorHandlerDefinitionParser.java | 5 +++++
3 files changed, 12 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/4136f927/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
index 99b6c09..f81867b 100644
--- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
@@ -44,6 +44,8 @@ public class CamelErrorHandlerFactoryBean extends AbstractCamelFactoryBean<Error
@XmlAttribute
private String deadLetterUri;
@XmlAttribute
+ private Boolean deadLetterHandleNewException;
+ @XmlAttribute
private LoggingLevel level;
@XmlAttribute
private String logName;
@@ -70,6 +72,9 @@ public class CamelErrorHandlerFactoryBean extends AbstractCamelFactoryBean<Error
if (deadLetterUri != null) {
handler.setDeadLetterUri(deadLetterUri);
}
+ if (deadLetterHandleNewException != null) {
+ handler.setDeadLetterHandleNewException(deadLetterHandleNewException);
+ }
if (useOriginalMessage != null) {
handler.setUseOriginalMessage(useOriginalMessage);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/4136f927/components/camel-spring/src/main/java/org/apache/camel/spring/ErrorHandlerDefinition.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/ErrorHandlerDefinition.java b/components/camel-spring/src/main/java/org/apache/camel/spring/ErrorHandlerDefinition.java
index d2d6ffd..90281fe 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/ErrorHandlerDefinition.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/ErrorHandlerDefinition.java
@@ -38,6 +38,8 @@ public class ErrorHandlerDefinition extends IdentifiedType {
@XmlAttribute
private String deadLetterUri;
@XmlAttribute
+ private String deadLetterHandleNewException;
+ @XmlAttribute
private LoggingLevel level;
@XmlAttribute
private LoggingLevel rollbackLoggingLevel;
http://git-wip-us.apache.org/repos/asf/camel/blob/4136f927/components/camel-spring/src/main/java/org/apache/camel/spring/handler/ErrorHandlerDefinitionParser.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/ErrorHandlerDefinitionParser.java b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/ErrorHandlerDefinitionParser.java
index 305ea89..c9f2228 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/ErrorHandlerDefinitionParser.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/ErrorHandlerDefinitionParser.java
@@ -114,6 +114,11 @@ public class ErrorHandlerDefinitionParser extends BeanDefinitionParser {
throw new IllegalArgumentException("Attribute deadLetterUri can only be used if type is "
+ ErrorHandlerType.DeadLetterChannel.name() + ", in error handler with id: " + id);
}
+ String deadLetterHandleNewException = element.getAttribute("deadLetterHandleNewException");
+ if (ObjectHelper.isNotEmpty(deadLetterHandleNewException) && !type.equals(ErrorHandlerType.DeadLetterChannel)) {
+ throw new IllegalArgumentException("Attribute deadLetterHandleNewException can only be used if type is "
+ + ErrorHandlerType.DeadLetterChannel.name() + ", in error handler with id: " + id);
+ }
String transactionTemplateRef = element.getAttribute("transactionTemplateRef");
if (ObjectHelper.isNotEmpty(transactionTemplateRef) && !type.equals(ErrorHandlerType.TransactionErrorHandler)) {
throw new IllegalArgumentException("Attribute transactionTemplateRef can only be used if type is "
[02/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Posted by da...@apache.org.
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/27136c33
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/27136c33
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/27136c33
Branch: refs/heads/master
Commit: 27136c3338881a3f24c70b7be5df2582bb970a99
Parents: b05668f
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 14:08:02 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 14:08:02 2015 +0100
----------------------------------------------------------------------
.../camel/model/OnExceptionDefinition.java | 22 ++++++++++++++++++++
.../camel/processor/RedeliveryErrorHandler.java | 6 ------
2 files changed, 22 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/27136c33/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java b/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java
index 2917707..e928f66 100644
--- a/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java
@@ -535,6 +535,28 @@ public class OnExceptionDefinition extends ProcessorDefinition<OnExceptionDefini
}
/**
+ * Sets whether new exceptions should be logged or not (supports property placeholders).
+ * Can be used to include or reduce verbose.
+ * <p/>
+ * A new exception is an exception that was thrown while handling a previous exception.
+ */
+ public OnExceptionDefinition logNewException(boolean logNewException) {
+ getOrCreateRedeliveryPolicy().logNewException(logNewException);
+ return this;
+ }
+
+ /**
+ * Sets whether new exceptions should be logged or not (supports property placeholders).
+ * Can be used to include or reduce verbose.
+ * <p/>
+ * A new exception is an exception that was thrown while handling a previous exception.
+ */
+ public OnExceptionDefinition logNewException(String logNewException) {
+ getOrCreateRedeliveryPolicy().logNewException(logNewException);
+ return this;
+ }
+
+ /**
* Sets whether to log errors even if its continued
*/
public OnExceptionDefinition logContinued(boolean logContinued) {
http://git-wip-us.apache.org/repos/asf/camel/blob/27136c33/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
index c0a8c4f..9120221 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
@@ -1000,12 +1000,6 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
return;
}
- // if we should not rollback, then check whether logging is enabled
- if (handled && !data.currentRedeliveryPolicy.isLogHandled()) {
- // do not log handled
- return;
- }
-
if (continued && !data.currentRedeliveryPolicy.isLogContinued()) {
// do not log handled
return;
[06/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Posted by da...@apache.org.
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/77851e15
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/77851e15
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/77851e15
Branch: refs/heads/master
Commit: 77851e15d77855c3b26a6bea3857f6fc57672457
Parents: 4136f92
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 15:24:14 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 16:33:56 2015 +0100
----------------------------------------------------------------------
.../management/event/DefaultEventFactory.java | 8 +-
.../camel/processor/DeadLetterChannel.java | 6 -
.../processor/FatalFallbackErrorHandler.java | 23 ++--
.../camel/processor/RedeliveryErrorHandler.java | 128 ++++++++++---------
...xceptionContinuedNoFailureProcessorTest.java | 60 +++++++++
...ceptionNotHandledNoFailureProcessorTest.java | 61 +++++++++
6 files changed, 213 insertions(+), 73 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/77851e15/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java b/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java
index 6019b72..c018b11 100644
--- a/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java
+++ b/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java
@@ -19,6 +19,7 @@ package org.apache.camel.management.event;
import java.util.EventObject;
import org.apache.camel.CamelContext;
+import org.apache.camel.DelegateProcessor;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
@@ -93,7 +94,12 @@ public class DefaultEventFactory implements EventFactory {
}
public EventObject createExchangeFailureHandledEvent(Exchange exchange, Processor failureHandler, boolean deadLetterChannel) {
- return new ExchangeFailureHandledEvent(exchange, failureHandler, deadLetterChannel);
+ // unwrap delegate processor
+ Processor handler = failureHandler;
+ if (handler instanceof DelegateProcessor) {
+ handler = ((DelegateProcessor) handler).getProcessor();
+ }
+ return new ExchangeFailureHandledEvent(exchange, handler, deadLetterChannel);
}
public EventObject createExchangeRedeliveryEvent(Exchange exchange, int attempt) {
http://git-wip-us.apache.org/repos/asf/camel/blob/77851e15/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java b/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
index c7545ee..b8da447 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
@@ -77,12 +77,6 @@ public class DeadLetterChannel extends RedeliveryErrorHandler {
}
@Override
- protected Predicate getDefaultHandledPredicate() {
- // DeadLetterChannel handles errors before sending to DLQ
- return ExpressionToPredicateAdapter.toPredicate(ExpressionBuilder.constantExpression(true));
- }
-
- @Override
protected boolean isRunAllowedOnPreparingShutdown() {
// allow tu run as we want to move the message eto DLC, instead of rejecting the message
return true;
http://git-wip-us.apache.org/repos/asf/camel/blob/77851e15/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
index 8d03d78..75c02c5 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
@@ -32,15 +32,15 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
private static final Logger LOG = LoggerFactory.getLogger(FatalFallbackErrorHandler.class);
- private boolean logWarn;
+ private boolean deadLetterChannel;
public FatalFallbackErrorHandler(Processor processor) {
this(processor, false);
}
- public FatalFallbackErrorHandler(Processor processor, boolean logWarn) {
+ public FatalFallbackErrorHandler(Processor processor, boolean isDeadLetterChannel) {
super(processor);
- this.logWarn = logWarn;
+ this.deadLetterChannel = isDeadLetterChannel;
}
@Override
@@ -70,10 +70,16 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
// to be visible in the error handler
exchange.setProperty(Exchange.EXCEPTION_CAUGHT, exchange.getException());
- // mark this exchange as already been error handler handled (just by having this property)
- // the false value mean the caught exception will be kept on the exchange, causing the
- // exception to be propagated back to the caller, and to break out routing
- exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, false);
+ if (deadLetterChannel) {
+ // special for dead letter channel as we want to let it determine what to do, depending how
+ // it has been configured
+ exchange.removeProperty(Exchange.ERRORHANDLER_HANDLED);
+ } else {
+ // mark this exchange as already been error handler handled (just by having this property)
+ // the false value mean the caught exception will be kept on the exchange, causing the
+ // exception to be propagated back to the caller, and to break out routing
+ exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, false);
+ }
}
callback.done(doneSync);
}
@@ -87,7 +93,8 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
}
private void log(String message, Throwable t) {
- if (logWarn) {
+ // when using dead letter channel we only want to log at WARN level
+ if (deadLetterChannel) {
if (t != null) {
LOG.warn(message, t);
} else {
http://git-wip-us.apache.org/repos/asf/camel/blob/77851e15/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
index 8fdea29..dbe3760 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
@@ -46,6 +46,7 @@ import org.apache.camel.util.ExchangeHelper;
import org.apache.camel.util.MessageHelper;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.ServiceHelper;
+import org.apache.camel.util.URISupport;
/**
* Base redeliverable error handler that also supports a final dead letter queue in case
@@ -382,7 +383,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
}
// we should always invoke the deliverToFailureProcessor as it prepares, logs and does a fair
// bit of work for exhausted exchanges (its only the target processor which may be null if handled by a savepoint)
- boolean isDeadLetterChannel = isDeadLetterChannel() && target == data.deadLetterProcessor;
+ boolean isDeadLetterChannel = isDeadLetterChannel() && (target == null || target == data.deadLetterProcessor);
boolean sync = deliverToFailureProcessor(target, isDeadLetterChannel, exchange, data, callback);
// we are breaking out
return sync;
@@ -833,13 +834,15 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
// clear exception as we let the failure processor handle it
exchange.setException(null);
- // always handle if dead letter channel
- final boolean shouldHandle = isDeadLetterChannel || shouldHandled(exchange, data);
- final boolean shouldContinue = shouldContinue(exchange, data);
+ final Boolean shouldHandle = shouldHandle(exchange, data);
+ final Boolean shouldContinue = shouldContinue(exchange, data);
+
// regard both handled or continued as being handled
boolean handled = false;
- if (shouldHandle || shouldContinue) {
+ // always handle if dead letter channel
+ boolean handleOrContinue = isDeadLetterChannel || (shouldHandle != null && shouldHandle) || (shouldContinue != null && shouldContinue);
+ if (handleOrContinue) {
// its handled then remove traces of redelivery attempted
exchange.getIn().removeHeader(Exchange.REDELIVERED);
exchange.getIn().removeHeader(Exchange.REDELIVERY_COUNTER);
@@ -890,7 +893,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
public void done(boolean sync) {
log.trace("Failure processor done: {} processing Exchange: {}", processor, exchange);
try {
- prepareExchangeAfterFailure(processor, exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
+ prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
// fire event as we had a failure processor to handle it, which there is a event for
boolean deadLetterChannel = processor == data.deadLetterProcessor;
EventHelper.notifyExchangeFailureHandled(exchange.getContext(), exchange, processor, deadLetterChannel);
@@ -904,7 +907,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
} else {
try {
// no processor but we need to prepare after failure as well
- prepareExchangeAfterFailure(processor, exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
+ prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
} finally {
// callback we are done
callback.done(data.sync);
@@ -924,39 +927,14 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
return sync;
}
- protected void prepareExchangeAfterFailure(final Processor failureProcessor, final Exchange exchange, final RedeliveryData data,
- final boolean isDeadLetterChannel, final boolean shouldHandle, final boolean shouldContinue) {
+ protected void prepareExchangeAfterFailure(final Exchange exchange, final RedeliveryData data, final boolean isDeadLetterChannel,
+ final Boolean shouldHandle, final Boolean shouldContinue) {
Exception newException = exchange.getException();
- if (newException != null && data.currentRedeliveryPolicy.isLogNewException()) {
- boolean handled = data.handleNewException;
- String msg = "New exception occurred during processing by the failure processor " + failureProcessor + " due " + newException.getMessage();
- if (handled) {
- msg += ". The new exception is being handled as deadLetterHandleNewException=true.";
- } else {
- msg += ". The new exception is not handled as deadLetterHandleNewException=false.";
- }
- logFailedDelivery(false, true, handled, false, exchange, msg, data, newException);
- }
// we could not process the exchange so we let the failure processor handled it
ExchangeHelper.setFailureHandled(exchange);
- // special for dead letter channel where it by default handle new exceptions, but its possible to turn that off
- if (isDeadLetterChannel && shouldHandle) {
- boolean handled = data.handleNewException;
- if (handled) {
- // if there is a new exception then log a warning about that
- log.trace("This exchange is handled so its marked as not failed: {}", exchange);
- } else {
- // exception not handled, put exception back in the exchange
- exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
- // and put failure endpoint back as well
- exchange.setProperty(Exchange.FAILURE_ENDPOINT, exchange.getProperty(Exchange.TO_ENDPOINT));
- }
- return;
- }
-
// honor if already set a handling
boolean alreadySet = exchange.getProperty(Exchange.ERRORHANDLER_HANDLED) != null;
if (alreadySet) {
@@ -971,25 +949,59 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
return;
}
- 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) {
+ // dead letter channel is special
+ if (shouldContinue != null && shouldContinue) {
log.trace("This exchange is continued: {}", exchange);
// okay we want to continue then prepare the exchange for that as well
prepareExchangeForContinue(exchange, data);
+ } else if (shouldHandle != null && shouldHandle) {
+ log.trace("This exchange is handled so its marked as not failed: {}", exchange);
+ exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, Boolean.TRUE);
} else {
- log.trace("This exchange is not handled or continued so its marked as failed: {}", exchange);
- // exception not handled, put exception back in the exchange
- exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, Boolean.FALSE);
- exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
- // and put failure endpoint back as well
- exchange.setProperty(Exchange.FAILURE_ENDPOINT, exchange.getProperty(Exchange.TO_ENDPOINT));
- // and store the route id so we know in which route we failed
- UnitOfWork uow = exchange.getUnitOfWork();
- if (uow != null && uow.getRouteContext() != null) {
- exchange.setProperty(Exchange.FAILURE_ROUTE_ID, uow.getRouteContext().getRoute().getId());
+ // okay the redelivery policy are not explicit set to true, so we should allow to check for some
+ // special situations when using dead letter channel
+ if (isDeadLetterChannel) {
+
+ // use the handled option from the DLC
+ boolean handled = data.handleNewException;
+
+ // when using DLC then log new exception whether its being handled or not, as otherwise it may appear as
+ // the DLC swallow new exceptions by default (which is by design to ensure the DLC always complete,
+ // to avoid causing endless poison messages that fails forever)
+ if (newException != null && data.currentRedeliveryPolicy.isLogNewException()) {
+ String uri = URISupport.sanitizeUri(deadLetterUri);
+ String msg = "New exception occurred during processing by the DeadLetterChannel[" + uri + "] due " + newException.getMessage();
+ if (handled) {
+ msg += ". The new exception is being handled as deadLetterHandleNewException=true.";
+ } else {
+ msg += ". The new exception is not handled as deadLetterHandleNewException=false.";
+ }
+ logFailedDelivery(false, true, handled, false, exchange, msg, data, newException);
+ }
+
+ if (handled) {
+ log.trace("This exchange is handled so its marked as not failed: {}", exchange);
+ exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, Boolean.TRUE);
+ return;
+ }
}
+
+ // not handled by default
+ prepareExchangeAfterFailureNotHandled(exchange);
+ }
+ }
+
+ private void prepareExchangeAfterFailureNotHandled(Exchange exchange) {
+ log.trace("This exchange is not handled or continued so its marked as failed: {}", exchange);
+ // exception not handled, put exception back in the exchange
+ exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, Boolean.FALSE);
+ exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
+ // and put failure endpoint back as well
+ exchange.setProperty(Exchange.FAILURE_ENDPOINT, exchange.getProperty(Exchange.TO_ENDPOINT));
+ // and store the route id so we know in which route we failed
+ UnitOfWork uow = exchange.getUnitOfWork();
+ if (uow != null && uow.getRouteContext() != null) {
+ exchange.setProperty(Exchange.FAILURE_ROUTE_ID, uow.getRouteContext().getRoute().getId());
}
}
@@ -1137,33 +1149,33 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
}
/**
- * Determines whether or not to continue if we are exhausted.
+ * Determines whether the redelivery configuration has a continued predicate
*
* @param exchange the current exchange
* @param data the redelivery data
- * @return <tt>true</tt> to continue, or <tt>false</tt> to exhaust.
+ * @return <tt>true</tt> to continue, or <tt>false</tt> to attempt to handle, or <tt>null</tt> if continued predicate has not been configured.
*/
- private boolean shouldContinue(Exchange exchange, RedeliveryData data) {
+ private Boolean shouldContinue(Exchange exchange, RedeliveryData data) {
if (data.continuedPredicate != null) {
return data.continuedPredicate.matches(exchange);
}
- // do not continue by default
- return false;
+ // no predicate
+ return null;
}
/**
- * Determines whether or not to handle if we are exhausted.
+ * Determines whether the redelivery configuration has a handled predicate
*
* @param exchange the current exchange
* @param data the redelivery data
- * @return <tt>true</tt> to handle, or <tt>false</tt> to exhaust.
+ * @return <tt>true</tt> to handle, or <tt>false</tt> to exhaust, or <tt>null</tt> if handled predicate has not been configured.
*/
- private boolean shouldHandled(Exchange exchange, RedeliveryData data) {
+ private Boolean shouldHandle(Exchange exchange, RedeliveryData data) {
if (data.handledPredicate != null) {
return data.handledPredicate.matches(exchange);
}
- // do not handle by default
- return false;
+ // no predicate
+ return null;
}
/**
http://git-wip-us.apache.org/repos/asf/camel/blob/77851e15/camel-core/src/test/java/org/apache/camel/issues/OnExceptionContinuedNoFailureProcessorTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/issues/OnExceptionContinuedNoFailureProcessorTest.java b/camel-core/src/test/java/org/apache/camel/issues/OnExceptionContinuedNoFailureProcessorTest.java
new file mode 100644
index 0000000..cad431e
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/issues/OnExceptionContinuedNoFailureProcessorTest.java
@@ -0,0 +1,60 @@
+/**
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ *
+ */
+public class OnExceptionContinuedNoFailureProcessorTest extends ContextTestSupport {
+
+ public void testOnException() throws Exception {
+ getMockEndpoint("mock:end").expectedMessageCount(1);
+ getMockEndpoint("mock:error").expectedMessageCount(1);
+
+ template.sendBody("direct:start", "Hello World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ errorHandler(deadLetterChannel("mock:error"));
+
+ // continue runtime exception
+ onException(RuntimeException.class)
+ .continued(true);
+
+ from("direct:start").
+ process(new Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ throw new RuntimeException("FAIL!");
+ }
+ }).
+ to("mock:end");
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/77851e15/camel-core/src/test/java/org/apache/camel/issues/OnExceptionNotHandledNoFailureProcessorTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/issues/OnExceptionNotHandledNoFailureProcessorTest.java b/camel-core/src/test/java/org/apache/camel/issues/OnExceptionNotHandledNoFailureProcessorTest.java
new file mode 100644
index 0000000..7c6d990
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/issues/OnExceptionNotHandledNoFailureProcessorTest.java
@@ -0,0 +1,61 @@
+/**
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ *
+ */
+public class OnExceptionNotHandledNoFailureProcessorTest extends ContextTestSupport {
+
+ public void testOnException() throws Exception {
+ getMockEndpoint("mock:end").expectedMessageCount(0);
+ getMockEndpoint("mock:error").expectedMessageCount(1);
+
+ template.sendBody("direct:start", "Hello World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ errorHandler(deadLetterChannel("mock:error"));
+
+ // NOT handle runtime exception, and let the regular error handler deal with it afterwards
+ // as its a DLC it will handle it then
+ onException(RuntimeException.class)
+ .handled(false);
+
+ from("direct:start").
+ process(new Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ throw new RuntimeException("FAIL!");
+ }
+ }).
+ to("mock:end");
+ }
+ };
+ }
+}
[10/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Posted by da...@apache.org.
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9461db29
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9461db29
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9461db29
Branch: refs/heads/master
Commit: 9461db295dfeb092ef50e193565d676160632e2b
Parents: 1a668e8
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 21:22:42 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 21:22:42 2015 +0100
----------------------------------------------------------------------
.../disruptor/DisruptorRemoveRouteThenAddAgainTest.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/9461db29/components/camel-disruptor/src/test/java/org/apache/camel/component/disruptor/DisruptorRemoveRouteThenAddAgainTest.java
----------------------------------------------------------------------
diff --git a/components/camel-disruptor/src/test/java/org/apache/camel/component/disruptor/DisruptorRemoveRouteThenAddAgainTest.java b/components/camel-disruptor/src/test/java/org/apache/camel/component/disruptor/DisruptorRemoveRouteThenAddAgainTest.java
index fc04262..5ef4181 100644
--- a/components/camel-disruptor/src/test/java/org/apache/camel/component/disruptor/DisruptorRemoveRouteThenAddAgainTest.java
+++ b/components/camel-disruptor/src/test/java/org/apache/camel/component/disruptor/DisruptorRemoveRouteThenAddAgainTest.java
@@ -27,7 +27,7 @@ import org.junit.Test;
public class DisruptorRemoveRouteThenAddAgainTest extends CamelTestSupport {
@Test
public void testRemoveRouteAndThenAddAgain() throws Exception {
- final MockEndpoint out = getMockEndpoint("mock:out");
+ MockEndpoint out = getMockEndpoint("mock:out");
out.expectedMessageCount(1);
out.expectedBodiesReceived("before removing the route");
@@ -35,8 +35,6 @@ public class DisruptorRemoveRouteThenAddAgainTest extends CamelTestSupport {
out.assertIsSatisfied();
- out.reset();
-
// now stop & remove the route
context.stopRoute("disruptorToMock");
context.removeRoute("disruptorToMock");
@@ -44,6 +42,8 @@ public class DisruptorRemoveRouteThenAddAgainTest extends CamelTestSupport {
// and then add it back again
context.addRoutes(createRouteBuilder());
+ // get mock endpoint again as we removed the route which removes the endpoint
+ out = getMockEndpoint("mock:out");
out.expectedMessageCount(1);
out.expectedBodiesReceived("after removing the route");
[04/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Posted by da...@apache.org.
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/42ded87e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/42ded87e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/42ded87e
Branch: refs/heads/master
Commit: 42ded87e1256b2aabdd0bd0ed5f2e87fcac766b1
Parents: 296c5af
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 14:44:32 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 14:44:32 2015 +0100
----------------------------------------------------------------------
.../builder/DefaultErrorHandlerBuilder.java | 9 +++
.../camel/processor/RedeliveryErrorHandler.java | 44 +++++++++------
.../DeadLetterChannelNewExceptionTest.java | 50 +++++++++++++++++
...dLetterChannelNotHandleNewExceptionTest.java | 58 ++++++++++++++++++++
.../src/test/resources/log4j.properties | 2 +-
5 files changed, 146 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/42ded87e/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
index 417728d..091c166 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
@@ -366,6 +366,15 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
return this;
}
+ /**
+ * @deprecated use {@link #deadLetterHandleNewException(boolean)}} with value <tt>false</tt>
+ */
+ @Deprecated
+ public DefaultErrorHandlerBuilder checkException() {
+ setDeadLetterHandleNewException(false);
+ return this;
+ }
+
// Properties
// -------------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/42ded87e/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
index c50c87c..8fdea29 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
@@ -890,7 +890,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
public void done(boolean sync) {
log.trace("Failure processor done: {} processing Exchange: {}", processor, exchange);
try {
- prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
+ prepareExchangeAfterFailure(processor, exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
// fire event as we had a failure processor to handle it, which there is a event for
boolean deadLetterChannel = processor == data.deadLetterProcessor;
EventHelper.notifyExchangeFailureHandled(exchange.getContext(), exchange, processor, deadLetterChannel);
@@ -904,7 +904,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
} else {
try {
// no processor but we need to prepare after failure as well
- prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
+ prepareExchangeAfterFailure(processor, exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
} finally {
// callback we are done
callback.done(data.sync);
@@ -924,19 +924,28 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
return sync;
}
- protected void prepareExchangeAfterFailure(final Exchange exchange, final RedeliveryData data,
+ protected void prepareExchangeAfterFailure(final Processor failureProcessor, final Exchange exchange, final RedeliveryData data,
final boolean isDeadLetterChannel, final boolean shouldHandle, final boolean shouldContinue) {
Exception newException = exchange.getException();
if (newException != null && data.currentRedeliveryPolicy.isLogNewException()) {
- logFailedDelivery(false, true, false, false, exchange, null, data, newException);
+ boolean handled = data.handleNewException;
+ String msg = "New exception occurred during processing by the failure processor " + failureProcessor + " due " + newException.getMessage();
+ if (handled) {
+ msg += ". The new exception is being handled as deadLetterHandleNewException=true.";
+ } else {
+ msg += ". The new exception is not handled as deadLetterHandleNewException=false.";
+ }
+ logFailedDelivery(false, true, handled, false, exchange, msg, data, newException);
}
// we could not process the exchange so we let the failure processor handled it
ExchangeHelper.setFailureHandled(exchange);
+ // special for dead letter channel where it by default handle new exceptions, but its possible to turn that off
if (isDeadLetterChannel && shouldHandle) {
- if (data.handleNewException) {
+ boolean handled = data.handleNewException;
+ if (handled) {
// if there is a new exception then log a warning about that
log.trace("This exchange is handled so its marked as not failed: {}", exchange);
} else {
@@ -984,7 +993,8 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
}
}
- private void logFailedDelivery(boolean shouldRedeliver, boolean newException, boolean handled, boolean continued, Exchange exchange, String message, RedeliveryData data, Throwable e) {
+ private void logFailedDelivery(boolean shouldRedeliver, boolean newException, boolean handled, boolean continued,
+ Exchange exchange, String message, RedeliveryData data, Throwable e) {
if (logger == null) {
return;
}
@@ -996,22 +1006,22 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
}
// if we should not rollback, then check whether logging is enabled
- if (handled && !data.currentRedeliveryPolicy.isLogHandled()) {
+ if (!newException && handled && !data.currentRedeliveryPolicy.isLogHandled()) {
// do not log handled
return;
}
- if (continued && !data.currentRedeliveryPolicy.isLogContinued()) {
+ if (!newException && continued && !data.currentRedeliveryPolicy.isLogContinued()) {
// do not log handled
return;
}
- if (shouldRedeliver && !data.currentRedeliveryPolicy.isLogRetryAttempted()) {
+ if (!newException && shouldRedeliver && !data.currentRedeliveryPolicy.isLogRetryAttempted()) {
// do not log retry attempts
return;
}
- if (!shouldRedeliver && !data.currentRedeliveryPolicy.isLogExhausted()) {
+ if (!newException && !shouldRedeliver && !data.currentRedeliveryPolicy.isLogExhausted()) {
// do not log exhausted
return;
}
@@ -1038,11 +1048,14 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
if (newLogLevel == LoggingLevel.ERROR) {
newLogLevel = LoggingLevel.WARN;
}
- // special for logging the new exception
- String msg = "New exception " + ExchangeHelper.logIds(exchange);
- Throwable cause = exchange.getException() != null ? exchange.getException() : exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
- if (cause != null) {
- msg = msg + " due: " + cause.getMessage();
+ String msg = message;
+ if (msg == null) {
+ msg = "New exception " + ExchangeHelper.logIds(exchange);
+ // special for logging the new exception
+ Throwable cause = e;
+ if (cause != null) {
+ msg = msg + " due: " + cause.getMessage();
+ }
}
if (e != null && logStackTrace) {
@@ -1057,7 +1070,6 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
msg = msg + " due: " + cause.getMessage();
}
-
// should we include message history
if (!shouldRedeliver && data.currentRedeliveryPolicy.isLogExhaustedMessageHistory()) {
String routeStackTrace = MessageHelper.dumpMessageHistoryStacktrace(exchange, exchangeFormatter, false);
http://git-wip-us.apache.org/repos/asf/camel/blob/42ded87e/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNewExceptionTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNewExceptionTest.java b/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNewExceptionTest.java
new file mode 100644
index 0000000..5b1b1c5
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNewExceptionTest.java
@@ -0,0 +1,50 @@
+/**
+ * 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 org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Handler;
+import org.apache.camel.builder.RouteBuilder;
+
+public class DeadLetterChannelNewExceptionTest extends ContextTestSupport {
+
+ public static class BadErrorHandler {
+ @Handler
+ public void onException(Exchange exchange, Exception exception) throws Exception {
+ throw new RuntimeException("error in errorhandler");
+ }
+ }
+
+ public void testDeadLetterChannelNewException() throws Exception {
+ template.sendBody("direct:start", "Hello World");
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ errorHandler(deadLetterChannel("bean:" + BadErrorHandler.class.getName()));
+
+ from("direct:start")
+ .log("Incoming ${body}")
+ .throwException(new IllegalArgumentException("Forced"));
+ }
+ };
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/42ded87e/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java b/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java
new file mode 100644
index 0000000..df4ed94
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java
@@ -0,0 +1,58 @@
+/**
+ * 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 org.apache.camel.CamelExecutionException;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Handler;
+import org.apache.camel.builder.RouteBuilder;
+
+public class DeadLetterChannelNotHandleNewExceptionTest extends ContextTestSupport {
+
+ public static class BadErrorHandler {
+ @Handler
+ public void onException(Exchange exchange, Exception exception) throws Exception {
+ throw new RuntimeException("error in errorhandler");
+ }
+ }
+
+ public void testDeadLetterChannelNewException() throws Exception {
+ try {
+ template.sendBody("direct:start", "Hello World");
+ fail("Should have thrown exception");
+ } catch (CamelExecutionException e) {
+ RuntimeException cause = assertIsInstanceOf(RuntimeException.class, e.getCause());
+ assertEquals("error in errorhandler", cause.getMessage());
+ }
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ errorHandler(deadLetterChannel("bean:" + BadErrorHandler.class.getName())
+ .deadLetterHandleNewException(false));
+
+ from("direct:start")
+ .log("Incoming ${body}")
+ .throwException(new IllegalArgumentException("Forced"));
+ }
+ };
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/42ded87e/components/camel-jms/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/resources/log4j.properties b/components/camel-jms/src/test/resources/log4j.properties
index 14beeb0..4732904 100644
--- a/components/camel-jms/src/test/resources/log4j.properties
+++ b/components/camel-jms/src/test/resources/log4j.properties
@@ -18,7 +18,7 @@
#
# The logging properties used
#
-log4j.rootLogger=INFO, stdout
+log4j.rootLogger=INFO, out
#log4j.logger.org.apache.activemq.spring=WARN
#log4j.logger.org.apache.camel.component.jms=DEBUG
[07/10] camel git commit: CAMEL-8256: Include deadLetterUri in
ExchangeFailureHandledEvent
Posted by da...@apache.org.
CAMEL-8256: Include deadLetterUri in ExchangeFailureHandledEvent
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/37d4914e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/37d4914e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/37d4914e
Branch: refs/heads/master
Commit: 37d4914eab4ba9e0bbcde98bba53c1a87e34245b
Parents: 77851e1
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 16:40:37 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 16:40:37 2015 +0100
----------------------------------------------------------------------
.../management/event/DefaultEventFactory.java | 5 +++--
.../event/ExchangeFailureHandledEvent.java | 18 +++++++++++++-----
.../camel/processor/RedeliveryErrorHandler.java | 2 +-
.../java/org/apache/camel/spi/EventFactory.java | 4 +++-
.../java/org/apache/camel/util/EventHelper.java | 4 ++--
.../EventNotifierFailureHandledEventsTest.java | 1 +
6 files changed, 23 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/37d4914e/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java b/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java
index c018b11..0f78475 100644
--- a/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java
+++ b/camel-core/src/main/java/org/apache/camel/management/event/DefaultEventFactory.java
@@ -93,13 +93,14 @@ public class DefaultEventFactory implements EventFactory {
return new ExchangeFailedEvent(exchange);
}
- public EventObject createExchangeFailureHandledEvent(Exchange exchange, Processor failureHandler, boolean deadLetterChannel) {
+ public EventObject createExchangeFailureHandledEvent(Exchange exchange, Processor failureHandler,
+ boolean deadLetterChannel, String deadLetterUri) {
// unwrap delegate processor
Processor handler = failureHandler;
if (handler instanceof DelegateProcessor) {
handler = ((DelegateProcessor) handler).getProcessor();
}
- return new ExchangeFailureHandledEvent(exchange, handler, deadLetterChannel);
+ return new ExchangeFailureHandledEvent(exchange, handler, deadLetterChannel, deadLetterUri);
}
public EventObject createExchangeRedeliveryEvent(Exchange exchange, int attempt) {
http://git-wip-us.apache.org/repos/asf/camel/blob/37d4914e/camel-core/src/main/java/org/apache/camel/management/event/ExchangeFailureHandledEvent.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/event/ExchangeFailureHandledEvent.java b/camel-core/src/main/java/org/apache/camel/management/event/ExchangeFailureHandledEvent.java
index 0f799c9..2c0dd7d 100644
--- a/camel-core/src/main/java/org/apache/camel/management/event/ExchangeFailureHandledEvent.java
+++ b/camel-core/src/main/java/org/apache/camel/management/event/ExchangeFailureHandledEvent.java
@@ -18,21 +18,24 @@ package org.apache.camel.management.event;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
+import org.apache.camel.util.URISupport;
/**
* @version
*/
public class ExchangeFailureHandledEvent extends AbstractExchangeEvent {
- private static final long serialVersionUID = -7554809462006009547L;
+ private static final long serialVersionUID = -7554809462006009548L;
- private final Processor failureHandler;
+ private final transient Processor failureHandler;
private final boolean deadLetterChannel;
+ private final String deadLetterUri;
private final boolean handled;
- public ExchangeFailureHandledEvent(Exchange source, Processor failureHandler, boolean deadLetterChannel) {
+ public ExchangeFailureHandledEvent(Exchange source, Processor failureHandler, boolean deadLetterChannel, String deadLetterUri) {
super(source);
this.failureHandler = failureHandler;
this.deadLetterChannel = deadLetterChannel;
+ this.deadLetterUri = deadLetterUri;
this.handled = source.getProperty(Exchange.ERRORHANDLER_HANDLED, false, Boolean.class);
}
@@ -44,6 +47,10 @@ public class ExchangeFailureHandledEvent extends AbstractExchangeEvent {
return deadLetterChannel;
}
+ public String getDeadLetterUri() {
+ return deadLetterUri;
+ }
+
public boolean isHandled() {
return handled;
}
@@ -51,9 +58,10 @@ public class ExchangeFailureHandledEvent extends AbstractExchangeEvent {
@Override
public String toString() {
if (isDeadLetterChannel()) {
- return getExchange().getExchangeId() + " exchange failed: " + getExchange() + " but was handled by dead letter channel: " + failureHandler;
+ String uri = URISupport.sanitizeUri(deadLetterUri);
+ return getExchange().getExchangeId() + " exchange failed: " + getExchange() + " but was handled by dead letter channel: " + uri;
} else {
- return getExchange().getExchangeId() + " exchange failed: " + getExchange() + " but was processed by: " + failureHandler;
+ return getExchange().getExchangeId() + " exchange failed: " + getExchange() + " but was processed by failure processor: " + failureHandler;
}
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/37d4914e/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
index dbe3760..9fcfc0f 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
@@ -896,7 +896,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
// fire event as we had a failure processor to handle it, which there is a event for
boolean deadLetterChannel = processor == data.deadLetterProcessor;
- EventHelper.notifyExchangeFailureHandled(exchange.getContext(), exchange, processor, deadLetterChannel);
+ EventHelper.notifyExchangeFailureHandled(exchange.getContext(), exchange, processor, deadLetterChannel, deadLetterUri);
} finally {
// if the fault was handled asynchronously, this should be reflected in the callback as well
data.sync &= sync;
http://git-wip-us.apache.org/repos/asf/camel/blob/37d4914e/camel-core/src/main/java/org/apache/camel/spi/EventFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/EventFactory.java b/camel-core/src/main/java/org/apache/camel/spi/EventFactory.java
index feeb9d1..25c9578 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/EventFactory.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/EventFactory.java
@@ -166,9 +166,11 @@ public interface EventFactory {
* @param exchange the exchange
* @param failureHandler the failure handler such as moving the message to a dead letter queue
* @param deadLetterChannel whether it was a dead letter channel or not handling the failure
+ * @param deadLetterUri the dead letter uri, if its a dead letter channel
* @return the created event
*/
- EventObject createExchangeFailureHandledEvent(Exchange exchange, Processor failureHandler, boolean deadLetterChannel);
+ EventObject createExchangeFailureHandledEvent(Exchange exchange, Processor failureHandler,
+ boolean deadLetterChannel, String deadLetterUri);
/**
* Creates an {@link EventObject} when an {@link org.apache.camel.Exchange} is about to be redelivered
http://git-wip-us.apache.org/repos/asf/camel/blob/37d4914e/camel-core/src/main/java/org/apache/camel/util/EventHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/EventHelper.java b/camel-core/src/main/java/org/apache/camel/util/EventHelper.java
index f80983a..cabe364 100644
--- a/camel-core/src/main/java/org/apache/camel/util/EventHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/EventHelper.java
@@ -479,7 +479,7 @@ public final class EventHelper {
}
public static void notifyExchangeFailureHandled(CamelContext context, Exchange exchange, Processor failureHandler,
- boolean deadLetterChannel) {
+ boolean deadLetterChannel, String deadLetterUri) {
if (exchange.getProperty(Exchange.NOTIFY_EVENT, false, Boolean.class)) {
// do not generate events for an notify event
return;
@@ -504,7 +504,7 @@ public final class EventHelper {
if (factory == null) {
return;
}
- EventObject event = factory.createExchangeFailureHandledEvent(exchange, failureHandler, deadLetterChannel);
+ EventObject event = factory.createExchangeFailureHandledEvent(exchange, failureHandler, deadLetterChannel, deadLetterUri);
if (event == null) {
return;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/37d4914e/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java b/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java
index 5888018..f7db679 100644
--- a/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java
@@ -106,6 +106,7 @@ public class EventNotifierFailureHandledEventsTest extends ContextTestSupport {
assertEquals("should be DLC", true, e.isDeadLetterChannel());
SendProcessor send = assertIsInstanceOf(SendProcessor.class, e.getFailureHandler());
assertEquals("mock://dead", send.getDestination().getEndpointUri());
+ assertEquals("mock://dead", e.getDeadLetterUri());
// dead letter channel will mark the exchange as completed
assertIsInstanceOf(ExchangeCompletedEvent.class, events.get(9));
[08/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Posted by da...@apache.org.
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/fb120dfa
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/fb120dfa
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/fb120dfa
Branch: refs/heads/master
Commit: fb120dfab276f6719ccc64c9741ccb064514ed25
Parents: 37d4914
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 17:18:27 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 17:18:27 2015 +0100
----------------------------------------------------------------------
...dLetterChannelNotHandleNewExceptionTest.java | 2 +-
.../spring/spi/TransactionErrorHandler.java | 2 +-
...SpringDeadLetterChannelNewExceptionTest.java | 29 +++++++++++++
...dLetterChannelNotHandleNewExceptionTest.java | 29 +++++++++++++
.../DeadLetterChannelNewExceptionTest.xml | 43 ++++++++++++++++++++
...adLetterChannelNotHandleNewExceptionTest.xml | 43 ++++++++++++++++++++
6 files changed, 146 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/fb120dfa/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java b/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java
index df4ed94..1cbf20d 100644
--- a/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java
+++ b/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelNotHandleNewExceptionTest.java
@@ -31,7 +31,7 @@ public class DeadLetterChannelNotHandleNewExceptionTest extends ContextTestSuppo
}
}
- public void testDeadLetterChannelNewException() throws Exception {
+ public void testDeadLetterChannelNotHandleNewException() throws Exception {
try {
template.sendBody("direct:start", "Hello World");
fail("Should have thrown exception");
http://git-wip-us.apache.org/repos/asf/camel/blob/fb120dfa/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandler.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandler.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandler.java
index fba08af..a27a73f 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandler.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandler.java
@@ -67,7 +67,7 @@ public class TransactionErrorHandler extends RedeliveryErrorHandler {
TransactionTemplate transactionTemplate, Predicate retryWhile, ScheduledExecutorService executorService,
LoggingLevel rollbackLoggingLevel) {
- super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, false, retryWhile, executorService);
+ super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, false, false, retryWhile, executorService);
setExceptionPolicy(exceptionPolicyStrategy);
this.transactionTemplate = transactionTemplate;
this.rollbackLoggingLevel = rollbackLoggingLevel;
http://git-wip-us.apache.org/repos/asf/camel/blob/fb120dfa/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringDeadLetterChannelNewExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringDeadLetterChannelNewExceptionTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringDeadLetterChannelNewExceptionTest.java
new file mode 100644
index 0000000..0c69554
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringDeadLetterChannelNewExceptionTest.java
@@ -0,0 +1,29 @@
+/**
+ * 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.spring.processor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.processor.DeadLetterChannelNewExceptionTest;
+
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+public class SpringDeadLetterChannelNewExceptionTest extends DeadLetterChannelNewExceptionTest {
+
+ protected CamelContext createCamelContext() throws Exception {
+ return createSpringCamelContext(this, "org/apache/camel/spring/processor/DeadLetterChannelNewExceptionTest.xml");
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/fb120dfa/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringDeadLetterChannelNotHandleNewExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringDeadLetterChannelNotHandleNewExceptionTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringDeadLetterChannelNotHandleNewExceptionTest.java
new file mode 100644
index 0000000..7293edf
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringDeadLetterChannelNotHandleNewExceptionTest.java
@@ -0,0 +1,29 @@
+/**
+ * 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.spring.processor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.processor.DeadLetterChannelNotHandleNewExceptionTest;
+
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+public class SpringDeadLetterChannelNotHandleNewExceptionTest extends DeadLetterChannelNotHandleNewExceptionTest {
+
+ protected CamelContext createCamelContext() throws Exception {
+ return createSpringCamelContext(this, "org/apache/camel/spring/processor/DeadLetterChannelNotHandleNewExceptionTest.xml");
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/fb120dfa/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/DeadLetterChannelNewExceptionTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/DeadLetterChannelNewExceptionTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/DeadLetterChannelNewExceptionTest.xml
new file mode 100644
index 0000000..91ebbd6
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/DeadLetterChannelNewExceptionTest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <bean id="forced" class="java.lang.IllegalArgumentException">
+ <constructor-arg index="0" value="Forced"/>
+ </bean>
+
+ <bean id="badErrorHandler"
+ class="org.apache.camel.processor.DeadLetterChannelNotHandleNewExceptionTest.BadErrorHandler"/>
+
+ <camelContext xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="dlc">
+
+ <errorHandler id="dlc" type="DeadLetterChannel" deadLetterUri="bean:badErrorHandler" deadLetterHandleNewException="true"/>
+
+ <route>
+ <from uri="direct:start"/>
+ <log message="Incoming ${body}"/>
+ <throwException ref="forced"/>
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/fb120dfa/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/DeadLetterChannelNotHandleNewExceptionTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/DeadLetterChannelNotHandleNewExceptionTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/DeadLetterChannelNotHandleNewExceptionTest.xml
new file mode 100644
index 0000000..0c3f6b2
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/DeadLetterChannelNotHandleNewExceptionTest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <bean id="forced" class="java.lang.IllegalArgumentException">
+ <constructor-arg index="0" value="Forced"/>
+ </bean>
+
+ <bean id="badErrorHandler"
+ class="org.apache.camel.processor.DeadLetterChannelNotHandleNewExceptionTest.BadErrorHandler"/>
+
+ <camelContext xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="dlc">
+
+ <errorHandler id="dlc" type="DeadLetterChannel" deadLetterUri="bean:badErrorHandler" deadLetterHandleNewException="false"/>
+
+ <route>
+ <from uri="direct:start"/>
+ <log message="Incoming ${body}"/>
+ <throwException ref="forced"/>
+ </route>
+ </camelContext>
+
+</beans>
[03/10] camel git commit: CAMEL-7050: DeadLetterChannel should make
more clear that it handles any new exception also. Added option to configure
this behavior so ppl can turn that off and let new exceptions be unhandled,
so transactions can rollback.
Posted by da...@apache.org.
CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/296c5af2
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/296c5af2
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/296c5af2
Branch: refs/heads/master
Commit: 296c5af2eaffef9d7bc6a39dd0dd7e226ca05b09
Parents: 27136c3
Author: Claus Ibsen <da...@apache.org>
Authored: Sun Jan 18 14:19:28 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Jan 18 14:19:28 2015 +0100
----------------------------------------------------------------------
.../builder/DefaultErrorHandlerBuilder.java | 5 +++++
.../camel/processor/RedeliveryErrorHandler.java | 19 +++++++++++++++----
...terChannelHandlerRollbackOnExceptionTest.java | 3 ++-
3 files changed, 22 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/296c5af2/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
index d57f110..417728d 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
@@ -191,6 +191,11 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
return this;
}
+ public DefaultErrorHandlerBuilder logNewException(boolean logNewException) {
+ getRedeliveryPolicy().setLogNewException(logNewException);
+ return this;
+ }
+
public DefaultErrorHandlerBuilder logExhausted(boolean logExhausted) {
getRedeliveryPolicy().setLogExhausted(logExhausted);
return this;
http://git-wip-us.apache.org/repos/asf/camel/blob/296c5af2/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
index 9120221..c50c87c 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
@@ -928,6 +928,9 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
final boolean isDeadLetterChannel, final boolean shouldHandle, final boolean shouldContinue) {
Exception newException = exchange.getException();
+ if (newException != null && data.currentRedeliveryPolicy.isLogNewException()) {
+ logFailedDelivery(false, true, false, false, exchange, null, data, newException);
+ }
// we could not process the exchange so we let the failure processor handled it
ExchangeHelper.setFailureHandled(exchange);
@@ -935,9 +938,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
if (isDeadLetterChannel && shouldHandle) {
if (data.handleNewException) {
// if there is a new exception then log a warning about that
- String msg = "DeadLetterChannel failed processing exchange due new exception: " + newException.getMessage()
- + ". This new exception is handled and ignored. The option deadLetterChannelHandleNewException can be turned off to not handle new exceptions";
- logFailedDelivery(false, true, false, false, exchange, msg, data, newException);
+ log.trace("This exchange is handled so its marked as not failed: {}", exchange);
} else {
// exception not handled, put exception back in the exchange
exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
@@ -1033,8 +1034,17 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
}
if (newException) {
+ // log at most WARN level
+ if (newLogLevel == LoggingLevel.ERROR) {
+ newLogLevel = LoggingLevel.WARN;
+ }
// special for logging the new exception
- String msg = message + " " + ExchangeHelper.logIds(exchange);
+ String msg = "New exception " + ExchangeHelper.logIds(exchange);
+ Throwable cause = exchange.getException() != null ? exchange.getException() : exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
+ if (cause != null) {
+ msg = msg + " due: " + cause.getMessage();
+ }
+
if (e != null && logStackTrace) {
logger.log(msg, e, newLogLevel);
} else {
@@ -1047,6 +1057,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
msg = msg + " due: " + cause.getMessage();
}
+
// should we include message history
if (!shouldRedeliver && data.currentRedeliveryPolicy.isLogExhaustedMessageHistory()) {
String routeStackTrace = MessageHelper.dumpMessageHistoryStacktrace(exchange, exchangeFormatter, false);
http://git-wip-us.apache.org/repos/asf/camel/blob/296c5af2/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
index 9052144..7dd8382 100644
--- a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
@@ -52,7 +52,8 @@ public class JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest extend
// we use DLC to handle the exception but if it throw a new exception
// then the DLC handles that too (the transaction will always commit)
errorHandler(deadLetterChannel("bean:" + BadErrorHandler.class.getName())
- .deadLetterHandleNewException(isHandleNew()));
+ .deadLetterHandleNewException(isHandleNew())
+ .logNewException(true));
from(testingEndpoint)
.log("Incoming JMS message ${body}")