camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject [1/2] camel git commit: CAMEL-9069: Added onExceptionOuccrredProcessor to error handler to allow a processor to be invoked right after an exception was thrown.
Date Sun, 31 Jan 2016 09:45:46 GMT
Repository: camel
Updated Branches:
  refs/heads/master 9f66481e0 -> 391e34f7b


CAMEL-9069: Added onExceptionOuccrredProcessor to error handler to allow a processor to be invoked right after an exception was thrown.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/44e85561
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/44e85561
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/44e85561

Branch: refs/heads/master
Commit: 44e85561fea98dc0ead00a033541fadf944d8620
Parents: 9f66481
Author: Claus Ibsen <davsclaus@apache.org>
Authored: Sun Jan 31 10:31:11 2016 +0100
Committer: Claus Ibsen <davsclaus@apache.org>
Committed: Sun Jan 31 10:31:11 2016 +0100

----------------------------------------------------------------------
 .../camel/builder/DeadLetterChannelBuilder.java |  3 +-
 .../builder/DefaultErrorHandlerBuilder.java     | 31 +++++++-
 .../camel/model/OnExceptionDefinition.java      | 57 ++++++++++++++-
 .../camel/processor/DeadLetterChannel.java      | 33 +++++----
 .../camel/processor/DefaultErrorHandler.java    | 35 ++++-----
 .../camel/processor/LoggingErrorHandler.java    |  2 +-
 .../camel/processor/RedeliveryErrorHandler.java | 59 +++++++++++----
 ...ceptionOccurredProcessorOnExceptionTest.java | 77 ++++++++++++++++++++
 .../OnExceptionOccurredProcessorTest.java       | 75 +++++++++++++++++++
 .../blueprint/CamelErrorHandlerFactoryBean.java |  5 ++
 .../camel/spring/ErrorHandlerDefinition.java    |  2 +
 .../handler/ErrorHandlerDefinitionParser.java   |  7 ++
 .../spring/spi/TransactionErrorHandler.java     |  6 +-
 .../spi/TransactionErrorHandlerBuilder.java     |  2 +-
 ...ceptionOccurredProcessorOnExceptionTest.java | 33 +++++++++
 .../SpringOnExceptionOccurredProcessorTest.java | 33 +++++++++
 ...xceptionOccurredProcessorOnExceptionTest.xml | 47 ++++++++++++
 .../OnExceptionOccurredProcessorTest.xml        | 44 +++++++++++
 ...ceptionOccurredProcessorOnExceptionTest.java | 57 +++++++++++++++
 .../OnExceptionOccurredProcessorTest.java       | 57 +++++++++++++++
 ...xceptionOccurredProcessorOnExceptionTest.xml | 46 ++++++++++++
 .../OnExceptionOccurredProcessorTest.xml        | 43 +++++++++++
 22 files changed, 701 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 646ed2d..1acd0a8 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
@@ -55,7 +55,8 @@ public class DeadLetterChannelBuilder extends DefaultErrorHandlerBuilder {
 
         DeadLetterChannel answer = new DeadLetterChannel(routeContext.getCamelContext(), processor, getLogger(), getOnRedelivery(), 
                 getRedeliveryPolicy(), getExceptionPolicyStrategy(), getFailureProcessor(), getDeadLetterUri(), isDeadLetterHandleNewException(),
-                isUseOriginalMessage(), getRetryWhilePolicy(routeContext.getCamelContext()), getExecutorService(routeContext.getCamelContext()), getOnPrepareFailure());
+                isUseOriginalMessage(), getRetryWhilePolicy(routeContext.getCamelContext()), getExecutorService(routeContext.getCamelContext()),
+                getOnPrepareFailure(), getOnExceptionOccurred());
         // configure error handler before we can use it
         configure(routeContext, answer);
         return answer;

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 b565bfe..674efae 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
@@ -55,6 +55,7 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
     protected String executorServiceRef;
     protected ScheduledExecutorService executorService;
     protected Processor onPrepareFailure;
+    protected Processor onExceptionOccurred;
 
     public DefaultErrorHandlerBuilder() {
     }
@@ -62,7 +63,7 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
     public Processor createErrorHandler(RouteContext routeContext, Processor processor) throws Exception {
         DefaultErrorHandler answer = new DefaultErrorHandler(routeContext.getCamelContext(), processor, getLogger(), getOnRedelivery(), 
             getRedeliveryPolicy(), getExceptionPolicyStrategy(), getRetryWhilePolicy(routeContext.getCamelContext()),
-                getExecutorService(routeContext.getCamelContext()), getOnPrepareFailure());
+                getExecutorService(routeContext.getCamelContext()), getOnPrepareFailure(), getOnExceptionOccurred());
         // configure error handler before we can use it
         configure(routeContext, answer);
         return answer;
@@ -106,6 +107,12 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
         if (deadLetterUri != null) {
             other.setDeadLetterUri(deadLetterUri);
         }
