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 */ 017 package org.apache.camel.builder; 018 019 import org.apache.camel.Endpoint; 020 import org.apache.camel.Expression; 021 import org.apache.camel.LoggingLevel; 022 import org.apache.camel.Predicate; 023 import org.apache.camel.Processor; 024 import org.apache.camel.processor.DefaultErrorHandler; 025 import org.apache.camel.processor.ErrorHandlerSupport; 026 import org.apache.camel.processor.Logger; 027 import org.apache.camel.processor.RedeliveryPolicy; 028 import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyStrategy; 029 import org.apache.camel.spi.RouteContext; 030 import org.apache.commons.logging.Log; 031 import org.apache.commons.logging.LogFactory; 032 import static org.apache.camel.builder.PredicateBuilder.toPredicate; 033 034 /** 035 * The default error handler builder. 036 * 037 * @version $Revision: 792966 $ 038 */ 039 public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport { 040 041 protected Logger logger; 042 protected ExceptionPolicyStrategy exceptionPolicyStrategy = ErrorHandlerSupport.createDefaultExceptionPolicyStrategy(); 043 protected RedeliveryPolicy redeliveryPolicy; 044 protected Processor onRedelivery; 045 protected Predicate handledPolicy; 046 protected Processor failureProcessor; 047 protected Endpoint deadLetter; 048 protected String deadLetterUri; 049 protected boolean useOriginalMessage; 050 051 public DefaultErrorHandlerBuilder() { 052 } 053 054 public Processor createErrorHandler(RouteContext routeContext, Processor processor) throws Exception { 055 DefaultErrorHandler answer = new DefaultErrorHandler(processor, getLogger(), getOnRedelivery(), getRedeliveryPolicy(), 056 getHandledPolicy(), getExceptionPolicyStrategy()); 057 // configure error handler before we can use it 058 configure(answer); 059 return answer; 060 } 061 062 public boolean supportTransacted() { 063 return false; 064 } 065 066 067 // Builder methods 068 // ------------------------------------------------------------------------- 069 public DefaultErrorHandlerBuilder backOffMultiplier(double backOffMultiplier) { 070 getRedeliveryPolicy().backOffMultiplier(backOffMultiplier); 071 return this; 072 } 073 074 public DefaultErrorHandlerBuilder collisionAvoidancePercent(short collisionAvoidancePercent) { 075 getRedeliveryPolicy().collisionAvoidancePercent(collisionAvoidancePercent); 076 return this; 077 } 078 079 public DefaultErrorHandlerBuilder redeliverDelay(long delay) { 080 getRedeliveryPolicy().redeliverDelay(delay); 081 return this; 082 } 083 084 public DefaultErrorHandlerBuilder delayPattern(String delayPattern) { 085 getRedeliveryPolicy().delayPattern(delayPattern); 086 return this; 087 } 088 089 public DefaultErrorHandlerBuilder maximumRedeliveries(int maximumRedeliveries) { 090 getRedeliveryPolicy().maximumRedeliveries(maximumRedeliveries); 091 return this; 092 } 093 094 public DefaultErrorHandlerBuilder disableRedelivery() { 095 getRedeliveryPolicy().maximumRedeliveries(0); 096 return this; 097 } 098 099 public DefaultErrorHandlerBuilder maximumRedeliveryDelay(long maximumRedeliveryDelay) { 100 getRedeliveryPolicy().maximumRedeliveryDelay(maximumRedeliveryDelay); 101 return this; 102 } 103 104 public DefaultErrorHandlerBuilder useCollisionAvoidance() { 105 getRedeliveryPolicy().useCollisionAvoidance(); 106 return this; 107 } 108 109 public DefaultErrorHandlerBuilder useExponentialBackOff() { 110 getRedeliveryPolicy().useExponentialBackOff(); 111 return this; 112 } 113 114 public DefaultErrorHandlerBuilder retriesExhaustedLogLevel(LoggingLevel retriesExhaustedLogLevel) { 115 getRedeliveryPolicy().setRetriesExhaustedLogLevel(retriesExhaustedLogLevel); 116 return this; 117 } 118 119 public DefaultErrorHandlerBuilder retryAttemptedLogLevel(LoggingLevel retryAttemptedLogLevel) { 120 getRedeliveryPolicy().setRetryAttemptedLogLevel(retryAttemptedLogLevel); 121 return this; 122 } 123 124 public DefaultErrorHandlerBuilder logStackTrace(boolean logStackTrace) { 125 getRedeliveryPolicy().setLogStackTrace(logStackTrace); 126 return this; 127 } 128 129 /** 130 * Sets whether the exchange should be marked as handled or not. 131 * 132 * @param handled handled or not 133 * @return the builder 134 */ 135 public DefaultErrorHandlerBuilder handled(boolean handled) { 136 Expression expression = ExpressionBuilder.constantExpression(Boolean.toString(handled)); 137 return handled(expression); 138 } 139 140 /** 141 * Sets whether the exchange should be marked as handled or not. 142 * 143 * @param handled predicate that determines true or false 144 * @return the builder 145 */ 146 public DefaultErrorHandlerBuilder handled(Predicate handled) { 147 this.setHandledPolicy(handled); 148 return this; 149 } 150 151 /** 152 * Sets whether the exchange should be marked as handled or not. 153 * 154 * @param handled expression that determines true or false 155 * @return the builder 156 */ 157 public DefaultErrorHandlerBuilder handled(Expression handled) { 158 this.setHandledPolicy(toPredicate(handled)); 159 return this; 160 } 161 162 /** 163 * Sets the logger used for caught exceptions 164 * 165 * @param logger the logger 166 * @return the builder 167 */ 168 public DefaultErrorHandlerBuilder logger(Logger logger) { 169 setLogger(logger); 170 return this; 171 } 172 173 /** 174 * Sets the logging level of exceptions caught 175 * 176 * @param level the logging level 177 * @return the builder 178 */ 179 public DefaultErrorHandlerBuilder loggingLevel(LoggingLevel level) { 180 getLogger().setLevel(level); 181 return this; 182 } 183 184 /** 185 * Sets the log used for caught exceptions 186 * 187 * @param log the logger 188 * @return the builder 189 */ 190 public DefaultErrorHandlerBuilder log(Log log) { 191 getLogger().setLog(log); 192 return this; 193 } 194 195 /** 196 * Sets the log used for caught exceptions 197 * 198 * @param log the log name 199 * @return the builder 200 */ 201 public DefaultErrorHandlerBuilder log(String log) { 202 return log(LogFactory.getLog(log)); 203 } 204 205 /** 206 * Sets the log used for caught exceptions 207 * 208 * @param log the log class 209 * @return the builder 210 */ 211 public DefaultErrorHandlerBuilder log(Class log) { 212 return log(LogFactory.getLog(log)); 213 } 214 215 /** 216 * Sets the exception policy to use 217 * 218 * @return the builder 219 */ 220 public DefaultErrorHandlerBuilder exceptionPolicyStrategy(ExceptionPolicyStrategy exceptionPolicyStrategy) { 221 setExceptionPolicyStrategy(exceptionPolicyStrategy); 222 return this; 223 } 224 225 /** 226 * Sets a processor that should be processed <b>before</b> a redelivey attempt. 227 * <p/> 228 * Can be used to change the {@link org.apache.camel.Exchange} <b>before</b> its being redelivered. 229 * 230 * @return the builder 231 */ 232 public DefaultErrorHandlerBuilder onRedelivery(Processor processor) { 233 setOnRedelivery(processor); 234 return this; 235 } 236 237 /** 238 * Will use the original input {@link org.apache.camel.Message} when an {@link org.apache.camel.Exchange} 239 * is moved to the dead letter queue. 240 * <p/> 241 * <b>Notice:</b> this only applies when all redeliveries attempt have failed and the {@link org.apache.camel.Exchange} 242 * is doomed for failure. 243 * <br/> 244 * Instead of using the current inprogress {@link org.apache.camel.Exchange} IN message we use the original 245 * IN message instead. This allows you to store the original input in the dead letter queue instead of the inprogress 246 * snapshot of the IN message. 247 * For instance if you route transform the IN body during routing and then failed. With the original exchange 248 * store in the dead letter queue it might be easier to manually re submit the {@link org.apache.camel.Exchange} 249 * again as the IN message is the same as when Camel received it. 250 * So you should be able to send the {@link org.apache.camel.Exchange} to the same input. 251 * <p/> 252 * By default this feature is off. 253 * 254 * @return the builder 255 */ 256 public DefaultErrorHandlerBuilder useOriginalMessage() { 257 setUseOriginalMessage(true); 258 return this; 259 } 260 261 // Properties 262 // ------------------------------------------------------------------------- 263 264 public Processor getFailureProcessor() { 265 return failureProcessor; 266 } 267 268 public void setFailureProcessor(Processor failureProcessor) { 269 this.failureProcessor = failureProcessor; 270 } 271 272 public RedeliveryPolicy getRedeliveryPolicy() { 273 if (redeliveryPolicy == null) { 274 redeliveryPolicy = createRedeliveryPolicy(); 275 } 276 return redeliveryPolicy; 277 } 278 279 /** 280 * Sets the redelivery policy 281 */ 282 public void setRedeliveryPolicy(RedeliveryPolicy redeliveryPolicy) { 283 this.redeliveryPolicy = redeliveryPolicy; 284 } 285 286 public Logger getLogger() { 287 if (logger == null) { 288 logger = createLogger(); 289 } 290 return logger; 291 } 292 293 public void setLogger(Logger logger) { 294 this.logger = logger; 295 } 296 297 /** 298 * Sets the exception policy strategy to use for resolving the {@link org.apache.camel.model.OnExceptionDefinition} 299 * to use for a given thrown exception 300 */ 301 public ExceptionPolicyStrategy getExceptionPolicyStrategy() { 302 return exceptionPolicyStrategy; 303 } 304 305 public void setExceptionPolicyStrategy(ExceptionPolicyStrategy exceptionPolicyStrategy) { 306 this.exceptionPolicyStrategy = exceptionPolicyStrategy; 307 } 308 309 public Processor getOnRedelivery() { 310 return onRedelivery; 311 } 312 313 public void setOnRedelivery(Processor onRedelivery) { 314 this.onRedelivery = onRedelivery; 315 } 316 317 public Predicate getHandledPolicy() { 318 if (handledPolicy == null) { 319 handledPolicy = createHandledPolicy(); 320 } 321 return handledPolicy; 322 } 323 324 public void setHandledPolicy(Predicate handled) { 325 this.handledPolicy = handled; 326 } 327 328 /** 329 * Sets the handled using a boolean and thus easier to use for Spring XML configuration as well 330 */ 331 public void setHandled(boolean handled) { 332 handled(handled); 333 } 334 335 public String getDeadLetterUri() { 336 return deadLetterUri; 337 } 338 339 public void setDeadLetterUri(String deadLetterUri) { 340 this.deadLetter = null; 341 this.deadLetterUri = deadLetterUri; 342 } 343 344 public Endpoint getDeadLetter() { 345 return deadLetter; 346 } 347 348 public void setDeadLetter(Endpoint deadLetter) { 349 this.deadLetter = deadLetter; 350 this.deadLetterUri = deadLetter.getEndpointUri(); 351 } 352 353 public boolean isUseOriginalMessage() { 354 return useOriginalMessage; 355 } 356 357 public void setUseOriginalMessage(boolean useOriginalMessage) { 358 this.useOriginalMessage = useOriginalMessage; 359 } 360 361 protected Predicate createHandledPolicy() { 362 // should NOT be handled by default for default error handler 363 return PredicateBuilder.toPredicate(ExpressionBuilder.constantExpression(false)); 364 } 365 366 protected RedeliveryPolicy createRedeliveryPolicy() { 367 RedeliveryPolicy policy = new RedeliveryPolicy(); 368 policy.disableRedelivery(); 369 policy.setRedeliverDelay(0); 370 return policy; 371 } 372 373 protected Logger createLogger() { 374 return new Logger(LogFactory.getLog(DefaultErrorHandler.class), LoggingLevel.ERROR); 375 } 376 377 @Override 378 public String toString() { 379 return "DefaultErrorHandlerBuilder"; 380 } 381 382 }