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 jakarta.xml.bind.annotation.XmlAccessType; 020import jakarta.xml.bind.annotation.XmlAccessorType; 021import jakarta.xml.bind.annotation.XmlAttribute; 022import jakarta.xml.bind.annotation.XmlElement; 023import jakarta.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 SpringErrorHandlerDefinition extends IdentifiedType { 037 @XmlAttribute 038 @Metadata(defaultValue = "DefaultErrorHandler", required = true) 039 private SpringErrorHandlerType type = SpringErrorHandlerType.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 SpringErrorHandlerType getType() { 076 return type; 077 } 078 079 /** 080 * The type of the error handler 081 */ 082 public void setType(SpringErrorHandlerType 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}