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.spring;
018
019import javax.xml.bind.annotation.XmlAccessType;
020import javax.xml.bind.annotation.XmlAccessorType;
021import javax.xml.bind.annotation.XmlAttribute;
022import javax.xml.bind.annotation.XmlElement;
023import javax.xml.bind.annotation.XmlRootElement;
024
025import org.apache.camel.LoggingLevel;
026import org.apache.camel.model.IdentifiedType;
027import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
028import org.apache.camel.spi.Metadata;
029
030/**
031 * Error handler settings
032 */
033@Metadata(label = "spring,configuration,error")
034@XmlRootElement(name = "errorHandler")
035@XmlAccessorType(XmlAccessType.FIELD)
036public class ErrorHandlerDefinition extends IdentifiedType {
037    @XmlAttribute @Metadata(defaultValue = "DefaultErrorHandler", required = true)
038    private ErrorHandlerType type = ErrorHandlerType.DefaultErrorHandler;
039    @XmlAttribute
040    private String deadLetterUri;
041    @XmlAttribute
042    private String deadLetterHandleNewException;
043    @XmlAttribute @Metadata(defaultValue = "ERROR")
044    private LoggingLevel level;
045    @XmlAttribute @Metadata(defaultValue = "WARN")
046    private LoggingLevel rollbackLoggingLevel;
047    @XmlAttribute
048    private String logName;
049    @XmlAttribute
050    private Boolean useOriginalMessage;
051    @XmlAttribute
052    private Boolean useOriginalBody;
053    @XmlAttribute
054    private String transactionTemplateRef;
055    @XmlAttribute
056    private String transactionManagerRef;
057    @XmlAttribute
058    private String onRedeliveryRef;
059    @XmlAttribute
060    private String onExceptionOccurredRef;
061    @XmlAttribute
062    private String onPrepareFailureRef;
063    @XmlAttribute
064    private String retryWhileRef;
065    @XmlAttribute
066    private String redeliveryPolicyRef;
067    @XmlAttribute
068    private String executorServiceRef;
069    @XmlElement
070    private CamelRedeliveryPolicyFactoryBean redeliveryPolicy;
071
072    public ErrorHandlerType getType() {
073        return type;
074    }
075
076    /**
077     * The type of the error handler
078     */
079    public void setType(ErrorHandlerType type) {
080        this.type = type;
081    }
082
083    public String getDeadLetterUri() {
084        return deadLetterUri;
085    }
086
087    /**
088     * The dead letter endpoint uri for the Dead Letter error handler.
089     */
090    public void setDeadLetterUri(String deadLetterUri) {
091        this.deadLetterUri = deadLetterUri;
092    }
093
094    public String getDeadLetterHandleNewException() {
095        return deadLetterHandleNewException;
096    }
097
098    /**
099     * Whether the dead letter channel should handle (and ignore) any new exception that may been thrown during sending the
100     * message to the dead letter endpoint.
101     * <p/>
102     * The default value is <tt>true</tt> which means any such kind of exception is handled and ignored. Set this to <tt>false</tt>
103     * to let the exception be propagated back on the {@link org.apache.camel.Exchange}. This can be used in situations
104     * where you use transactions, and want to use Camel's dead letter channel to deal with exceptions during routing,
105     * but if the dead letter channel itself fails because of a new exception being thrown, then by setting this to <tt>false</tt>
106     * the new exceptions is propagated back and set on the {@link org.apache.camel.Exchange}, which allows the transaction
107     * to detect the exception, and rollback.
108     */
109    public void setDeadLetterHandleNewException(String deadLetterHandleNewException) {
110        this.deadLetterHandleNewException = deadLetterHandleNewException;
111    }
112
113    public LoggingLevel getLevel() {
114        return level;
115    }
116
117    /**
118     * Logging level to use when using the logging error handler type.
119     */
120    public void setLevel(LoggingLevel level) {
121        this.level = level;
122    }
123
124    public LoggingLevel getRollbackLoggingLevel() {
125        return rollbackLoggingLevel;
126    }
127
128    /**
129     * Sets the logging level to use for logging transactional rollback.
130     * <p/>
131     * This option is default WARN.
132     */
133    public void setRollbackLoggingLevel(LoggingLevel rollbackLoggingLevel) {
134        this.rollbackLoggingLevel = rollbackLoggingLevel;
135    }
136
137    public String getLogName() {
138        return logName;
139    }
140
141    /**
142     * Name of the logger to use for the logging error handler
143     */
144    public void setLogName(String logName) {
145        this.logName = logName;
146    }
147
148    public Boolean getUseOriginalMessage() {
149        return useOriginalMessage;
150    }
151
152    /**
153     * Will use the original input {@link org.apache.camel.Message} (original body and headers) when an {@link org.apache.camel.Exchange}
154     * is moved to the dead letter queue.
155     * <p/>
156     * <b>Notice:</b> this only applies when all redeliveries attempt have failed and the {@link org.apache.camel.Exchange}
157     * is doomed for failure.
158     * <br/>
159     * Instead of using the current inprogress {@link org.apache.camel.Exchange} IN message we use the original
160     * IN message instead. This allows you to store the original input in the dead letter queue instead of the inprogress
161     * snapshot of the IN message.
162     * For instance if you route transform the IN body during routing and then failed. With the original exchange
163     * store in the dead letter queue it might be easier to manually re submit the {@link org.apache.camel.Exchange}
164     * again as the IN message is the same as when Camel received it.
165     * So you should be able to send the {@link org.apache.camel.Exchange} to the same input.
166     * <p/>
167     * The difference between useOriginalMessage and useOriginalBody is that the former includes both the original
168     * body and headers, where as the latter only includes the original body. You can use the latter to enrich
169     * the message with custom headers and include the original message body. The former wont let you do this, as its
170     * using the original message body and headers as they are.
171     * You cannot enable both useOriginalMessage and useOriginalBody.
172     * <p/>
173     * <b>Important:</b> The original input means the input message that are bounded by the current {@link org.apache.camel.spi.UnitOfWork}.
174     * An unit of work typically spans one route, or multiple routes if they are connected using internal
175     * endpoints such as direct or seda. When messages is passed via external endpoints such as JMS or HTTP
176     * then the consumer will create a new unit of work, with the message it received as input as the
177     * original input. Also some EIP patterns such as splitter, multicast, will create a new unit of work
178     * boundary for the messages in their sub-route (eg the splitted message); however these EIPs have
179     * an option named <tt>shareUnitOfWork</tt> which allows to combine with the parent unit of work in
180     * regard to error handling and therefore use the parent original message.
181     * <p/>
182     * By default this feature is off.
183     *
184     * @see #setUseOriginalBody(Boolean)
185     */
186    public void setUseOriginalMessage(Boolean useOriginalMessage) {
187        this.useOriginalMessage = useOriginalMessage;
188    }
189
190    public Boolean getUseOriginalBody() {
191        return useOriginalBody;
192    }
193
194    /**
195     * Will use the original input {@link org.apache.camel.Message} body (original body only) when an {@link org.apache.camel.Exchange}
196     * is moved to the dead letter queue.
197     * <p/>
198     * <b>Notice:</b> this only applies when all redeliveries attempt have failed and the {@link org.apache.camel.Exchange}
199     * is doomed for failure.
200     * <br/>
201     * Instead of using the current inprogress {@link org.apache.camel.Exchange} IN message we use the original
202     * IN message instead. This allows you to store the original input in the dead letter queue instead of the inprogress
203     * snapshot of the IN message.
204     * For instance if you route transform the IN body during routing and then failed. With the original exchange
205     * store in the dead letter queue it might be easier to manually re submit the {@link org.apache.camel.Exchange}
206     * again as the IN message is the same as when Camel received it.
207     * So you should be able to send the {@link org.apache.camel.Exchange} to the same input.
208     * <p/>
209     * The difference between useOriginalMessage and useOriginalBody is that the former includes both the original
210     * body and headers, where as the latter only includes the original body. You can use the latter to enrich
211     * the message with custom headers and include the original message body. The former wont let you do this, as its
212     * using the original message body and headers as they are.
213     * You cannot enable both useOriginalMessage and useOriginalBody.
214     * <p/>
215     * <b>Important:</b> The original input means the input message that are bounded by the current {@link org.apache.camel.spi.UnitOfWork}.
216     * An unit of work typically spans one route, or multiple routes if they are connected using internal
217     * endpoints such as direct or seda. When messages is passed via external endpoints such as JMS or HTTP
218     * then the consumer will create a new unit of work, with the message it received as input as the
219     * original input. Also some EIP patterns such as splitter, multicast, will create a new unit of work
220     * boundary for the messages in their sub-route (eg the splitted message); however these EIPs have
221     * an option named <tt>shareUnitOfWork</tt> which allows to combine with the parent unit of work in
222     * regard to error handling and therefore use the parent original message.
223     * <p/>
224     * By default this feature is off.
225     *
226     * @see #setUseOriginalMessage(Boolean)
227     */
228    public void setUseOriginalBody(Boolean useOriginalBody) {
229        this.useOriginalBody = useOriginalBody;
230    }
231
232    public String getTransactionTemplateRef() {
233        return transactionTemplateRef;
234    }
235
236    /**
237     * References to the {@link org.springframework.transaction.support.TransactionTemplate} to use with the transaction error handler.
238     */
239    public void setTransactionTemplateRef(String transactionTemplateRef) {
240        this.transactionTemplateRef = transactionTemplateRef;
241    }
242
243    public String getTransactionManagerRef() {
244        return transactionManagerRef;
245    }
246
247    /**
248     * References to the {@link org.springframework.transaction.PlatformTransactionManager} to use with the transaction error handler.
249     */
250    public void setTransactionManagerRef(String transactionManagerRef) {
251        this.transactionManagerRef = transactionManagerRef;
252    }
253
254    public String getOnRedeliveryRef() {
255        return onRedeliveryRef;
256    }
257
258    /**
259     * Sets a reference to a processor that should be processed <b>before</b> a redelivery attempt.
260     * <p/>
261     * Can be used to change the {@link org.apache.camel.Exchange} <b>before</b> its being redelivered.
262     */
263    public void setOnRedeliveryRef(String onRedeliveryRef) {
264        this.onRedeliveryRef = onRedeliveryRef;
265    }
266
267    public String getOnExceptionOccurredRef() {
268        return onExceptionOccurredRef;
269    }
270
271    /**
272     * Sets a reference to a processor that should be processed <b>just after</b> an exception occurred.
273     * Can be used to perform custom logging about the occurred exception at the exact time it happened.
274     * <p/>
275     * Important: Any exception thrown from this processor will be ignored.
276     */
277    public void setOnExceptionOccurredRef(String onExceptionOccurredRef) {
278        this.onExceptionOccurredRef = onExceptionOccurredRef;
279    }
280
281    public String getOnPrepareFailureRef() {
282        return onPrepareFailureRef;
283    }
284
285    /**
286     * Sets a reference to a processor to prepare the {@link org.apache.camel.Exchange} before
287     * handled by the failure processor / dead letter channel. This allows for example to enrich the message
288     * before sending to a dead letter queue.
289     */
290    public void setOnPrepareFailureRef(String onPrepareFailureRef) {
291        this.onPrepareFailureRef = onPrepareFailureRef;
292    }
293
294    public String getRetryWhileRef() {
295        return retryWhileRef;
296    }
297
298    /**
299     * Sets a reference to an retry while expression.
300     * <p/>
301     * Will continue retrying until expression evaluates to <tt>false</tt>.
302     */
303    public void setRetryWhileRef(String retryWhileRef) {
304        this.retryWhileRef = retryWhileRef;
305    }
306
307    public String getRedeliveryPolicyRef() {
308        return redeliveryPolicyRef;
309    }
310
311    /**
312     * Sets a reference to a {@link RedeliveryPolicy} to be used for redelivery settings.
313     */
314    public void setRedeliveryPolicyRef(String redeliveryPolicyRef) {
315        this.redeliveryPolicyRef = redeliveryPolicyRef;
316    }
317
318    public String getExecutorServiceRef() {
319        return executorServiceRef;
320    }
321
322    /**
323     * Sets a reference to a thread pool to be used by the error handler
324     */
325    public void setExecutorServiceRef(String executorServiceRef) {
326        this.executorServiceRef = executorServiceRef;
327    }
328
329    public CamelRedeliveryPolicyFactoryBean getRedeliveryPolicy() {
330        return redeliveryPolicy;
331    }
332
333    /**
334     * Sets the redelivery settings
335     */
336    public void setRedeliveryPolicy(CamelRedeliveryPolicyFactoryBean redeliveryPolicy) {
337        this.redeliveryPolicy = redeliveryPolicy;
338    }
339}