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

13

我正在尝试从Camel路由中删除一些样板代码。

例如,考虑这两个路由,它们非常相似,它们的大部分内部内容可以生成。我创建了一个名为“template”的组件,它创建TemplateEndpoint,并修改了XML配置以使用模板组件。

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

如何启动在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);
       }
  }
}
1个回答

14

我将创建一个动态路由生成器,例如:

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);
            }
    }

并将其添加到某些事件(例如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"));

..

嘿,这个例子真的很好。我在实现它时遇到了一些问题。 - Sam Berchmans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接