Apache Camel - 将文件名从 route1 传递到 FTP 的 route2

Apache Camel - Pass Filename from route1 to route2 which FTPs

我需要从网络服务生成文件并 FTP 到某个位置。

路线 1:

from("direct:start")
    .routeId("generateFileRoute")
    .setHeader(Exchange.HTTP_METHOD, constant("GET"))
    .setHeader(Exchange.HTTP_URI, simple(URL))
    .setHeader("Authorization", simple(APP_KEY))
    .to(URL)
    .unmarshal(listJacksonDataFormat)
    .marshal(bindyCsvDataFormat)
    .to(fileDirLoc + "?fileName=RMA_OUT_${date:now:MMddyyyy_HHmmss}.csv&noop=true");  

路线 2:FTP路线

from("file://"+header("CamelFileNameProduced"))
    .routeId("ftpRoute")
    .to("sftp://FTP_HOST/DIR?username=???&password=???)

开始路线

Exchange exchange = template.request("direct:start", null);

Object filePathObj = exchange.getIn().getHeader("CamelFileNameProduced");

if (filePathObj != null) { // Makesure Route1 has created the file
    camelContext.startRoute("ftpRoute");     // Start FTP route
    template.send(exchange); // Send exchange from Route1 to Route2
}

当我在 FTP 路线中硬编码位置时,上面的代码有效。 有人可以帮忙吗,我如何通过管道将这 2 条路线("File Name")的输出传递给路线 2 以获得 FTP?

ftpRoute 不能简单地为新文件轮询 fileDirLoc 吗?

您不能将 headers 传递给 file 端点,它不能那样工作。此外,from("file://...") 不能在其路径中包含动态值,即任何类型的占位符,这里引用 official Camel documentation:

Camel supports only endpoints configured with a starting directory. So the directoryName must be a directory. If you want to consume a single file only, you can use the fileName option e.g., by setting fileName=thefilename. Also, the starting directory must not contain dynamic expressions with ${} placeholders. Again use the fileName option to specify the dynamic part of the filename.

如果您不进行任何额外的 CSV 文件处理,我的建议是直接发送至 FTP:

from("direct:start")
    .routeId("generateFileRoute")
    .setHeader(Exchange.HTTP_METHOD, constant("GET"))
    .setHeader(Exchange.HTTP_URI, simple(URL))
    .setHeader("Authorization", simple(APP_KEY))
    .to(URL)
    .unmarshal(listJacksonDataFormat)
    .marshal(bindyCsvDataFormat)
    .to("sftp://FTP_HOST/DIR?username=???&password=??&fileName=RMA_OUT_${date:now:MMddyyyy_HHmmss}.csv");

或将路线 2 定义从 file 更改为 direct:

from("direct:ftp-send")
    .routeId("ftpRoute")
    .pollEnrich("file:destination?fileName=${headers.CamelFileNameProduced}")
    .to("sftp://FTP_HOST/DIR?username=???&password=??&fileName=${headers.CamelFileName}")

或更改路由 2 的定义以仅提取生成的文件:

from("file://" + fileDirLoc + "?antInclude=RMA_OUT_*.csv")
    .routeId("ftpRoute")
    .to("sftp://FTP_HOST/DIR?username=???&password=???)

有一个解决方法,你可以尝试将它们结合起来:

from("direct:start")
    .routeId("generateFileRoute")
    .setHeader(Exchange.HTTP_METHOD, constant("GET"))
    .setHeader(Exchange.HTTP_URI, simple(URL))
    .setHeader("Authorization", simple(APP_KEY))
    .to(URL)
    .unmarshal(listJacksonDataFormat)
    .marshal(bindyCsvDataFormat)
    .to(fileUri.getUri())
    .setHeader(Exchange.FILE_NAME, file.getName())
    .to("sftp://FTP_HOST/DIR?username=???&password=???);

是的,您不能在文件 uri 中包含动态表达式,但您可以在其他地方生成 uri 和文件名。说个实用方法什么的,这里参考一下。