+        if (onPrepareFailure != null) {
+            other.setOnPrepareFailure(onPrepareFailure);
+        }
+        if (onExceptionOccurred != null) {
+            other.setOnExceptionOccurred(onExceptionOccurred);
+        }
         other.setDeadLetterHandleNewException(deadLetterHandleNewException);
         other.setUseOriginalMessage(useOriginalMessage);
         other.setAsyncDelayedRedelivery(asyncDelayedRedelivery);
@@ -395,6 +402,20 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
         return this;
     }
 
+    /**
+     * Sets a custom {@link org.apache.camel.Processor} to process the {@link org.apache.camel.Exchange} just after an exception was thrown.
+     * This allows to execute the processor at the same time the exception was thrown.
+     * <p/>
+     * Important: Any exception thrown from this processor will be ignored.
+     *
+     * @param processor the processor
+     * @return the builder
+     */
+    public DefaultErrorHandlerBuilder onExceptionOccurred(Processor processor) {
+        setOnExceptionOccurred(processor);
+        return this;
+    }
+
     // Properties
     // -------------------------------------------------------------------------
 
@@ -525,6 +546,14 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
         this.onPrepareFailure = onPrepareFailure;
     }
 
+    public Processor getOnExceptionOccurred() {
+        return onExceptionOccurred;
+    }
+
+    public void setOnExceptionOccurred(Processor onExceptionOccurred) {
+        this.onExceptionOccurred = onExceptionOccurred;
+    }
+
     protected RedeliveryPolicy createRedeliveryPolicy() {
         RedeliveryPolicy policy = new RedeliveryPolicy();
         policy.disableRedelivery();

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 9070ae0..f7c06c5 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
@@ -72,6 +72,8 @@ public class OnExceptionDefinition extends ProcessorDefinition<OnExceptionDefini
     private ExpressionSubElementDefinition continued;
     @XmlAttribute(name = "onRedeliveryRef")
     private String onRedeliveryRef;
+    @XmlAttribute(name = "onExceptionOccurredRef")
+    private String onExceptionbOccurredRef;
     @XmlAttribute(name = "useOriginalMessage")
     private Boolean useOriginalMessagePolicy;
     @XmlElementRef
@@ -87,6 +89,8 @@ public class OnExceptionDefinition extends ProcessorDefinition<OnExceptionDefini
     @XmlTransient
     private Processor onRedelivery;
     @XmlTransient
+    private Processor onExceptionOccurred;
+    @XmlTransient
     private Boolean routeScoped;
     // TODO: in Camel 3.0 the OnExceptionDefinition should not contain state and ErrorHandler processors
     @XmlTransient
@@ -180,6 +184,7 @@ public class OnExceptionDefinition extends ProcessorDefinition<OnExceptionDefini
         setContinuedFromExpressionType(routeContext);
         setRetryWhileFromExpressionType(routeContext);
         setOnRedeliveryFromRedeliveryRef(routeContext);
+        setOnExceptionOccurredFromOnExceptionOccurredRef(routeContext);
 
         // load exception classes
         if (exceptions != null && !exceptions.isEmpty()) {
@@ -247,7 +252,8 @@ public class OnExceptionDefinition extends ProcessorDefinition<OnExceptionDefini
         if (outputs == null || getOutputs().isEmpty()) {
             // no outputs so there should be some sort of configuration
             if (handledPolicy == null && continuedPolicy == null && retryWhilePolicy == null
-                    && redeliveryPolicyType == null && useOriginalMessagePolicy == null && onRedelivery == null) {
+                    && redeliveryPolicyType == null && useOriginalMessagePolicy == null
+                    && onRedelivery == null && onExceptionOccurred == null) {
                 throw new IllegalArgumentException(this + " is not configured.");
             }
         }
@@ -800,6 +806,30 @@ public class OnExceptionDefinition extends ProcessorDefinition<OnExceptionDefini
         return this;
     }
 
+    /**
+     * Sets a processor that should be processed <b>just after</b> an exception occurred.
+     * Can be used to perform custom logging about the occurred exception at the exact time it happened.
+     * <p/>
+     * Important: Any exception thrown from this processor will be ignored.
+     */
+    public OnExceptionDefinition onExceptionOccurred(Processor processor) {
+        setOnExceptionOccurred(processor);
+        return this;
+    }
+
+    /**
+     * Sets a reference to a processor that should be processed <b>just after</b> an exception occurred.
+     * Can be used to perform custom logging about the occurred exception at the exact time it happened.
+     * <p/>
+     * Important: Any exception thrown from this processor will be ignored.
+     *
+     * @param ref  reference to the processor
+     */
+    public OnExceptionDefinition onExceptionOccurredRef(String ref) {
+        setOnExceptionbOccurredRef(ref);
+        return this;
+    }
+
     // Properties
     //-------------------------------------------------------------------------
     @Override
@@ -938,6 +968,22 @@ public class OnExceptionDefinition extends ProcessorDefinition<OnExceptionDefini
         this.onRedeliveryRef = onRedeliveryRef;
     }
 
