001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.processor;
018
019import java.io.Serializable;
020import java.util.Random;
021
022import org.apache.camel.Exchange;
023import org.apache.camel.LoggingLevel;
024import org.apache.camel.Predicate;
025import org.apache.camel.util.ObjectHelper;
026import org.apache.camel.util.StringHelper;
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030/**
031 * The policy used to decide how many times to redeliver and the time between
032 * the redeliveries before being sent to a <a
033 * href="http://camel.apache.org/dead-letter-channel.html">Dead Letter
034 * Channel</a>
035 * <p>
036 * The default values are:
037 * <ul>
038 *   <li>maximumRedeliveries = 0</li>
039 *   <li>redeliveryDelay = 1000L (the initial delay)</li>
040 *   <li>maximumRedeliveryDelay = 60 * 1000L</li>
041 *   <li>asyncDelayedRedelivery = false</li>
042 *   <li>backOffMultiplier = 2</li>
043 *   <li>useExponentialBackOff = false</li>
044 *   <li>collisionAvoidanceFactor = 0.15d</li>
045 *   <li>useCollisionAvoidance = false</li>
046 *   <li>retriesExhaustedLogLevel = LoggingLevel.ERROR</li>
047 *   <li>retryAttemptedLogLevel = LoggingLevel.DEBUG</li>
048 *   <li>retryAttemptedLogInterval = 1</li>
049 *   <li>logRetryAttempted = true</li>
050 *   <li>logRetryStackTrace = false</li>
051 *   <li>logStackTrace = true</li>
052 *   <li>logHandled = false</li>
053 *   <li>logExhausted = true</li>
054 *   <li>logExhaustedMessageHistory = true</li>
055 *   <li>logExhaustedMessageBody = false</li>
056 *   <li>logNewException = true</li>
057 *   <li>allowRedeliveryWhileStopping = true</li>
058 * </ul>
059 * <p/>
060 * Setting the maximumRedeliveries to a negative value such as -1 will then always redeliver (unlimited).
061 * Setting the maximumRedeliveries to 0 will disable redelivery.
062 * <p/>
063 * This policy can be configured either by one of the following two settings:
064 * <ul>
065 *   <li>using conventional options, using all the options defined above</li>
066 *   <li>using delay pattern to declare intervals for delays</li>
067 * </ul>
068 * <p/>
069 * <b>Note:</b> If using delay patterns then the following options is not used (delay, backOffMultiplier, useExponentialBackOff, useCollisionAvoidance)
070 * <p/>
071 * <b>Using delay pattern</b>:
072 * <br/>The delay pattern syntax is: <tt>limit:delay;limit 2:delay 2;limit 3:delay 3;...;limit N:delay N</tt>.
073 * <p/>
074 * How it works is best illustrate with an example with this pattern: <tt>delayPattern=5:1000;10:5000:20:20000</tt>
075 * <br/>The delays will be for attempt in range 0..4 = 0 millis, 5..9 = 1000 millis, 10..19 = 5000 millis, >= 20 = 20000 millis.
076 * <p/>
077 * If you want to set a starting delay, then use 0 as the first limit, eg: <tt>0:1000;5:5000</tt> will use 1 sec delay
078 * until attempt number 5 where it will use 5 seconds going forward.
079 *
080 * @version 
081 */
082public class RedeliveryPolicy implements Cloneable, Serializable {
083    protected static Random randomNumberGenerator;
084    private static final long serialVersionUID = -338222777701473252L;
085    private static final Logger LOG = LoggerFactory.getLogger(RedeliveryPolicy.class);
086
087    protected long redeliveryDelay = 1000L;
088    protected int maximumRedeliveries;
089    protected long maximumRedeliveryDelay = 60 * 1000L;
090    protected double backOffMultiplier = 2;
091    protected boolean useExponentialBackOff;
092    // +/-15% for a 30% spread -cgs
093    protected double collisionAvoidanceFactor = 0.15d;
094    protected boolean useCollisionAvoidance;
095    protected LoggingLevel retriesExhaustedLogLevel = LoggingLevel.ERROR;
096    protected LoggingLevel retryAttemptedLogLevel = LoggingLevel.DEBUG;
097    protected int retryAttemptedLogInterval = 1;
098    protected boolean logStackTrace = true;
099    protected boolean logRetryStackTrace;
100    protected boolean logHandled;
101    protected boolean logContinued;
102    protected boolean logExhausted = true;
103    protected boolean logNewException = true;
104    protected Boolean logExhaustedMessageHistory;
105    protected Boolean logExhaustedMessageBody;
106    protected boolean logRetryAttempted = true;
107    protected String delayPattern;
108    protected boolean asyncDelayedRedelivery;
109    protected boolean allowRedeliveryWhileStopping = true;
110    protected String exchangeFormatterRef;
111
112    public RedeliveryPolicy() {
113    }
114
115    @Override
116    public String toString() {
117        return "RedeliveryPolicy[maximumRedeliveries=" + maximumRedeliveries
118            + ", redeliveryDelay=" + redeliveryDelay
119            + ", maximumRedeliveryDelay=" + maximumRedeliveryDelay
120            + ", asyncDelayedRedelivery=" + asyncDelayedRedelivery
121            + ", allowRedeliveryWhileStopping=" + allowRedeliveryWhileStopping
122            + ", retriesExhaustedLogLevel=" + retriesExhaustedLogLevel
123            + ", retryAttemptedLogLevel=" + retryAttemptedLogLevel
124            + ", retryAttemptedLogInterval=" + retryAttemptedLogInterval
125            + ", logRetryAttempted=" + logRetryAttempted
126            + ", logStackTrace=" + logStackTrace
127            + ", logRetryStackTrace=" + logRetryStackTrace
128            + ", logHandled=" + logHandled
129            + ", logContinued=" + logContinued
130            + ", logExhausted=" + logExhausted
131            + ", logNewException=" + logNewException
132            + ", logExhaustedMessageHistory=" + logExhaustedMessageHistory
133            + ", logExhaustedMessageBody=" + logExhaustedMessageBody
134            + ", useExponentialBackOff="  + useExponentialBackOff
135            + ", backOffMultiplier=" + backOffMultiplier
136            + ", useCollisionAvoidance=" + useCollisionAvoidance
137            + ", collisionAvoidanceFactor=" + collisionAvoidanceFactor
138            + ", delayPattern=" + delayPattern 
139            + ", exchangeFormatterRef=" + exchangeFormatterRef + "]";
140    }
141
142    public RedeliveryPolicy copy() {
143        try {
144            return (RedeliveryPolicy)clone();
145        } catch (CloneNotSupportedException e) {
146            throw new RuntimeException("Could not clone: " + e, e);
147        }
148    }
149
150    /**
151     * Returns true if the policy decides that the message exchange should be
152     * redelivered.
153     *
154     * @param exchange  the current exchange
155     * @param redeliveryCounter  the current retry counter
156     * @param retryWhile  an optional predicate to determine if we should redeliver or not
157     * @return true to redeliver, false to stop
158     */
159    public boolean shouldRedeliver(Exchange exchange, int redeliveryCounter, Predicate retryWhile) {
160        // predicate is always used if provided
161        if (retryWhile != null) {
162            return retryWhile.matches(exchange);
163        }
164
165        if (getMaximumRedeliveries() < 0) {
166            // retry forever if negative value
167            return true;
168        }
169        // redeliver until we hit the max
170        return redeliveryCounter <= getMaximumRedeliveries();
171    }
172
173
174    /**
175     * Calculates the new redelivery delay based on the last one and then <b>sleeps</b> for the necessary amount of time.
176     * <p/>
177     * This implementation will block while sleeping.
178     *
179     * @param redeliveryDelay  previous redelivery delay
180     * @param redeliveryCounter  number of previous redelivery attempts
181     * @return the calculate delay
182     * @throws InterruptedException is thrown if the sleep is interrupted likely because of shutdown
183     */
184    public long sleep(long redeliveryDelay, int redeliveryCounter) throws InterruptedException {
185        redeliveryDelay = calculateRedeliveryDelay(redeliveryDelay, redeliveryCounter);
186
187        if (redeliveryDelay > 0) {
188            sleep(redeliveryDelay);
189        }
190        return redeliveryDelay;
191    }
192
193    /**
194     * Sleeps for the given delay
195     *
196     * @param redeliveryDelay  the delay
197     * @throws InterruptedException is thrown if the sleep is interrupted likely because of shutdown
198     */
199    public void sleep(long redeliveryDelay) throws InterruptedException {
200        LOG.debug("Sleeping for: {} millis until attempting redelivery", redeliveryDelay);
201        Thread.sleep(redeliveryDelay);
202    }
203
204    /**
205     * Calculates the new redelivery delay based on the last one
206     *
207     * @param previousDelay  previous redelivery delay
208     * @param redeliveryCounter  number of previous redelivery attempts
209     * @return the calculate delay
210     */
211    public long calculateRedeliveryDelay(long previousDelay, int redeliveryCounter) {
212        if (ObjectHelper.isNotEmpty(delayPattern)) {
213            // calculate delay using the pattern
214            return calculateRedeliverDelayUsingPattern(delayPattern, redeliveryCounter);
215        }
216
217        // calculate the delay using the conventional parameters
218        long redeliveryDelayResult;
219        if (previousDelay == 0) {
220            redeliveryDelayResult = redeliveryDelay;
221        } else if (useExponentialBackOff && backOffMultiplier > 1) {
222            redeliveryDelayResult = Math.round(backOffMultiplier * previousDelay);
223        } else {
224            redeliveryDelayResult = previousDelay;
225        }
226
227        if (useCollisionAvoidance) {
228
229            /*
230             * First random determines +/-, second random determines how far to
231             * go in that direction. -cgs
232             */
233            Random random = getRandomNumberGenerator();
234            double variance = (random.nextBoolean() ? collisionAvoidanceFactor : -collisionAvoidanceFactor)
235                              * random.nextDouble();
236            redeliveryDelayResult += redeliveryDelayResult * variance;
237        }
238
239        // ensure the calculated result is not bigger than the max delay (if configured)
240        if (maximumRedeliveryDelay > 0 && redeliveryDelayResult > maximumRedeliveryDelay) {
241            redeliveryDelayResult = maximumRedeliveryDelay;
242        }
243
244        return redeliveryDelayResult;
245    }
246
247    /**
248     * Calculates the delay using the delay pattern
249     */
250    protected static long calculateRedeliverDelayUsingPattern(String delayPattern, int redeliveryCounter) {
251        String[] groups = delayPattern.split(";");
252        // find the group where the redelivery counter matches
253        long answer = 0;
254        for (String group : groups) {
255            long delay = Long.valueOf(StringHelper.after(group, ":"));
256            int count = Integer.valueOf(StringHelper.before(group, ":"));
257            if (count > redeliveryCounter) {
258                break;
259            } else {
260                answer = delay;
261            }
262        }
263
264        return answer;
265    }
266
267    // Builder methods
268    // -------------------------------------------------------------------------
269
270    /**
271     * Sets the initial redelivery delay in milliseconds
272     *
273     * @deprecated will be removed in the near future. Instead use {@link #redeliveryDelay(long)} instead
274     */
275    @Deprecated
276    public RedeliveryPolicy redeliverDelay(long delay) {
277        return redeliveryDelay(delay);
278    }
279
280    /**
281     * Sets the initial redelivery delay in milliseconds
282     */
283    public RedeliveryPolicy redeliveryDelay(long delay) {
284        setRedeliveryDelay(delay);
285        return this;
286    }
287
288    /**
289     * Sets the maximum number of times a message exchange will be redelivered
290     */
291    public RedeliveryPolicy maximumRedeliveries(int maximumRedeliveries) {
292        setMaximumRedeliveries(maximumRedeliveries);
293        return this;
294    }
295
296    /**
297     * Enables collision avoidance which adds some randomization to the backoff
298     * timings to reduce contention probability
299     */
300    public RedeliveryPolicy useCollisionAvoidance() {
301        setUseCollisionAvoidance(true);
302        return this;
303    }
304
305    /**
306     * Enables exponential backoff using the {@link #getBackOffMultiplier()} to
307     * increase the time between retries
308     */
309    public RedeliveryPolicy useExponentialBackOff() {
310        setUseExponentialBackOff(true);
311        return this;
312    }
313
314    /**
315     * Enables exponential backoff and sets the multiplier used to increase the
316     * delay between redeliveries
317     */
318    public RedeliveryPolicy backOffMultiplier(double multiplier) {
319        useExponentialBackOff();
320        setBackOffMultiplier(multiplier);
321        return this;
322    }
323
324    /**
325     * Enables collision avoidance and sets the percentage used
326     */
327    public RedeliveryPolicy collisionAvoidancePercent(double collisionAvoidancePercent) {
328        useCollisionAvoidance();
329        setCollisionAvoidancePercent(collisionAvoidancePercent);
330        return this;
331    }
332
333    /**
334     * Sets the maximum redelivery delay if using exponential back off.
335     * Use -1 if you wish to have no maximum
336     */
337    public RedeliveryPolicy maximumRedeliveryDelay(long maximumRedeliveryDelay) {
338        setMaximumRedeliveryDelay(maximumRedeliveryDelay);
339        return this;
340    }
341
342    /**
343     * Sets the logging level to use for log messages when retries have been exhausted.
344     */
345    public RedeliveryPolicy retriesExhaustedLogLevel(LoggingLevel retriesExhaustedLogLevel) {
346        setRetriesExhaustedLogLevel(retriesExhaustedLogLevel);
347        return this;
348    }    
349
350    /**
351     * Sets the logging level to use for log messages when retries are attempted.
352     */    
353    public RedeliveryPolicy retryAttemptedLogLevel(LoggingLevel retryAttemptedLogLevel) {
354        setRetryAttemptedLogLevel(retryAttemptedLogLevel);
355        return this;
356    }
357
358    /**
359     * Sets the interval to log retry attempts
360     */
361    public RedeliveryPolicy retryAttemptedLogInterval(int logRetryAttemptedInterval) {
362        setRetryAttemptedLogInterval(logRetryAttemptedInterval);
363        return this;
364    }
365
366    /**
367     * Sets whether to log retry attempts
368     */
369    public RedeliveryPolicy logRetryAttempted(boolean logRetryAttempted) {
370        setLogRetryAttempted(logRetryAttempted);
371        return this;
372    }
373
374    /**
375     * Sets whether to log stacktrace for failed messages.
376     */
377    public RedeliveryPolicy logStackTrace(boolean logStackTrace) {
378        setLogStackTrace(logStackTrace);
379        return this;
380    }
381
382    /**
383     * Sets whether to log stacktrace for failed redelivery attempts
384     */
385    public RedeliveryPolicy logRetryStackTrace(boolean logRetryStackTrace) {
386        setLogRetryStackTrace(logRetryStackTrace);
387        return this;
388    }
389
390    /**
391     * Sets whether to log errors even if its handled
392     */
393    public RedeliveryPolicy logHandled(boolean logHandled) {
394        setLogHandled(logHandled);
395        return this;
396    }
397
398    /**
399     * Sets whether errors should be logged when a new exception occurred during handling a previous exception
400     */
401    public RedeliveryPolicy logNewException(boolean logNewException) {
402        setLogNewException(logNewException);
403        return this;
404    }
405
406    /**
407     * Sets whether to log exhausted errors
408     */
409    public RedeliveryPolicy logExhausted(boolean logExhausted) {
410        setLogExhausted(logExhausted);
411        return this;
412    }
413
414    /**
415     * Sets whether to log exhausted errors including message history
416     */
417    public RedeliveryPolicy logExhaustedMessageHistory(boolean logExhaustedMessageHistory) {
418        setLogExhaustedMessageHistory(logExhaustedMessageHistory);
419        return this;
420    }
421
422    /**
423     * Sets whether to log exhausted errors including message body (requires message history to be enabled)
424     */
425    public RedeliveryPolicy logExhaustedMessageBody(boolean logExhaustedMessageBody) {
426        setLogExhaustedMessageBody(logExhaustedMessageBody);
427        return this;
428    }
429
430    /**
431     * Sets the delay pattern with delay intervals.
432     */
433    public RedeliveryPolicy delayPattern(String delayPattern) {
434        setDelayPattern(delayPattern);
435        return this;
436    }
437
438    /**
439     * Disables redelivery by setting maximum redeliveries to 0.
440     */
441    public RedeliveryPolicy disableRedelivery() {
442        setMaximumRedeliveries(0);
443        return this;
444    }
445
446    /**
447     * Allow asynchronous delayed redelivery.
448     *
449     * @see #setAsyncDelayedRedelivery(boolean)
450     */
451    public RedeliveryPolicy asyncDelayedRedelivery() {
452        setAsyncDelayedRedelivery(true);
453        return this;
454    }
455
456    /**
457     * Controls whether to allow redelivery while stopping/shutting down a route that uses error handling.
458     *
459     * @param redeliverWhileStopping <tt>true</tt> to allow redelivery, <tt>false</tt> to reject redeliveries
460     */
461    public RedeliveryPolicy allowRedeliveryWhileStopping(boolean redeliverWhileStopping) {
462        setAllowRedeliveryWhileStopping(redeliverWhileStopping);
463        return this;
464    }
465    
466    /**
467     * Sets the reference of the instance of {@link org.apache.camel.spi.ExchangeFormatter} to generate the log message from exchange.
468     *
469     * @param exchangeFormatterRef name of the instance of {@link org.apache.camel.spi.ExchangeFormatter}
470     * @return the builder
471     */
472    public RedeliveryPolicy exchangeFormatterRef(String exchangeFormatterRef) {
473        setExchangeFormatterRef(exchangeFormatterRef);
474        return this;
475    }
476
477    // Properties
478    // -------------------------------------------------------------------------
479
480    /**
481     * @deprecated will be removed in the near future. Instead use {@link #getRedeliveryDelay()}
482     */
483    @Deprecated
484    public long getRedeliverDelay() {
485        return getRedeliveryDelay();
486    }
487
488    /**
489     * @deprecated will be removed in the near future. Instead use {@link #setRedeliveryDelay(long)}
490     */
491    @Deprecated
492    public void setRedeliverDelay(long redeliveryDelay) {
493        setRedeliveryDelay(redeliveryDelay);
494    }
495    
496    public long getRedeliveryDelay() {
497        return redeliveryDelay;
498    }
499
500    /**
501     * Sets the initial redelivery delay in milliseconds
502     */
503    public void setRedeliveryDelay(long redeliverDelay) {
504        this.redeliveryDelay = redeliverDelay;
505        // if max enabled then also set max to this value in case max was too low
506        if (maximumRedeliveryDelay > 0 && redeliverDelay > maximumRedeliveryDelay) {
507            this.maximumRedeliveryDelay = redeliverDelay;
508        }
509    }
510
511    public double getBackOffMultiplier() {
512        return backOffMultiplier;
513    }
514
515    /**
516     * Sets the multiplier used to increase the delay between redeliveries if
517     * {@link #setUseExponentialBackOff(boolean)} is enabled
518     */
519    public void setBackOffMultiplier(double backOffMultiplier) {
520        this.backOffMultiplier = backOffMultiplier;
521    }
522
523    public long getCollisionAvoidancePercent() {
524        return Math.round(collisionAvoidanceFactor * 100);
525    }
526
527    /**
528     * Sets the percentage used for collision avoidance if enabled via
529     * {@link #setUseCollisionAvoidance(boolean)}
530     */
531    public void setCollisionAvoidancePercent(double collisionAvoidancePercent) {
532        this.collisionAvoidanceFactor = collisionAvoidancePercent * 0.01d;
533    }
534
535    public double getCollisionAvoidanceFactor() {
536        return collisionAvoidanceFactor;
537    }
538
539    /**
540     * Sets the factor used for collision avoidance if enabled via
541     * {@link #setUseCollisionAvoidance(boolean)}
542     */
543    public void setCollisionAvoidanceFactor(double collisionAvoidanceFactor) {
544        this.collisionAvoidanceFactor = collisionAvoidanceFactor;
545    }
546
547    public int getMaximumRedeliveries() {
548        return maximumRedeliveries;
549    }
550
551    /**
552     * Sets the maximum number of times a message exchange will be redelivered.
553     * Setting a negative value will retry forever.
554     */
555    public void setMaximumRedeliveries(int maximumRedeliveries) {
556        this.maximumRedeliveries = maximumRedeliveries;
557    }
558
559    public long getMaximumRedeliveryDelay() {
560        return maximumRedeliveryDelay;
561    }
562
563    /**
564     * Sets the maximum redelivery delay.
565     * Use -1 if you wish to have no maximum
566     */
567    public void setMaximumRedeliveryDelay(long maximumRedeliveryDelay) {
568        this.maximumRedeliveryDelay = maximumRedeliveryDelay;
569    }
570
571    public boolean isUseCollisionAvoidance() {
572        return useCollisionAvoidance;
573    }
574
575    /**
576     * Enables/disables collision avoidance which adds some randomization to the
577     * backoff timings to reduce contention probability
578     */
579    public void setUseCollisionAvoidance(boolean useCollisionAvoidance) {
580        this.useCollisionAvoidance = useCollisionAvoidance;
581    }
582
583    public boolean isUseExponentialBackOff() {
584        return useExponentialBackOff;
585    }
586
587    /**
588     * Enables/disables exponential backoff using the
589     * {@link #getBackOffMultiplier()} to increase the time between retries
590     */
591    public void setUseExponentialBackOff(boolean useExponentialBackOff) {
592        this.useExponentialBackOff = useExponentialBackOff;
593    }
594
595    protected static synchronized Random getRandomNumberGenerator() {
596        if (randomNumberGenerator == null) {
597            randomNumberGenerator = new Random();
598        }
599        return randomNumberGenerator;
600    }
601
602    /**
603     * Sets the logging level to use for log messages when retries have been exhausted.
604     */    
605    public void setRetriesExhaustedLogLevel(LoggingLevel retriesExhaustedLogLevel) {
606        this.retriesExhaustedLogLevel = retriesExhaustedLogLevel;        
607    }
608    
609    public LoggingLevel getRetriesExhaustedLogLevel() {
610        return retriesExhaustedLogLevel;
611    }
612
613    /**
614     * Sets the logging level to use for log messages when retries are attempted.
615     */    
616    public void setRetryAttemptedLogLevel(LoggingLevel retryAttemptedLogLevel) {
617        this.retryAttemptedLogLevel = retryAttemptedLogLevel;
618    }
619
620    public LoggingLevel getRetryAttemptedLogLevel() {
621        return retryAttemptedLogLevel;
622    }
623
624    public int getRetryAttemptedLogInterval() {
625        return retryAttemptedLogInterval;
626    }
627
628    /**
629     * Sets the interval to log retry attempts
630     */
631    public void setRetryAttemptedLogInterval(int retryAttemptedLogInterval) {
632        this.retryAttemptedLogInterval = retryAttemptedLogInterval;
633    }
634
635    public String getDelayPattern() {
636        return delayPattern;
637    }
638
639    /**
640     * Sets an optional delay pattern to use instead of fixed delay.
641     */
642    public void setDelayPattern(String delayPattern) {
643        this.delayPattern = delayPattern;
644    }
645
646    public boolean isLogStackTrace() {
647        return logStackTrace;
648    }
649
650    /**
651     * Sets whether stack traces should be logged or not
652     */
653    public void setLogStackTrace(boolean logStackTrace) {
654        this.logStackTrace = logStackTrace;
655    }
656
657    public boolean isLogRetryStackTrace() {
658        return logRetryStackTrace;
659    }
660
661    /**
662     * Sets whether stack traces should be logged or not
663     */
664    public void setLogRetryStackTrace(boolean logRetryStackTrace) {
665        this.logRetryStackTrace = logRetryStackTrace;
666    }
667
668    public boolean isLogHandled() {
669        return logHandled;
670    }
671
672    /**
673     * Sets whether errors should be logged even if its handled
674     */
675    public void setLogHandled(boolean logHandled) {
676        this.logHandled = logHandled;
677    }
678
679    public boolean isLogNewException() {
680        return logNewException;
681    }
682
683    /**
684     * Sets whether errors should be logged when a new exception occurred during handling a previous exception
685     */
686    public void setLogNewException(boolean logNewException) {
687        this.logNewException = logNewException;
688    }
689
690    public boolean isLogContinued() {
691        return logContinued;
692    }
693
694    /**
695     * Sets whether errors should be logged even if its continued
696     */
697    public void setLogContinued(boolean logContinued) {
698        this.logContinued = logContinued;
699    }
700
701    public boolean isLogRetryAttempted() {
702        return logRetryAttempted;
703    }
704
705    /**
706     * Sets whether retry attempts should be logged or not
707     */
708    public void setLogRetryAttempted(boolean logRetryAttempted) {
709        this.logRetryAttempted = logRetryAttempted;
710    }
711
712    public boolean isLogExhausted() {
713        return logExhausted;
714    }
715
716    /**
717     * Sets whether exhausted exceptions should be logged or not
718     */
719    public void setLogExhausted(boolean logExhausted) {
720        this.logExhausted = logExhausted;
721    }
722
723    public boolean isLogExhaustedMessageHistory() {
724        // should default be enabled
725        return logExhaustedMessageHistory == null || logExhaustedMessageHistory;
726    }
727
728    /**
729     * Whether the option logExhaustedMessageHistory has been configured or not
730     *
731     * @return <tt>null</tt> if not configured, or the configured value as true or false
732     * @see #isLogExhaustedMessageHistory()
733     */
734    public Boolean getLogExhaustedMessageHistory() {
735        return logExhaustedMessageHistory;
736    }
737
738    /**
739     * Sets whether exhausted exceptions should be logged with message history included.
740     */
741    public void setLogExhaustedMessageHistory(boolean logExhaustedMessageHistory) {
742        this.logExhaustedMessageHistory = logExhaustedMessageHistory;
743    }
744
745    public boolean isLogExhaustedMessageBody() {
746        // should default be disabled
747        return logExhaustedMessageBody != null && logExhaustedMessageBody;
748    }
749
750    /**
751     * Whether the option logExhaustedMessageBody has been configured or not
752     *
753     * @return <tt>null</tt> if not configured, or the configured value as true or false
754     * @see #isLogExhaustedMessageBody()
755     */
756    public Boolean getLogExhaustedMessageBody() {
757        return logExhaustedMessageBody;
758    }
759
760    /**
761     * Sets whether exhausted message body/headers should be logged with message history included
762     * (requires logExhaustedMessageHistory to be enabled).
763     */
764    public void setLogExhaustedMessageBody(Boolean logExhaustedMessageBody) {
765        this.logExhaustedMessageBody = logExhaustedMessageBody;
766    }
767
768    public boolean isAsyncDelayedRedelivery() {
769        return asyncDelayedRedelivery;
770    }
771
772    /**
773     * Sets whether asynchronous delayed redelivery is allowed.
774     * <p/>
775     * This is disabled by default.
776     * <p/>
777     * When enabled it allows Camel to schedule a future task for delayed
778     * redelivery which prevents current thread from blocking while waiting.
779     * <p/>
780     * Exchange which is transacted will however always use synchronous delayed redelivery
781     * because the transaction must execute in the same thread context.
782     *
783     * @param asyncDelayedRedelivery whether asynchronous delayed redelivery is allowed
784     */
785    public void setAsyncDelayedRedelivery(boolean asyncDelayedRedelivery) {
786        this.asyncDelayedRedelivery = asyncDelayedRedelivery;
787    }
788
789    public boolean isAllowRedeliveryWhileStopping() {
790        return allowRedeliveryWhileStopping;
791    }
792
793    /**
794     * Controls whether to allow redelivery while stopping/shutting down a route that uses error handling.
795     *
796     * @param allowRedeliveryWhileStopping <tt>true</tt> to allow redelivery, <tt>false</tt> to reject redeliveries
797     */
798    public void setAllowRedeliveryWhileStopping(boolean allowRedeliveryWhileStopping) {
799        this.allowRedeliveryWhileStopping = allowRedeliveryWhileStopping;
800    }
801
802    public String getExchangeFormatterRef() {
803        return exchangeFormatterRef;
804    }
805
806    /**
807     * Sets the reference of the instance of {@link org.apache.camel.spi.ExchangeFormatter} to generate the log message from exchange.
808     */
809    public void setExchangeFormatterRef(String exchangeFormatterRef) {
810        this.exchangeFormatterRef = exchangeFormatterRef;
811    }
812
813}