0

在我的一个用例中,我将所有路由信息都保存在一个 json 文件中,我想读取该文件并相应地创建路由。

例如,

如果我在我的 json 配置文件中声明了这样的路由

{
  "config": [
    {
      "routeSrcSystem": "System1",
      "routes": [
        {
          "fromRoute": {
            "type": "default",
            "typeValue": "direct:CMStart"
            },  
          "toRoute": {
            "type": "http"
            "typeMethod": "POST",
            "typeContent": "application/json",
            "typeValue": "http://localhost:8080/v1/System1/inboundMessage"
            }
        }
      ]
    }
  ]
}

然后我能够动态地创建如下路线。但是在这里,尽管它是动态的,但路由定义不是动态的,因为我使用了一个“from”和一个“to”定义,但是这个定义的参数我是动态传递的。

public class GenerateRouter extends RouteBuilder {

        private RoutesMetadata routesMetadata;

        public GenerateRouter(CamelContext context,RoutesMetadata routesMetadata) {
            super(context);
            this.routesMetadata=routesMetadata;
        }

        @Override
        public void configure() throws Exception {
            from(routesMetadata.getFromRoute().getTypeValue())
            .setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
            .setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
            .to(routesMetadata.getToRoute().getTypeValue());
        }
    }

但我想动态地做路由定义。例如,我有这样的路由配置,

{
  "config": [
    {
      "routeSrcSystem": "System1",
      "routes": [
        {
          "fromRoute": {
            "type": "default",
            "typeValue": "direct:CMStart"
            },  
          "toRoute1": {
            "type": "http"
            "typeMethod": "POST",
            "typeContent": "application/json",
            "typeValue": "http://localhost:8080/v1/System1/inboundMessage"
            }
         "toRoute2": {
            "type": "http"
            "typeMethod": "POST",
            "typeContent": "application/json",
            "typeValue": "http://localhost:8080/v1/System2/inboundMessage"
            }
        }
      ]
    }
  ]
}

然后在我的路由定义中,我需要动态添加一个“到”定义。它只是一个例子。它可能更具活力。例如,可以更改配置以引入“进程”或“bean”或“类”定义。所以根据配置,我们需要决定要创建多少个“to”以及要创建多少个“process”等等。我可能需要在一些验证等之后调用下一个休息端点,有时我需要调用 kafka 将消息放入队列。我确实看到了一个在列表中列出所有路由并执行它的选项,但我认为我们需要在调用下一个端点之前灵活地添加进程或类定义,这必须基于配置。

public class GenerateRouter extends RouteBuilder {

        private RoutesMetadata routesMetadata;

        public GenerateRouter(CamelContext context,RoutesMetadata routesMetadata) {
            super(context);
            this.routesMetadata=routesMetadata;
        }

        @Override
        public void configure() throws Exception {
            from(routesMetadata.getFromRoute().getTypeValue())
            .setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
            .setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
            .to(routesMetadata.getToRoute().getTypeValue())
            .setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
            .setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
            .to(routesMetadata.getToRoute().getTypeValue());
        }
    }

我看到了一些可以动态定义路由定义本身的信息,我正在研究它。但同时我想在这里发布这个以获得专家的意见。另外,请建议我是否以正确的方式使用骆驼?因为在我的用例中,我正在考虑添加“to”定义,根据配置文件动态传递类名,以便应用程序开发人员可以在交付到目标之前动态地在此类中执行转换、丰富或操作的逻辑系统。如果我们有更好的方法,请告诉我。另外,让我知道 XML 的做法是好方法还是以 json 格式定义自己的配置文件是创建动态路由的好方法。

我打算读取 json 文件并将路由器定义动态地创建为字符串。但我需要将此字符串加载为上下文中的定义。我想我错过了这部分。

.to("class:com.xxx.camel.layoutTransform?method=layout()")

如果我们在 xml 文件中提供所有这些配置,并且如果 camel 支持使用该文件自动创建路由定义,那么我们也可以考虑这个选项。

下面是从另一个来源使用 XML 文件创建路由器定义的一种方法。在 XML 中,我们定义了路由器信息,并将此 xml 视为字符串,并将此字符串转换为路由器定义对象,最后添加到上下文中。

<routes
  xmlns=\"http://camel.apache.org/schema/spring\">
  <route>
      <from uri='direct:c'/>
      <to uri='mock:d'/>
  </route>
</routes>
CamelContext context = new DefaultCamelContext(); 
context.setTracing(true); 
String xmlString = "<routes  xmlns=\"http://camel.apache.org/schema/spring\"><route><from uri='direct:c'/><to uri='mock:d'/></route></routes>"; 

InputStream is = new ByteArrayInputStream(xmlString.getBytes()); 
RoutesDefinition routes = context.loadRoutesDefinition(is); 
context.addRouteDefinitions(routes.getRoutes()); 

context.start(); 

ProducerTemplate template = null; 
template = context.createProducerTemplate(); 
template.start(); 
template.sendBody("direct:c", "HelloC"); 
Thread.sleep(10000); 
context.stop();

我想使用 java dsl 定义作为字符串来做类似的概念。

例如,如果我有如下字符串,那么可以将其转换为路由器定义吗?

String dslString = "from("direct:starting").to("seda:end")";

这是我的用例。有时,我们想调用 2 个 http 服务,如下所示

from("direct:start").to( http://localhost:8080/service1).to (" http://localhost:8080/service2 ")

有时我们可能需要调用 3 个服务,如下所示

from("direct:start").to( http://localhost:8080/service1).to (" http://localhost:8080/service2 ").to(" http://localhost :8080/service3 " )

有时我们需要在调用 service2 之前进行转换,如下所示。

from("direct:start").to( http://localhost:8080/service1).to ("class:com.xxx.yyy").to(" http://localhost:8080/service2 ")。 to(" http://localhost:8080/service3 ")

在偶数驱动架构中,我们必须为每种事件类型定义一组路由。所以想法是,如果我们在表中为每种事件类型定义这些路由,那么在服务启动时,所有路由都将在上下文中加载并启动。我能够以 XML DSL 方式做同样的事情,但尝试在 java DSL 中做同样的事情。

提前致谢!

4

1 回答 1

2

Camel 支持以特定的基于 XML 的格式定义有关路由的所有详细信息。此页面包含指向该(和其他)DSL 的链接。

您绝对可以提出自己的 DSL 并动态构建路由,但如果您想支持完整的 Camel DSL 将支持的所有内容,那就需要做很多工作。无论您的用例如何,我都怀疑这不是正确的解决方案。

如果您的路线有某些模式,您可以创建由某些配置驱动的相当动态的 Camel 路线构建器。具体来说,假设您有许多遵循非常相似的模式的用例......比如说,来自文件夹中文件的消费者数据,从(比如说)10-15 转换的菜单中进行一些转换,然后发送输出到多个队列之一。

由于您有各种可能的组合,因此在文件等中配置这些详细信息然后构建一些路由可能是有意义的。权衡与任何其他地方没有什么不同,在这些地方你必须决定是只编写你想要的 10 件事更清楚,还是让一些更复杂但通用的东西更清晰。

本质上,您仍然会创建一个 DSL 或排序,但它更接近您的用例。

于 2019-05-17T02:30:49.803 回答