+    public Processor getOnExceptionOccurred() {
+        return onExceptionOccurred;
+    }
+
+    public void setOnExceptionOccurred(Processor onExceptionOccurred) {
+        this.onExceptionOccurred = onExceptionOccurred;
+    }
+
+    public String getOnExceptionbOccurredRef() {
+        return onExceptionbOccurredRef;
+    }
+
+    public void setOnExceptionbOccurredRef(String onExceptionbOccurredRef) {
+        this.onExceptionbOccurredRef = onExceptionbOccurredRef;
+    }
+
     public Boolean getUseOriginalMessagePolicy() {
         return useOriginalMessagePolicy;
     }
@@ -1000,4 +1046,13 @@ public class OnExceptionDefinition extends ProcessorDefinition<OnExceptionDefini
         }
     }
 
+    private void setOnExceptionOccurredFromOnExceptionOccurredRef(RouteContext routeContext) {
+        // lookup onRedelivery if ref is provided
+        if (ObjectHelper.isNotEmpty(onExceptionbOccurredRef)) {
+            // if ref is provided then use mandatory lookup to fail if not found
+            Processor onExceptionOccurred = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), onExceptionbOccurredRef, Processor.class);
+            setOnExceptionOccurred(onExceptionOccurred);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 cc92859..d6e44b6 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
@@ -38,27 +38,28 @@ public class DeadLetterChannel extends RedeliveryErrorHandler {
     /**
      * Creates the dead letter channel.
      *
-     * @param camelContext              the camel context
-     * @param output                    outer processor that should use this dead letter channel
-     * @param logger                    logger to use for logging failures and redelivery attempts
-     * @param redeliveryProcessor       an optional processor to run before redelivery attempt
-     * @param redeliveryPolicy          policy for redelivery
-     * @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>.
-     * @param onPrepare                 a custom {@link org.apache.camel.Processor} to prepare the {@link org.apache.camel.Exchange} before
-     *                                  handled by the failure processor / dead letter channel.
+     * @param camelContext                  the camel context
+     * @param output                        outer processor that should use this dead letter channel
+     * @param logger                        logger to use for logging failures and redelivery attempts
+     * @param redeliveryProcessor           an optional processor to run before redelivery attempt
+     * @param redeliveryPolicy              policy for redelivery
+     * @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>.
+     * @param onPrepareProcessor            a custom {@link org.apache.camel.Processor} to prepare the {@link org.apache.camel.Exchange} before
+     *                                      handled by the failure processor / dead letter channel.
+     * @param onExceptionOccurredProcessor  a custom {@link org.apache.camel.Processor} to process the {@link org.apache.camel.Exchange} just after an exception was thrown.
      */
     public DeadLetterChannel(CamelContext camelContext, Processor output, CamelLogger logger, Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy,
             ExceptionPolicyStrategy exceptionPolicyStrategy, Processor deadLetter, String deadLetterUri, boolean deadLetterHandleException,
-            boolean useOriginalBodyPolicy, Predicate retryWhile, ScheduledExecutorService executorService, Processor onPrepare) {
+            boolean useOriginalBodyPolicy, Predicate retryWhile, ScheduledExecutorService executorService, Processor onPrepareProcessor, Processor onExceptionOccurredProcessor) {
 
         super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, deadLetter, deadLetterUri, deadLetterHandleException,
-                useOriginalBodyPolicy, retryWhile, executorService, onPrepare);
+                useOriginalBodyPolicy, retryWhile, executorService, onPrepareProcessor, onExceptionOccurredProcessor);
         setExceptionPolicy(exceptionPolicyStrategy);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 697db20..a8fa1e9 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
@@ -5,9 +5,9 @@
  * 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
  * 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.
