2016-09-17 46 views
3

我有一个SFTP路由(在Spring XML中),它的路径以每日更改的目录(即./yyyyMMdd)结尾,并且当所有路径都在autoCreate=true或目录在路线开始时存在。但是如果不存在,我不允许创建目录!骆驼 - 当消费目录不存在时停止路由

当目录存在时,路由获取文件并自行终止。

当目录不存在时,路由将永久轮询并出现警告(即org.apache.camel.component.file.GenericFileOperationFailedException: Cannot change directory to: 20160917),并且永不停止。

如何避免此行为(例如,将警告转换为空的消息或异常或...)?我已经完成了对startingDirectoryMustExist,consumer.bridgeErrorHandler和其他许多项目的实验,但没有取得任何成功。

简化路线(开始前,填补了elmu.sftp.importDir属性与实际为准):

<from 
     uri="sftp://{{elmu.sftp.host}}:{{elmu.sftp.port}}{{elmu.sftp.importDir}}?username={{elmu.sftp.userName}}&amp;password={{elmu.sftp.password}}&amp; 
     autoCreate=false&amp;preferredAuthentications=password&amp;binary=true&amp;include={{elmu.importMask}}&amp;initialDelay=100&amp; 
     noop=true&amp;sortBy=file:name&amp;sendEmptyMessageWhenIdle=true"/> 
    <choice> 
     <when> 
      <simple>${body} != null</simple> 
      ... a lot of stuff ... 
      <to uri="bean:shutdownRoute" /> 
     </when> 
     <otherwise> 
      <to uri="bean:shutdownRoute" /> 
     </otherwise> 
    </choice> 

随着directoryMustExist=true and startingDirectoryMustExist=true结果是一个无限循环(调查)有这样的警告:

08:30:14,658 WARN SftpConsumer - Consumer Consumer[sftp://xxx.xxx.xx:22/DBHtest/ELMUteszt/Kiadott_adatok/20160918?autoCreate=false&binary=true&directoryMustExist=true&include=%5E.*%24&initialDelay=100&noop=true&password=xxxxxx&preferredAuthentications=password&sendEmptyMessageWhenIdle=true&sortBy=file%3Aname&startingDirectoryMustExist=true&username=xxx] failed polling endpoint: Endpoint[sftp://xxx:22/DBHtest/ELMUteszt/Kiadott_adatok/20160918?autoCreate=false&binary=true&directoryMustExist=true&include=%5E.*%24&initialDelay=100&noop=true&password=xxxxxx&preferredAuthentications=password&sendEmptyMessageWhenIdle=true&sortBy=file%3Aname&startingDirectoryMustExist=true&username=xxx]. Will try again at next poll. Caused by: [org.apache.camel.component.file.GenericFileOperationFailedException - Cannot change directory to: 20160918] 
org.apache.camel.component.file.GenericFileOperationFailedException: Cannot change directory to: 20160918 
    at org.apache.camel.component.file.remote.SftpOperations.doChangeDirectory(SftpOperations.java:576) 
    at org.apache.camel.component.file.remote.SftpOperations.changeCurrentDirectory(SftpOperations.java:564) 
    at org.apache.camel.component.file.remote.SftpConsumer.doPollDirectory(SftpConsumer.java:107) 
    at org.apache.camel.component.file.remote.SftpConsumer.pollDirectory(SftpConsumer.java:79) 
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:131) 
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:175) 
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:102) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) 
    at java.util.concurrent.FutureTask.runAndReset(Unknown Source) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: 2: No such file 
    at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846) 
    at com.jcraft.jsch.ChannelSftp._realpath(ChannelSftp.java:2340) 
    at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:342) 
    at org.apache.camel.component.file.remote.SftpOperations.doChangeDirectory(SftpOperations.java:574) 
    ... 13 more 

它不stepwise=false工作:

