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