Camel如何动态添加和启动路由?

我正在尝试从 Camel 的路线中删除一些样板.

I'm trying to remove some boilerplate from routes in Camel.

例如,让我们考虑两条路线,它们相似并且可以生成它们的大部分内部内容.我创建了一个组件模板",它创建 TemplateEndpoint,并修改了 XML 配置以使用模板组件.

For example, let's consider the two routes, which are similar and most of their inner stuff could be generated. I've created a component "template", which creates TemplateEndpoint, and modifyed an XML config to use the template component.

正在从 StartupListener(在 TemplateEndpoint.setSuffix 中定义)调用自定义方法 TemplateEndpoint.generateRoute(添加路由定义).因此,当 Camel 上下文启动时,路由定义会出现在上下文中,但框架不会为它们创建路由服务,因此它们不会启动.

A custom method TemplateEndpoint.generateRoute (adding route definitions) is being called from StartupListener (defined in TemplateEndpoint.setSuffix). So while Camel context starting, route definitions appear in the context, but the framework doesn't create route services for them and hence they don't get started.

StartupListener中添加的路由如何启动?

How to start routes added in StartupListener?

可能我遇到了 XY 问题,您可以建议我一个更好的方法来解决这个问题(即即时添加和启动路线).

类似的两条路线

<route id="route_A">
  <from uri="restlet:/another1?restletMethods=GET" />
  <to uri="first:run_A" />
  <to uri="second:jump_A" />     
  <to uri="third:fly_A" />
</route>

<route id="route_B">
  <from uri="restlet:/another2?restletMethods=GET" />
  <to uri="first:run_B" />
  <to uri="second:jump_B" />     
  <to uri="third:fly_B" />
</route>

修改后的 XML

<route id="route_A">
  <from uri="restlet:/another1?restletMethods=GET" />
  <to uri="template://?suffix=A" />
</route>

<route id="route_B">
  <from uri="restlet:/another2?restletMethods=GET" />
  <to uri="template://?suffix=B" />
</route>

端点

public class TemplateEndpoint extends DefaultEndpoint {

  /* some methods omitted */ 
  // this endpoint creates a DefaultProducer, which does nothing

  public void setSuffix(final String suffix) throws Exception {

    this.getCamelContext().addStartupListener(new StartupListener() {
      @Override
      public void onCamelContextStarted(CamelContext context, boolean alreadyStarted) throws Exception {       
        generateRoute(suffix)
        .addRoutesToCamelContext(context);
      }
    });
  }

  private RouteBuilder generateRoute(final String suffix){ 
     final Endpoint endpoint = this;

     return new RouteBuilder() {
        @Override
        public void configure() throws Exception {
          from(endpoint)
           .to("first:run_" + suffix)
           .to("second:jump_" + suffix)
           .to("third:fly_" + suffix);
       }
  }
}

推荐答案

我会创建一个动态路由构建器,例如

I would create a dynamic route builder e.g.

public class MyRouteBuilder extends RouteBuilder {

            private String another;
            private String letter;

            public MyRouteBuilder(CamelContext context,String another, String letter) {
                super(context);
                this.another=another;
                this.letter=letter;
            }

            @Override
            public void configure() throws Exception {
                super.configure();
                from("restlet:/"+another+"?restletMethods=GET")
                .to("first:run_"+letter)
                .to("second:jump_"+letter)
                .to("third:fly_"+letter);
            }
    }

并将其添加到某些事件中,例如

and add it on some event e.g

public class ApplicationContextProvider implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext context)
            throws BeansException {

        camelContext=(CamelContext)context.getBean("mainCamelContext");
        camelContext.addRoutes(new MyRouteBuilder(camelContext, "another1","A"));
        camelContext.addRoutes(new MyRouteBuilder(camelContext, "another2","B"));

..

相关文章