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