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