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 }