【问题标题】:Apache Camel - Pass Filename from route1 to route2 which FTPsApache Camel - 将文件名从路由 1 传递到 FTP 的路由 2
【发布时间】:2016-08-23 01:30:08
【问题描述】:

我需要从 web 服务和 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 条路由并将 Route 1(“文件名”)的输出传递到 Route2 以进行 FTP?

【问题讨论】:

    标签: java apache-camel camel-ftp


    【解决方案1】:

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

    Camel 仅支持配置了起始目录的端点。所以 directoryName 必须是一个目录。如果您只想使用单个文件,则可以使用 fileName 选项,例如,通过设置 fileName=thefilename。 此外,起始目录不得包含带有 ${} 占位符的动态表达式。再次使用 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");
    

    或将 Route 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}")
    

    或更改 Route 2 的定义以仅拾取生成的文件:

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

    【讨论】:

    • 非常感谢您在这方面帮助我。一个后续问题。目前我正在检查filePathObj 并开始ftp-route。我想做route1的onCompletion。这是正确的做法吗。 exchange.addOnCompletion(new Synchronization() { @Override public void onComplete(Exchange exchange) { camelContext.addRoutes(ftpRouteBuilder); camelContext.startRoute("rmaftpRoute"); template.send("direct:ftp-send", exchange); }
    • 并非如此 - 您应该在添加和启动 ftpRouteBuilder 的同时添加 generateFileRoute。此外,这里不需要 onCompletion - direct 路由是同步的,这意味着当template.request 返回您的交换时,路由已经完成。但是不需要这么多的手动工作 - 您可以从您的第一条路线致电direct:ftp-send。只需在最后添加.to("direct:ftp-send")
    【解决方案2】:

    ftpRoute 不能简单地轮询 fileDirLoc 以获取新文件吗?

    【讨论】:

      【解决方案3】:

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

      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 和文件名。说一个实用方法或其他东西并在此处引用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-14
        相关资源
        最近更新 更多