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: 905291 $
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(double 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 public DefaultErrorHandlerBuilder logRetryStackTrace(boolean logRetryStackTrace) {
130 getRedeliveryPolicy().setLogRetryStackTrace(logRetryStackTrace);
131 return this;
132 }
133
134 /**
135 * Sets whether the exchange should be marked as handled or not.
136 *
137 * @param handled handled or not
138 * @return the builder
139 */
140 public DefaultErrorHandlerBuilder handled(boolean handled) {
141 Expression expression = ExpressionBuilder.constantExpression(Boolean.toString(handled));
142 return handled(expression);
143 }
144
145 /**
146 * Sets whether the exchange should be marked as handled or not.
147 *
148 * @param handled predicate that determines true or false
149 * @return the builder
150 */
151 public DefaultErrorHandlerBuilder handled(Predicate handled) {
152 this.setHandledPolicy(handled);
153 return this;
154 }
155
156 /**
157 * Sets whether the exchange should be marked as handled or not.
158 *
159 * @param handled expression that determines true or false
160 * @return the builder
161 */
162 public DefaultErrorHandlerBuilder handled(Expression handled) {
163 this.setHandledPolicy(toPredicate(handled));
164 return this;
165 }
166
167 /**
168 * Sets the logger used for caught exceptions
169 *
170 * @param logger the logger
171 * @return the builder
172 */
173 public DefaultErrorHandlerBuilder logger(Logger logger) {
174 setLogger(logger);
175 return this;
176 }
177
178 /**
179 * Sets the logging level of exceptions caught
180 *
181 * @param level the logging level
182 * @return the builder
183 */
184 public DefaultErrorHandlerBuilder loggingLevel(LoggingLevel level) {
185 getLogger().setLevel(level);
186 return this;
187 }
188
189 /**
190 * Sets the log used for caught exceptions
191 *
192 * @param log the logger
193 * @return the builder
194 */
195 public DefaultErrorHandlerBuilder log(Log log) {
196 getLogger().setLog(log);
197 return this;
198 }
199
200 /**
201 * Sets the log used for caught exceptions
202 *
203 * @param log the log name
204 * @return the builder
205 */
206 public DefaultErrorHandlerBuilder log(String log) {
207 return log(LogFactory.getLog(log));
208 }
209
210 /**
211 * Sets the log used for caught exceptions
212 *
213 * @param log the log class
214 * @return the builder
215 */
216 public DefaultErrorHandlerBuilder log(Class<?> log) {
217 return log(LogFactory.getLog(log));
218 }
219
220 /**
221 * Sets the exception policy to use
222 *
223 * @return the builder
224 */
225 public DefaultErrorHandlerBuilder exceptionPolicyStrategy(ExceptionPolicyStrategy exceptionPolicyStrategy) {
226 setExceptionPolicyStrategy(exceptionPolicyStrategy);
227 return this;
228 }
229
230 /**
231 * Sets a processor that should be processed <b>before</b> a redelivey attempt.
232 * <p/>
233 * Can be used to change the {@link org.apache.camel.Exchange} <b>before</b> its being redelivered.
234 *
235 * @return the builder
236 */
237 public DefaultErrorHandlerBuilder onRedelivery(Processor processor) {
238 setOnRedelivery(processor);
239 return this;
240 }
241
242 /**
243 * Will use the original input {@link org.apache.camel.Message} when an {@link org.apache.camel.Exchange}
244 * is moved to the dead letter queue.
245 * <p/>
246 * <b>Notice:</b> this only applies when all redeliveries attempt have failed and the {@link org.apache.camel.Exchange}
247 * is doomed for failure.
248 * <br/>
249 * Instead of using the current inprogress {@link org.apache.camel.Exchange} IN message we use the original
250 * IN message instead. This allows you to store the original input in the dead letter queue instead of the inprogress
251 * snapshot of the IN message.
252 * For instance if you route transform the IN body during routing and then failed. With the original exchange
253 * store in the dead letter queue it might be easier to manually re submit the {@link org.apache.camel.Exchange}
254 * again as the IN message is the same as when Camel received it.
255 * So you should be able to send the {@link org.apache.camel.Exchange} to the same input.
256 * <p/>
257 * By default this feature is off.
258 *
259 * @return the builder
260 */
261 public DefaultErrorHandlerBuilder useOriginalMessage() {
262 setUseOriginalMessage(true);
263 return this;
264 }
265
266 // Properties
267 // -------------------------------------------------------------------------
268
269 public Processor getFailureProcessor() {
270 return failureProcessor;
271 }
272
273 public void setFailureProcessor(Processor failureProcessor) {
274 this.failureProcessor = failureProcessor;
275 }
276
277 public RedeliveryPolicy getRedeliveryPolicy() {
278 if (redeliveryPolicy == null) {
279 redeliveryPolicy = createRedeliveryPolicy();
280 }
281 return redeliveryPolicy;
282 }
283
284 /**
285 * Sets the redelivery policy
286 */
287 public void setRedeliveryPolicy(RedeliveryPolicy redeliveryPolicy) {
288 this.redeliveryPolicy = redeliveryPolicy;
289 }
290
291 public Logger getLogger() {
292 if (logger == null) {
293 logger = createLogger();
294 }
295 return logger;
296 }
297
298 public void setLogger(Logger logger) {
299 this.logger = logger;
300 }
301
302 /**
303 * Sets the exception policy strategy to use for resolving the {@link org.apache.camel.model.OnExceptionDefinition}
304 * to use for a given thrown exception
305 */
306 public ExceptionPolicyStrategy getExceptionPolicyStrategy() {
307 return exceptionPolicyStrategy;
308 }
309
310 public void setExceptionPolicyStrategy(ExceptionPolicyStrategy exceptionPolicyStrategy) {
311 this.exceptionPolicyStrategy = exceptionPolicyStrategy;
312 }
313
314 public Processor getOnRedelivery() {
315 return onRedelivery;
316 }
317
318 public void setOnRedelivery(Processor onRedelivery) {
319 this.onRedelivery = onRedelivery;
320 }
321
322 public Predicate getHandledPolicy() {
323 if (handledPolicy == null) {
324 handledPolicy = createHandledPolicy();
325 }
326 return handledPolicy;
327 }
328
329 public void setHandledPolicy(Predicate handled) {
330 this.handledPolicy = handled;
331 }
332
333 /**
334 * Sets the handled using a boolean and thus easier to use for Spring XML configuration as well
335 */
336 public void setHandled(boolean handled) {
337 handled(handled);
338 }
339
340 public String getDeadLetterUri() {
341 return deadLetterUri;
342 }
343
344 public void setDeadLetterUri(String deadLetterUri) {
345 this.deadLetter = null;
346 this.deadLetterUri = deadLetterUri;
347 }
348
349 public Endpoint getDeadLetter() {
350 return deadLetter;
351 }
352
353 public void setDeadLetter(Endpoint deadLetter) {
354 this.deadLetter = deadLetter;
355 this.deadLetterUri = deadLetter.getEndpointUri();
356 }
357
358 public boolean isUseOriginalMessage() {
359 return useOriginalMessage;
360 }
361
362 public void setUseOriginalMessage(boolean useOriginalMessage) {
363 this.useOriginalMessage = useOriginalMessage;
364 }
365
366 protected Predicate createHandledPolicy() {
367 // should NOT be handled by default for default error handler
368 return PredicateBuilder.toPredicate(ExpressionBuilder.constantExpression(false));
369 }
370
371 protected RedeliveryPolicy createRedeliveryPolicy() {
372 RedeliveryPolicy policy = new RedeliveryPolicy();
373 policy.disableRedelivery();
374 policy.setRedeliverDelay(0);
375 return policy;
376 }
377
378 protected Logger createLogger() {
379 return new Logger(LogFactory.getLog(DefaultErrorHandler.class), LoggingLevel.ERROR);
380 }
381
382 @Override
383 public String toString() {
384 return "DefaultErrorHandlerBuilder";
385 }
386
387 }