当前位置: 首页 > 知识库问答 >
问题:

如何在不停止应用程序的情况下使用驼峰路由或重新启动路由中的动态自

彭开畅
2023-03-14

我有现有的Spring Boot应用程序,它使用Camel框架从不同的文件夹获取数据。所有路由以类似的方式轮询数据:

from(fileUriWithCurrentDay(path, config.getParams())).routeId(ROUTE_ID)

其中,方法定义如下:

public static String fileUriWithCurrentDay(String path, Map<String, String> params) {
path = path.endsWith(SEPARATOR) ? path : path + SEPARATOR;
return "file:" + path + currentDayPath() + fileParams(params);
}

并根据日期返回类似的内容:

c:/test/data/2021/242?noop=true&idempotent=false&autoCreate=false&includeExt=xml&scheduler=spring&scheduler.cron = "0 0 13 ? * *"

cron设置为每天启动一次。当到达cron时间时,路由开始执行其工作并正确完成它。但是在第二天,它开始轮询同一个文件夹,例如242,但应该是243。

所以问题是:从endpoint开始应该在其开始时动态计算。

我在Camel中读过关于dynamic from:的文章,但没有发现任何信息表明这种选项是现成的。我尝试使用计算的头使用pollRich()选项,但它似乎不支持动态endpoint,因为返回下一个错误:

org.apache.camel.不允许使用${}占位符的动态表达式。使用fileName选项设置动态表达式。

路由启动后,如何刷新起始endpoint?

我也看到了两种可能的解决方案,但不知道它是否有用:

  1. 重新启动从endpointuri重新计算的路由。
  2. 重新启动整个Camel上下文。目前所有路由都标记为Spring@Component

共有2个答案

云承弼
2023-03-14

仅使用来自endpoint的URI无法查看File组件的留档。

我建议在URI中使用一个通用的基本目录并创建一个GenericFileFilter的实现,您可以将其与from-endpoint一起使用。它允许在实现哪些文件被处理和哪些文件未被处理的逻辑方面有很大的自由度。

要从base/path/2021读取文件,请创建如下内容:


@Component
public class FileFilter<T> implements GenericFileFilter<T> {
    @Override
    public boolean accept(GenericFile<T> file) {
        if (file.isDirectory()) {
            return "2021".equals(file.getFileName());
        }
        return file.getFileName().startsWith("2021/");
    }
}

endpointURI如下所示:

file://base/path?recursive=true

在实现GenericFileFilter时,您应该注意,目录也会调用accept()

湛博易
2023-03-14

与其他EIP组件不同,routeId和from endpoint中的字符串在创建路由后是固定的(除非使用另一个from endpoint url重新创建路由)。因此,有两个可能的前进方向。一种方法是使用new from endpoint url重新创建路由,另一种方法是在组件中查找参数以支持您的操作。

>

  • 在相同的CamelContext中使用相同的routeId重新创建消费者路由

    • 每天在行动下方触发(例如使用计时器路线)
    • 使用RouteBuilder构建路由配置(使用相同的用户路由id和新的来自endpointurl)
    • 使用带有新路由配置的CamelContext类的addRoutes方法重新创建路由

    利用文件组件中的过滤器目录

    • 设置文件路径到公共根文件夹(即c:/test/data
    • 启用递归查找子目录
    • 使用filterDirectory基于简单语言过滤目录
      • 从简单语言留档,简单语言的日期命令使用java.text.SimpleDateFormat
      • 从Oracle文档中,SimpleDateFormat确实支持年份和年份日(假设您的示例中的242和243是年份日)

      免责声明

      我以前没有使用过filterDirectory,方法2是从Camel文档推导出来的。

  •  类似资料:
    • 关于ApacheCamel的简短问题。我有以下场景,其中我的服务器接收jms消息,然后转换为csv文件,然后插入DB。为此,我有两个bean: xml2csv 我使用路由像: 当"路由"一个文件从-到,它是移动像一个消息?或者把问题放在不同的地方,ApacheCamel是否获取一个文件,将其包装为消息,并将其路由到bean或组件? 我的理解是正确的还是错误的。

    • 我有以下骆驼上下文XML。我设置了一个名为MediaType的标题。但是,当我在RenamerProcessor中设置断点时,我看不到标题(我也尝试过使用setProperty,但结果相同。我对Camel非常陌生,我发现了几个例子,似乎下面的例子应该可以使用。 怎么了?

    • 我有一个在 Openshift Online 启动器中运行的应用程序,该应用程序在过去 5 个月内一直有效。服务后面的单个 Pod,定义了执行边缘 tls 终止的路由。 自星期六以来,当尝试访问该应用程序时,我收到错误消息 应用程序不可用应用程序当前未在此endpoint上为请求提供服务。它可能尚未启动或仍在启动。 您看到此页面的可能原因: 主机不存在。确保正确键入了主机名,并且存在与此主机名匹配

    • 我有一个在Openshift 4.6中运行的应用程序。 pod正在运行,我可以执行它并检查它,我可以端口转发到它并访问它。 尝试访问应用程序时,我得到错误消息: 应用程序不可用应用程序当前未在此endpoint上为请求提供服务。它可能尚未启动或仍在启动。 您看到此页面的可能原因: 主机不存在。请确保键入的主机名正确,并且存在与该主机名匹配的路由。 主机存在,但没有匹配的路径。检查URL路径是否输入

    • 问题内容: 我需要在单页应用程序中检测页面刷新事件。 问题答案: 您不确定,因为刷新浏览器页面等同于退出应用程序然后再次打开它。 您可以做的是检测页面退出事件和应用程序打开事件。 在app.run()块中注入“窗口”依赖项并添加: 并在$ routeChangeStart事件上 而且如果绝对需要链接这两个事件,它必须在后端/服务器端..... 我希望这有帮助。

    • 问题内容: 我需要在 不更改URL的情况下 进行路由。 在自己实现此功能之前,我尝试过通过React Router寻找一些东西。我看到有这样一个东西 : createMemoryHistory([options]) createMemoryHistory创建一个不与浏览器URL交互的内存历史对象。当您需要自定义用于服务器端呈现,自动测试的历史记录对象或不想操纵浏览器URL(例如,将应用程序嵌入到i