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