Apache Camel:路由继承 - 将代码移动到超级 class

Apache Camel: routes inheritance - moving code to the super class

我有以下 supercalss BaseRouteBuilder,我在其中处理常见异常。我所有的路线都扩展了这个 class 1234Route extends BaseRouteBuilder。在我所有的路线中,我最后都会调用一个 http 请求来创建订单,并且我正在使用一种格式将其转换为 JSON。是否可以在 apache Camel 中将格式和此条件移动到 supercass BaseRouteBuilder?

.marshal(format)
.setHeader(
    Exchange.HTTP_METHOD, 
    constant(org.apache.camel.component.http.HttpMethods.POST)
)
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.to("http://localhost:8080/orders/create-order")

**超级class - BaseRouteBuilder **

@Component
public class BaseRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        //@formatter:off
        onException(Exception.class).process(new Processor() {

            public void process(Exchange exchange) throws Exception {
              //Coding to enrich the exception error
            }
        })
        
        .handled(true)
        .to("activemq:queue:dead-messages");
        
        //@formatter:on

    }

}

**Subclass - 1234Route

@Component
public class 1234Route extends BaseRouteBuilder {

    @Override
    public void configure() throws Exception {

        super.configure();

        JacksonDataFormat format = new JacksonDataFormat();
        format.useList();
        format.setUnmarshalType(DataBase.class);

        //@formatter:off
        from("activemq:queue:1234")
            // my route coding (I have deleted it)
            //.setHeader()
            //.process
            //.bean()

            //This is the common coding I want to move it to the super class.
            .marshal(format)
            .setHeader(
                Exchange.HTTP_METHOD, 
                constant(
                    org.apache.camel.component.http.HttpMethods.POST
                )
            )
            .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
            .to("http://localhost:8080/orders/create-order");
        //@formatter:on
    }

}

RouteBuilder 像其他任何东西一样支持继承 class,因为 onException 是 RouteBuilder 的作用域,所以可以在基础 class 中定义它。然而,我会建议反对或至少在像 BaseRouteBuilder 这样的东西中定义路由时要非常小心。

你还应该将 BaseRouteBuilder 标记为抽象,我也会尝试给它起一个更具描述性的名称,例如 RouteBuilderWithGenericErrorHandler。

RouteBuilder 用于创建 RouteDefinitions 并将其添加到 CamelContext 中,您不仅限于使用一个 RouteBuilder。现在,如果您向 CamelContext 添加多个 RouteBuilder,它们都继承自 BaseRouteBuilder ,这将导致 BaseRouteBuilder.configure 被多次调用。

这可能会导致如下问题:

  • RouteId 冲突。
  • 消费者终结点 URI 冲突。
  • 多次应用相同的配置更改。
    • 即如果您使用 RouteBuilder.getContext 以某种方式修改 CamelContext。

In all my route I am calling at the end a http request to create the order and I am using a format to convert it to JSON.

如果您的许多路由共享相同的路由逻辑,您应该将该部分拆分为单独的路由并像函数一样使用它。它还可以更轻松地添加 route-scope 错误处理,例如当订单 api 没有响应或提供给 direct:createOrder 消费者端点的正文无效时该怎么做。

@Override
public void configure() throws Exception {
    
    from("direct:createOrderA")
        .routeId("createOrderA")
        // .. do stuff for A
        .to("direct:createOrder");
    
    from("direct:createOrderB")
        .routeId("createOrderB")
        // .. do stuff for B
        .to("direct:createOrder");
    
    
    DataFormat format = ...;

    from("direct:createOrder")
        .routeId("createOrder")
        .marshal(format)
        .setHeader(
            Exchange.HTTP_METHOD, 
            constant(org.apache.camel.component.http.HttpMethods.POST)
        )
        .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
        .to("http://localhost:8080/orders/create-order");
        
}