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}