11:52:19,210 WARN SftpConsumer - Consumer Consumer[sftp://xxx:22/DBHtest/ELMUteszt/Kiadott_adatok/20160918?autoCreate=false&binary=true&directoryMustExist=true&include=%5E.*%24&initialDelay=100&noop=true&password=xxxxxx&preferredAuthentications=password&sendEmptyMessageWhenIdle=true&sortBy=file%3Aname&startingDirectoryMustExist=true&stepwise=false&username=xxx] failed polling endpoint: Endpoint[sftp://xxx:22/DBHtest/ELMUteszt/Kiadott_adatok/20160918?autoCreate=false&binary=true&directoryMustExist=true&include=%5E.*%24&initialDelay=100&noop=true&password=xxxxxx&preferredAuthentications=password&sendEmptyMessageWhenIdle=true&sortBy=file%3Aname&startingDirectoryMustExist=true&stepwise=false&username=xxx]. Will try again at next poll. Caused by: [org.apache.camel.component.file.GenericFileOperationFailedException - Cannot list directory: DBHtest/ELMUteszt/Kiadott_adatok/20160918] 
org.apache.camel.component.file.GenericFileOperationFailedException: Cannot list directory: DBHtest/ELMUteszt/Kiadott_adatok/20160918 

更新(根据@ ruffp的回答):

我试图设置一个自定义的PollingConsumerPollStrategy,但我不能阻止它的路线。只有第三条(注释行)停止路线,但我有几条路线,我不知道实际路线的名称。我怎么才能得到它?

@Override 
    public boolean rollback(Consumer consumer, Endpoint endpoint, int retryCounter, Exception cause) throws Exception { 
     consumer.getEndpoint().stop(); // 1 
     consumer.stop(); // 2 
     consumer.getEndpoint().getCamelContext().stopRoute(route???); // 3 
     return false; 
    } 
+1

你可以分享你的路线吗? –

+0

我已经分享了路线。 –

+0

您是否尝试添加directoryMustExist = true和startingDirectoryMustExist = true?添加它们之后,你能显示你得到的日志输出吗? –

回答

1

最后我和consumer.exceptionHandler解决它。但看起来,这个选项不在可用选项列表http://camel.apache.org/file2.html,我已经一次又一次地阅读),只是在巨大页面的底部提到了一个例子。不幸的是,它是如此“隐藏”,直到现在我错过了它。

我成立了一个新的类并实现了handleExceptions方法:

public class DirNotExistsExHandler implements ExceptionHandler 

其中获得异常,并决定该怎么做。在情况下,我做了一个bean定义:

<bean id="dirNotExistsExHandler" class="hu.dbit.eleo.DirNotExistsExHandler" /> 

而且在消费,通过豆到处理程序:

consumer.exceptionHandler=#dirNotExistsExHandler 

你的帮助非常感谢!

1

我认为做的最好的方式,它是:

  1. 启用选项throwExceptionOnConnectFailedsftp端点这样的:

    sftp://{{elmu.sftp.host}}:{{elmu.sftp.port}}{{elmu.sftp.importDir}}?username={{elmu.sftp.userName}}&amp;password={{elmu.sftp.password}}&amp; 
    autoCreate=false&amp;preferredAuthentications=password&amp;binary=true&amp;include={{elmu.importMask}}&amp;initialDelay=100&amp; 
    noop=true&amp;sortBy=file:name&amp;sendEmptyMessageWhenIdle=true&amp;throwExceptionOnConnectFailed=true 
    

    这可以帮助管理异常,并通过驼峰路由onException来捕获它。不过,我不确定这是否真的有必要在你的情况下。

  2. 生成特殊处理您的连接异常

    // 2a) Solution to redirect an empty body to a destination 
    onException(GenericFileOperationFailedException.class) 
          .handled(true) 
          .log(LoggingLevel.INFO, "Source directory not present: send empty body to shutdown route...") 
          .setBody(null) 
          .to("bean:shutdownRoute"); 
    

    或者另一种方式:

    // 2b)Solution to just stop the processing without log in warn or error 
    onException(GenericFileOperationFailedException.class) 
        .handled(true) 
        .log(LoggingLevel.INFO, "Source directory not present: stop the process and wait until next time...") 
        .stop(); 
    

更新: 我发现this post,显然没有其他的方式比实现你自己PollingConsumerPollStrategy,因为GenericFileOperationFailedException显然是在默认实现内处理的。

+0

谢谢,但不幸的是它不起作用,因为没有例外(在路线级别)。我认为,骆驼“赶上并翻译”异常,甚至警告“throwExceptionOnConnectFailed = true”。 –

+0

我已阅读你编辑过的文章,看来这是实现我的目标的可能方法。但不幸的是,它似乎非常困难(并且如果我可能会说不知所措),并且我不知道如何开始在xml(spring)中实现它。但我正在努力管理它。谢谢! –

+0

我已经更新了我原来的问题,请看看它。谢谢。 –

0

使用doCatch块处理异常。如果没有抛出异常,那么使用你的代码检查文件是否存在,并手动抛出异常。

http://camel.apache.org/try-catch-finally.html

+0

对不起,但我不明白你。你可以再详细一点吗?如何检查(和什么文件)的SFTP的存在?我的问题再次:我必须下载所有文件,并终止。但是,如果目录(结尾处的每日目录的完整路径)不存在,只需终止。 –

+0

我想当文件不在目的地时,会抛出一些异常,如FileNotFoundException。所以,仅仅捕获了异常和路线将遭到终止 –

+0

在你的情况下,使用: GenericFileOperationFailedException