@@ -28,29 +28,30 @@ import org.apache.camel.util.CamelLogger;
 /**
  * Default error handler
  *
- * @version 
+ * @version
  */
 public class DefaultErrorHandler extends RedeliveryErrorHandler {
 
     /**
      * Creates the default error handler.
      *
-     * @param camelContext              the camel context
-     * @param output                    outer processor that should use this default error handler
-     * @param logger                    logger to use for logging failures and redelivery attempts
-     * @param redeliveryProcessor       an optional processor to run before redelivery attempt
-     * @param redeliveryPolicy          policy for redelivery
-     * @param exceptionPolicyStrategy   strategy for onException handling
-     * @param retryWhile                retry while
-     * @param executorService           the {@link java.util.concurrent.ScheduledExecutorService} to be used for redelivery thread pool. Can be <tt>null</tt>.
-     * @param onPrepare                 a custom {@link org.apache.camel.Processor} to prepare the {@link org.apache.camel.Exchange} before
-     *                                  handled by the failure processor / dead letter channel.
+     * @param camelContext                 the camel context
+     * @param output                       outer processor that should use this default error handler
+     * @param logger                       logger to use for logging failures and redelivery attempts
+     * @param redeliveryProcessor           an optional processor to run before redelivery attempt
+     * @param redeliveryPolicy              policy for redelivery
+     * @param exceptionPolicyStrategy       strategy for onException handling
+     * @param retryWhile                    retry while
+     * @param executorService               the {@link java.util.concurrent.ScheduledExecutorService} to be used for redelivery thread pool. Can be <tt>null</tt>.
+     * @param onPrepareProcessor            a custom {@link org.apache.camel.Processor} to prepare the {@link org.apache.camel.Exchange} before
+     *                                      handled by the failure processor / dead letter channel.
+     * @param onExceptionOccurredProcessor  a custom {@link org.apache.camel.Processor} to process the {@link org.apache.camel.Exchange} just after an exception was thrown.
      */
     public DefaultErrorHandler(CamelContext camelContext, Processor output, CamelLogger logger, Processor redeliveryProcessor,
-            RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy exceptionPolicyStrategy, Predicate retryWhile,
-            ScheduledExecutorService executorService, Processor onPrepare) {
+                               RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy exceptionPolicyStrategy, Predicate retryWhile,
+                               ScheduledExecutorService executorService, Processor onPrepareProcessor, Processor onExceptionOccurredProcessor) {
 
-        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, true, false, retryWhile, executorService, onPrepare);
+        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, true, false, retryWhile, executorService, onPrepareProcessor, onExceptionOccurredProcessor);
         setExceptionPolicy(exceptionPolicyStrategy);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/camel-core/src/main/java/org/apache/camel/processor/LoggingErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/LoggingErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/LoggingErrorHandler.java
