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