Apache camel ftp使用者异常后聚合:FatalFallbackErrorHandler
我的驼峰路由尝试从sftp中提取一些文件,将它们传输到网络,然后从sftp中删除它们。如果3次尝试后无法访问sftp,我希望路由发送一封电子邮件,警告管理员该问题 因此,我的sftp地址具有以下参数:Apache camel ftp使用者异常后聚合:FatalFallbackErrorHandler,apache-camel,sftp,Apache Camel,Sftp,我的驼峰路由尝试从sftp中提取一些文件,将它们传输到网络,然后从sftp中删除它们。如果3次尝试后无法访问sftp,我希望路由发送一封电子邮件,警告管理员该问题 因此,我的sftp地址具有以下参数: maximumReconnectAttempts=2&throwExceptionOnConnectFailed=true&consumer.bridgeErrorHandler=true 如果网络位置不可用,我希望路由通知管理员并不从sftp中删除文件。 因此,我在OneExc
maximumReconnectAttempts=2&throwExceptionOnConnectFailed=true&consumer.bridgeErrorHandler=true
如果网络位置不可用,我希望路由通知管理员并不从sftp中删除文件。
因此,我在OneException中设置了.handled(false)
然而,当连接到sftp失败时,聚合也会失败,并且没有电子邮件出现。我在下面举了一个极简主义的例子:
/configure
onException(Throwable.class)
.retryAttemptedLogLevel(LoggingLevel.WARN)
.redeliveryDelay(1000)
.handled(false)
.log(LoggingLevel.ERROR, LOG, "XXX - Error moving files")
.to(AGGREGATEROUTE)
.end();
from(downloadFrom)
.to(to)
.log(LoggingLevel.INFO, LOG, "XXX - Moving file OK")
.to(AGGREGATEROUTE);
from(AGGREGATEROUTE)
.log(LoggingLevel.INFO, LOG, "XXX - Starting aggregation.")
.aggregate(constant(true), new GroupedExchangeAggregationStrategy())
.completionFromBatchConsumer()
.completionTimeout(10000)
.log(LoggingLevel.INFO, LOG, "XXX - Aggregation completed, sending mail.");
在日志中,我看到:
16:02| ERROR | CamelLogger.java 156 | XXX - Error moving files
然后查看连接期间发生的异常的日志
然后这个:
16:02| ERROR | FatalFallbackErrorHandler.java 174 | Exception occurred while trying to handle previously thrown exception on exchangeId: ID-LP0641-1552662095664-0-2 using: [Pipeline[[Channel[Log(proefjes.camel_cursus.routebuilders.MoveWithPickupExceptions)[XXX - Error moving files]], Channel[sendTo(direct://aggregate)]]]].
16:02| ERROR | FatalFallbackErrorHandler.java 172 | \--> New exception on exchangeId: ID-LP0641-1552662095664-0-2
org.apache.camel.component.file.GenericFileOperationFailedException: Cannot connect to sftp://user@mycompany.nl:22
at org.apache.camel.component.file.remote.SftpOperations.connect(SftpOperations.java:149)
我没有在日志中看到“XXX-正在启动聚合”。聚合之前是否发生了某种错误?聚合(*,*)上的断点从未到达。首先,我只想澄清一些事情。你写“如果网络位置不可用,我希望路由通知管理员,而不是从sftp中删除文件”,但这不是显而易见的吗?我的意思是,如果网络位置不可用,那么从sftp中删除文件不是不可能的吗 异常处理程序也将
路由到(AGGREGATEROUTE)
,这有点令人困惑。如果你想给管理员发电子邮件,那不应该在异常处理程序中,而不是在快乐路径中吗?为什么要以及如何“聚合”连接失败
最后,我认为您的实现存在一个真正的问题,您可能误解了处理(false)
的功能。将此设置为false意味着路由应该停止并传播返回给调用方的异常。我不确定在这种情况下必须使用.to(AGGREGATEROUTE)
做什么,但我并不奇怪它没有被调用
我建议尝试一些东西。我没有你的代码,所以我不确定哪一个最好。这些都是相关的,任何方法都可能奏效:
- 将
更改为handled(false)
handled(true)
- 用
替换continued(true)
handled
- 使用死信频道
//configure exception on sft end
onException(Throwable.class)
.maximumRedeliveries(2)
.retryAttemptedLogLevel(LoggingLevel.WARN)
.redeliveryDelay(1000)
.onWhen(new hasSFTPErrorPredicate())
// .continued(true) // tries to connect once, mails and continues to aggregation with empty exchange
//.handled(false) // tries to connect twice but does not reach mail
.handled(true) // tries to connect once, does reach mail
// handled not defined: tries to connect twice but does not reach mail
.log(LoggingLevel.INFO, LOG, "XXX - SFTP exception")
.to(MAIL_ROUTE)
.end();
// exception anywhere else
onException(Throwable.class)
.maximumRedeliveries(2)
.retryAttemptedLogLevel(LoggingLevel.WARN)
.redeliveryDelay(1000)
.log(LoggingLevel.ERROR, LOG, "XXX - Error moving file ${file:name}: ${exception}")
.to(AGGREGATEROUTE)
.handled(false)
.end();
在sftp端发生的异常在第一个OneException中处理,因为在那里HassftPerorPredicate返回“true”。该谓词所做的只是检查消息中是否存在异常或其原因为“无法连接到sftp:”。
在这种情况下不需要回滚,因为还没有发生任何事情
任何其他异常都由第二个OneException处理。任何一端都可能不可用,如果to端点不可用,我希望回滚,因此我已处理(错误),我更喜欢聚合,因此我不会为无法传递的每个文件都收到电子邮件。在任何情况下,我都不想接受异常,据我所知,handled(true)就是这样做的。我可以继续,但如何确保不删除任何文件?