index 1f66275..218da95 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/LoggingErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/LoggingErrorHandler.java
@@ -39,7 +39,7 @@ public class LoggingErrorHandler extends DefaultErrorHandler {
      */
     public LoggingErrorHandler(CamelContext camelContext, Processor output, CamelLogger logger,
                                RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy exceptionPolicyStrategy) {
-        super(camelContext, output, logger, null, redeliveryPolicy, exceptionPolicyStrategy, null, null, null);
+        super(camelContext, output, logger, null, redeliveryPolicy, exceptionPolicyStrategy, null, null, null, null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 8c9a838..9491f3a 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
@@ -78,7 +78,8 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
     protected volatile boolean preparingShutdown;
     protected final ExchangeFormatter exchangeFormatter;
     protected final boolean customExchangeFormatter;
-    protected final Processor onPrepare;
+    protected final Processor onPrepareProcessor;
+    protected final Processor onExceptionProcessor;
 
     /**
      * Contains the current redelivery data
@@ -97,6 +98,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         Processor failureProcessor;
         Processor onRedeliveryProcessor;
         Processor onPrepareProcessor;
+        Processor onExceptionProcessor;
         Predicate handledPredicate;
         Predicate continuedPredicate;
         boolean useOriginalInMessage;
@@ -108,7 +110,8 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
             this.currentRedeliveryPolicy = redeliveryPolicy;
             this.deadLetterProcessor = deadLetter;
             this.onRedeliveryProcessor = redeliveryProcessor;
-            this.onPrepareProcessor = onPrepare;
+            this.onPrepareProcessor = RedeliveryErrorHandler.this.onPrepareProcessor;
+            this.onExceptionProcessor = RedeliveryErrorHandler.this.onExceptionProcessor;
             this.handledPredicate = getDefaultHandledPredicate();
             this.useOriginalInMessage = useOriginalMessagePolicy;
             this.handleNewException = deadLetterHandleNewException;
@@ -202,9 +205,9 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
     }
 
     public RedeliveryErrorHandler(CamelContext camelContext, Processor output, CamelLogger logger,
-            Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy, Processor deadLetter,
-            String deadLetterUri, boolean deadLetterHandleNewException, boolean useOriginalMessagePolicy,
-            Predicate retryWhile, ScheduledExecutorService executorService, Processor onPrepare) {
+                                  Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy, Processor deadLetter,
+                                  String deadLetterUri, boolean deadLetterHandleNewException, boolean useOriginalMessagePolicy,
+                                  Predicate retryWhile, ScheduledExecutorService executorService, Processor onPrepareProcessor, Processor onExceptionProcessor) {
 
         ObjectHelper.notNull(camelContext, "CamelContext", this);
         ObjectHelper.notNull(redeliveryPolicy, "RedeliveryPolicy", this);
@@ -221,7 +224,8 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         this.useOriginalMessagePolicy = useOriginalMessagePolicy;
         this.retryWhilePolicy = retryWhile;
         this.executorService = executorService;
-        this.onPrepare = onPrepare;
+        this.onPrepareProcessor = onPrepareProcessor;
+        this.onExceptionProcessor = onExceptionProcessor;
 
         if (ObjectHelper.isNotEmpty(redeliveryPolicy.getExchangeFormatterRef())) {
             ExchangeFormatter formatter = camelContext.getRegistry().lookupByNameAndType(redeliveryPolicy.getExchangeFormatterRef(), ExchangeFormatter.class);
@@ -368,6 +372,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
             boolean handle = shouldHandleException(exchange);
             if (handle) {
                 handleException(exchange, data, isDeadLetterChannel());
+                onExceptionOccurred(exchange, data);
             }
 
             // compute if we are exhausted, and whether redelivery is allowed
@@ -546,6 +551,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         boolean handle = shouldHandleException(exchange);
         if (handle) {
             handleException(exchange, data, isDeadLetterChannel());
+            onExceptionOccurred(exchange, data);
         }
 
         // compute if we are exhausted or not
@@ -805,6 +811,11 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
             if (processor != null) {
                 data.onRedeliveryProcessor = processor;
             }
+            // route specific on exception occurred?
+            processor = exceptionPolicy.getOnExceptionOccurred();
+            if (processor != null) {
+                data.onExceptionProcessor = processor;
+            }
         }
 
         // only log if not failure handled or not an exhausted unit of work
@@ -818,7 +829,29 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
     }
 
     /**
-     * Gives an optional configure redelivery processor a chance to process before the Exchange
+     * Gives an optional configured OnExceptionOccurred processor a chance to process just after an exception
+     * was thrown while processing the Exchange. This allows to execute the processor at the same time the exception was thrown.
+     */
+    protected void onExceptionOccurred(Exchange exchange, final RedeliveryData data) {
+        if (data.onExceptionProcessor == null) {
+            return;
+        }
+
+        // run this synchronously as its just a Processor
+        try {
+            if (log.isTraceEnabled()) {
+                log.trace("OnExceptionOccurred processor {} is processing Exchange: {} due exception occurred", data.onExceptionProcessor, exchange);
+            }
+            data.onExceptionProcessor.process(exchange);
+        } catch (Throwable e) {
+            // we dont not want new exception to override existing, so log it as a WARN
+            log.warn("Error during processing OnExceptionOccurred. This exception is ignored.", e);
+        }
+        log.trace("OnExceptionOccurred processor done");
+    }
+
+    /**
+     * Gives an optional configured redelivery processor a chance to process before the Exchange
      * will be redelivered. This can be used to alter the Exchange.
      */
     protected void deliverToOnRedeliveryProcessor(final Exchange exchange, final RedeliveryData data) {
@@ -897,10 +930,10 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
             MessageHelper.resetStreamCache(exchange.getIn());
 
             // invoke custom on prepare
-            if (onPrepare != null) {
+            if (onPrepareProcessor != null) {
                 try {
-                    log.trace("OnPrepare processor {} is processing Exchange: {}", onPrepare, exchange);
-                    onPrepare.process(exchange);
+                    log.trace("OnPrepare processor {} is processing Exchange: {}", onPrepareProcessor, exchange);
+                    onPrepareProcessor.process(exchange);
                 } catch (Exception e) {
                     // a new exception was thrown during prepare
                     exchange.setException(e);
@@ -941,10 +974,10 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         } else {
             try {
                 // invoke custom on prepare
-                if (onPrepare != null) {
+                if (onPrepareProcessor != null) {
                     try {
-                        log.trace("OnPrepare processor {} is processing Exchange: {}", onPrepare, exchange);
-                        onPrepare.process(exchange);
+                        log.trace("OnPrepare processor {} is processing Exchange: {}", onPrepareProcessor, exchange);
+                        onPrepareProcessor.process(exchange);
                     } catch (Exception e) {
                         // a new exception was thrown during prepare
                         exchange.setException(e);

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.java b/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.java
new file mode 100644
index 0000000..838f8a3
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.onexception;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.JndiRegistry;
+
+public class OnExceptionOccurredProcessorOnExceptionTest extends ContextTestSupport {
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndi = super.createRegistry();
+        jndi.bind("myProcessor", new MyProcessor());
+        return jndi;
+    }
+
+    public void testOnExceptionOccurred() throws Exception {
+        getMockEndpoint("mock:dead").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        MyProcessor myProcessor = context.getRegistry().lookupByNameAndType("myProcessor", MyProcessor.class);
+        // 1 = first time + 3 redelivery attempts
+        assertEquals(1 + 3, myProcessor.getInvoked());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                MyProcessor myProcessor = context.getRegistry().lookupByNameAndType("myProcessor", MyProcessor.class);
+
+                errorHandler(deadLetterChannel("mock:dead"));
+
+                onException(Exception.class).maximumRedeliveries(3).redeliveryDelay(0).onExceptionOccurred(myProcessor);
+
+                from("direct:start")
+                    .throwException(new IllegalArgumentException("Forced"));
+            }
+        };
+    }
+
+    public static class MyProcessor implements Processor {
+
+        private int invoked;
+
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            invoked++;
+        }
+
+        public int getInvoked() {
+            return invoked;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionOccurredProcessorTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionOccurredProcessorTest.java b/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionOccurredProcessorTest.java
new file mode 100644
index 0000000..77d959f
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionOccurredProcessorTest.java
@@ -0,0 +1,75 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.onexception;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.JndiRegistry;
+
+public class OnExceptionOccurredProcessorTest extends ContextTestSupport {
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndi = super.createRegistry();
+        jndi.bind("myProcessor", new MyProcessor());
+        return jndi;
+    }
+
+    public void testOnExceptionOccurred() throws Exception {
+        getMockEndpoint("mock:dead").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        MyProcessor myProcessor = context.getRegistry().lookupByNameAndType("myProcessor", MyProcessor.class);
+        // 1 = first time + 3 redelivery attempts
+        assertEquals(1 + 3, myProcessor.getInvoked());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                MyProcessor myProcessor = context.getRegistry().lookupByNameAndType("myProcessor", MyProcessor.class);
+
+                errorHandler(deadLetterChannel("mock:dead").maximumRedeliveries(3).redeliveryDelay(0).onExceptionOccurred(myProcessor));
+
+                from("direct:start")
+                    .throwException(new IllegalArgumentException("Forced"));
+            }
+        };
+    }
+
+    public static class MyProcessor implements Processor {
+
+        private int invoked;
+
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            invoked++;
+        }
+
+        public int getInvoked() {
+            return invoked;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 98244a1..2965f93 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
@@ -56,6 +56,8 @@ public class CamelErrorHandlerFactoryBean extends AbstractCamelFactoryBean<Error
     @XmlAttribute
     private String onPrepareFailureRef;
     @XmlAttribute
+    private String onExceptionOccurredRef;
+    @XmlAttribute
     private String retryWhileRef;
     @XmlAttribute
     private String executorServiceRef;
@@ -92,6 +94,9 @@ public class CamelErrorHandlerFactoryBean extends AbstractCamelFactoryBean<Error
             if (onPrepareFailureRef != null) {
                 handler.setOnPrepareFailure(lookup(onPrepareFailureRef, Processor.class));
             }
+            if (onExceptionOccurredRef != null) {
+                handler.setOnExceptionOccurred(lookup(onExceptionOccurredRef, Processor.class));
+            }
             if (retryWhileRef != null) {
                 handler.setRetryWhileRef(retryWhileRef);
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 43df20b..80fcdb8 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
@@ -54,6 +54,8 @@ public class ErrorHandlerDefinition extends IdentifiedType {
     @XmlAttribute
     private String onRedeliveryRef;
     @XmlAttribute
+    private String onExceptionOccurredRef;
+    @XmlAttribute
     private String onPrepareFailureRef;
     @XmlAttribute
     private String retryWhileRef;

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 65ae81a..0dbc53d 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
@@ -62,6 +62,7 @@ public class ErrorHandlerDefinitionParser extends BeanDefinitionParser {
                 && !attributeName.equals("onRedeliveryRef")
                 && !attributeName.equals("onRetryWhileRef")
                 && !attributeName.equals("onPrepareFailureRef")
+                && !attributeName.equals("onExceptionOccurredRef")
                 && !attributeName.equals("redeliveryPolicyRef")
                 && !attributeName.equals("transactionTemplateRef")
                 && !attributeName.equals("transactionManagerRef");
@@ -102,6 +103,7 @@ public class ErrorHandlerDefinitionParser extends BeanDefinitionParser {
             parserRefAttribute(element, "onRedeliveryRef", "onRedelivery", builder);
             parserRefAttribute(element, "onRetryWhileRef", "onRetryWhile", builder);
             parserRefAttribute(element, "onPrepareFailureRef", "onPrepareFailure", builder);
+            parserRefAttribute(element, "onExceptionOccurredRef", "onExceptionOccurred", builder);
             parserRefAttribute(element, "redeliveryPolicyRef", "redeliveryPolicy", builder);
             if (type.equals(ErrorHandlerType.TransactionErrorHandler)) {
                 parserRefAttribute(element, "transactionTemplateRef", "transactionTemplate", builder);
@@ -146,6 +148,11 @@ public class ErrorHandlerDefinitionParser extends BeanDefinitionParser {
             throw new IllegalArgumentException("Attribute onRedeliveryRef is not supported by error handler type: "
                     + type.name() + ", in error handler with id: " + id);
         }
+        String onExceptionOccurredRef = element.getAttribute("onExceptionOccurredRef");
+        if (ObjectHelper.isNotEmpty(onExceptionOccurredRef) && (type.equals(ErrorHandlerType.LoggingErrorHandler) || type.equals(ErrorHandlerType.NoErrorHandler))) {
+            throw new IllegalArgumentException("Attribute onExceptionOccurredRef is not supported by error handler type: "
+                    + type.name() + ", in error handler with id: " + id);
+        }
         String onPrepareFailureRef = element.getAttribute("onPrepareFailureRef");
         if (ObjectHelper.isNotEmpty(onPrepareFailureRef) && (type.equals(ErrorHandlerType.TransactionErrorHandler) || type.equals(ErrorHandlerType.LoggingErrorHandler) 
             || type.equals(ErrorHandlerType.NoErrorHandler))) {

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/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 3e04802..653ea84 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
@@ -61,13 +61,15 @@ public class TransactionErrorHandler extends RedeliveryErrorHandler {
      * @param retryWhile              retry while
      * @param executorService         the {@link java.util.concurrent.ScheduledExecutorService} to be used for redelivery thread pool. Can be <tt>null</tt>.
      * @param rollbackLoggingLevel    logging level to use for logging transaction rollback occurred
+     * @param onExceptionOccurredProcessor  a custom {@link org.apache.camel.Processor} to process the {@link org.apache.camel.Exchange} just after an exception was thrown.
      */
     public TransactionErrorHandler(CamelContext camelContext, Processor output, CamelLogger logger, 
             Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy exceptionPolicyStrategy,
             TransactionTemplate transactionTemplate, Predicate retryWhile, ScheduledExecutorService executorService,
-            LoggingLevel rollbackLoggingLevel) {
+            LoggingLevel rollbackLoggingLevel, Processor onExceptionOccurredProcessor) {
 
-        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, false, false, retryWhile, executorService, null);
+        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, false, false, retryWhile,
+                executorService, null, onExceptionOccurredProcessor);
         setExceptionPolicy(exceptionPolicyStrategy);
         this.transactionTemplate = transactionTemplate;
         this.rollbackLoggingLevel = rollbackLoggingLevel;

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
index d3cad1b..2e35574 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
@@ -107,7 +107,7 @@ public class TransactionErrorHandlerBuilder extends DefaultErrorHandlerBuilder {
 
         TransactionErrorHandler answer = new TransactionErrorHandler(routeContext.getCamelContext(), processor,
             getLogger(), getOnRedelivery(), getRedeliveryPolicy(), getExceptionPolicyStrategy(), transactionTemplate, 
-            getRetryWhilePolicy(routeContext.getCamelContext()), getExecutorService(routeContext.getCamelContext()), getRollbackLoggingLevel());
+            getRetryWhilePolicy(routeContext.getCamelContext()), getExecutorService(routeContext.getCamelContext()), getRollbackLoggingLevel(), getOnExceptionOccurred());
         // configure error handler before we can use it
         configure(routeContext, answer);
         return answer;

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-spring/src/test/java/org/apache/camel/spring/processor/onexception/SpringOnExceptionOccurredProcessorOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/processor/onexception/SpringOnExceptionOccurredProcessorOnExceptionTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/onexception/SpringOnExceptionOccurredProcessorOnExceptionTest.java
new file mode 100644
index 0000000..526b609
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/onexception/SpringOnExceptionOccurredProcessorOnExceptionTest.java
@@ -0,0 +1,33 @@
+/**
+ * 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.onexception;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.processor.onexception.OnExceptionOccurredProcessorOnExceptionTest;
+
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+/**
+ * @version 
+ */
+public class SpringOnExceptionOccurredProcessorOnExceptionTest extends OnExceptionOccurredProcessorOnExceptionTest {
+
+    protected CamelContext createCamelContext() throws Exception {
+        return createSpringCamelContext(this, "org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.xml");
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-spring/src/test/java/org/apache/camel/spring/processor/onexception/SpringOnExceptionOccurredProcessorTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/processor/onexception/SpringOnExceptionOccurredProcessorTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/onexception/SpringOnExceptionOccurredProcessorTest.java
new file mode 100644
index 0000000..afb67be
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/processor/onexception/SpringOnExceptionOccurredProcessorTest.java
@@ -0,0 +1,33 @@
+/**
+ * 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.onexception;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.processor.onexception.OnExceptionOccurredProcessorTest;
+
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+/**
+ * @version 
+ */
+public class SpringOnExceptionOccurredProcessorTest extends OnExceptionOccurredProcessorTest {
+
+    protected CamelContext createCamelContext() throws Exception {
+        return createSpringCamelContext(this, "org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorTest.xml");
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.xml
new file mode 100644
index 0000000..442aa11
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorOnExceptionTest.xml
@@ -0,0 +1,47 @@
+<?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="myProcessor" class="org.apache.camel.processor.onexception.OnExceptionOccurredProcessorOnExceptionTest.MyProcessor"/>
+
+  <bean id="forced" class="java.lang.IllegalArgumentException">
+    <constructor-arg index="0" value="Forced"/>
+  </bean>
+
+  <camelContext errorHandlerRef="eh" xmlns="http://camel.apache.org/schema/spring">
+
+    <errorHandler id="eh" deadLetterUri="mock:dead" type="DeadLetterChannel"/>
+
+    <onException onExceptionOccurredRef="myProcessor">
+      <exception>java.lang.Exception</exception>
+      <redeliveryPolicy maximumRedeliveries="3" redeliveryDelay="0"/>
+    </onException>
+
+    <route>
+      <from uri="direct:start"/>
+      <throwException ref="forced"/>
+    </route>
+
+  </camelContext>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorTest.xml
new file mode 100644
index 0000000..9c032f7
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/OnExceptionOccurredProcessorTest.xml
@@ -0,0 +1,44 @@
+<?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="myProcessor" class="org.apache.camel.processor.onexception.OnExceptionOccurredProcessorTest.MyProcessor"/>
+
+  <bean id="forced" class="java.lang.IllegalArgumentException">
+    <constructor-arg index="0" value="Forced"/>
+  </bean>
+
+  <camelContext errorHandlerRef="eh" xmlns="http://camel.apache.org/schema/spring">
+
+    <errorHandler id="eh" deadLetterUri="mock:dead" type="DeadLetterChannel" onExceptionOccurredRef="myProcessor">
+      <redeliveryPolicy maximumRedeliveries="3" redeliveryDelay="0"/>
+    </errorHandler>
+
+    <route>
+      <from uri="direct:start"/>
+      <throwException ref="forced"/>
+    </route>
+
+  </camelContext>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.java b/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.java
new file mode 100644
index 0000000..aad66eb
--- /dev/null
+++ b/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.test.blueprint;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.junit.Test;
+
+public class OnExceptionOccurredProcessorOnExceptionTest extends CamelBlueprintTestSupport {
+
+    @Override
+    protected String getBlueprintDescriptor() {
+        return "org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.xml";
+    }
+
+    @Test
+    public void testOnExceptionOccurred() throws Exception {
+        getMockEndpoint("mock:dead").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        MyProcessor myProcessor = context.getRegistry().lookupByNameAndType("myProcessor", MyProcessor.class);
+        // 1 = first time + 3 redelivery attempts
+        assertEquals(1 + 3, myProcessor.getInvoked());
+    }
+
+    public static class MyProcessor implements Processor {
+
+        private int invoked;
+
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            invoked++;
+        }
+
+        public int getInvoked() {
+            return invoked;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.java
----------------------------------------------------------------------
diff --git a/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.java b/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.java
new file mode 100644
index 0000000..57b8621
--- /dev/null
+++ b/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.test.blueprint;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.junit.Test;
+
+public class OnExceptionOccurredProcessorTest extends CamelBlueprintTestSupport {
+
+    @Override
+    protected String getBlueprintDescriptor() {
+        return "org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.xml";
+    }
+
+    @Test
+    public void testOnExceptionOccurred() throws Exception {
+        getMockEndpoint("mock:dead").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        MyProcessor myProcessor = context.getRegistry().lookupByNameAndType("myProcessor", MyProcessor.class);
+        // 1 = first time + 3 redelivery attempts
+        assertEquals(1 + 3, myProcessor.getInvoked());
+    }
+
+    public static class MyProcessor implements Processor {
+
+        private int invoked;
+
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            invoked++;
+        }
+
+        public int getInvoked() {
+            return invoked;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.xml b/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.xml
new file mode 100644
index 0000000..39db3a0
--- /dev/null
+++ b/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorOnExceptionTest.xml
@@ -0,0 +1,46 @@
+<?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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:schemaLocation="
+             http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+  <bean id="myProcessor" class="org.apache.camel.test.blueprint.OnExceptionOccurredProcessorOnExceptionTest.MyProcessor"/>
+
+  <bean id="forced" class="java.lang.IllegalArgumentException">
+    <argument index="0" value="Forced"/>
+  </bean>
+
+  <camelContext errorHandlerRef="eh" xmlns="http://camel.apache.org/schema/blueprint">
+
+    <errorHandler id="eh" deadLetterUri="mock:dead" type="DeadLetterChannel"/>
+
+    <onException onExceptionOccurredRef="myProcessor">
+      <exception>java.lang.Exception</exception>
+      <redeliveryPolicy maximumRedeliveries="3" redeliveryDelay="0"/>
+    </onException>
+
+    <route>
+      <from uri="direct:start"/>
+      <throwException ref="forced"/>
+    </route>
+
+  </camelContext>
+
+</blueprint>
+

http://git-wip-us.apache.org/repos/asf/camel/blob/44e85561/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.xml b/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.xml
new file mode 100644
index 0000000..0285024
--- /dev/null
+++ b/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/OnExceptionOccurredProcessorTest.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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:schemaLocation="
+             http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+  <bean id="myProcessor" class="org.apache.camel.test.blueprint.OnExceptionOccurredProcessorTest.MyProcessor"/>
+
+  <bean id="forced" class="java.lang.IllegalArgumentException">
+    <argument index="0" value="Forced"/>
+  </bean>
+
+  <camelContext errorHandlerRef="eh" xmlns="http://camel.apache.org/schema/blueprint">
+
+    <errorHandler id="eh" deadLetterUri="mock:dead" type="DeadLetterChannel" onExceptionOccurredRef="myProcessor">
+      <redeliveryPolicy maximumRedeliveries="3" redeliveryDelay="0"/>
+    </errorHandler>
+
+    <route>
+      <from uri="direct:start"/>
+      <throwException ref="forced"/>
+    </route>
+
+  </camelContext>
+
+</blueprint>
+


Mime
View raw message