Apache Camel:重用其他路由中的 Camel 路由的最佳方法是什么?

Áng*_*el 3 java spring apache-camel spring-boot

我正在尝试使用 routeContext 在同一个骆驼上下文中重用 Camel 路由,但我看到使用 onException、intercept、dataFormats 有一些限制,正如它在如何从其他 XML 文件导入路由中所述

另一种选择是使用许多 camelContext 和 vm-direct 端点来进行它们之间的通信,但是 Spring Boot 有一个仅限一个 camelContext 的限制。在这个替代方案中,我找到了这篇文章如何在 Spring Boot 应用程序中配置多个 Camel 上下文

有没有其他选择可以不受任何限制地共享路线?

Spring Boot Came 单个 configl xml 模型中不接受多骆驼上下文相关的问题

添加了更多信息

我想在一条大路线上建立一个完整的处理工作流程,其中有许多小路线,每条路线都有特定的任务要做。我更喜欢 XML DSL 而不是 Java 以便能够使用图形编辑器。

主要处理工作流将自动生成(不可修改),然后开发团队只需实现具有特定任务的小路由。一个必要条件是我必须使用 Spring Boot。

第一次尝试:一个 Camel 上下文并通过 routeContext 导入路由。使用直接端点来通信路由。

文件mainWorkFlow.xml

<!-- Import routerContexts-->
<import resource="tranformationIN_route.xml"/>
<import resource="tranformationOUT_route.xml"/>
<camelContext id="mainWorkFlow">        
    <!-- refer to custom routes -->
    <routeContextRef ref="tranformationIN"/>
    <routeContextRef ref="tranformationOUT"/>
    <route id="main">
        <from id="_inRequest" uri="cxf:bean:exposedWS"/>
        <to id="_validation" uri="inputData.xsd"/>
        <!-- Call route in another context for transformation data received to a backend service data model -->
        <to id="_toTransformationInRoute" uri="direct:appTransformationInRoute"/> 
        <!-- Call backend service -->
        <to id="_wsBE" uri="cxf:bean:backendWS"/>
        <!-- Call route in another context for transformation data from backend service response to exposed service data model -->
        <to id="_toTransformationOutRoute" uri="direct:appTransformationOutRoute"/>
    </route>
</camelContext>
Run Code Online (Sandbox Code Playgroud)

文件转换IN_route.xml

<routeContext ...>  
    <endpoint id="reqTrans" uri="dozer:...req_transformation.xml"/>
    <!--
        Declare dataFormats used by dozer           
    -->
    <dataFormats>
        <jaxb contextPath="some.package" id="someID"/>
    </dataFormats>
    <route id="tranformationIN">
        <from uri="direct:appTransformationInRoute"/>
        <to id="_to1" uri="ref:reqTrans"/>
    </route>
</routeContext>
Run Code Online (Sandbox Code Playgroud)

文件转换OUT_route.xml

<routeContext ...>  
    <endpoint id="reqTrans" uri="dozer:...resp_transformation.xml"/>
    <!--
        Declare dataFormats used by dozer           
    -->
    <dataFormats>
        <jaxb contextPath="some.package" id="someID"/>
    </dataFormats>
    <route id="tranformationOUT">
        <from uri="direct:appTransformationOutRoute"/>
        <to id="_to1" uri="ref:respTrans"/>
    </route>
</routeContext>
Run Code Online (Sandbox Code Playgroud)

看起来我们不能在 routeContext 中使用 dataFormats:

    Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: 
    Line 6 in XML document from class path resource [spring/custom-routes.xml] is invalid; 
    nested exception is org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 22; cvc-complex-type.2.4.a: Se ha encontrado contenido no válido a partir del elemento 'dataFormats'. 
    Se esperaba uno de '{"http://camel.apache.org/schema/spring":route}'...
Run Code Online (Sandbox Code Playgroud)

第二次尝试:许多 CamelContext。使用 direct-vm 端点来通信路由。

文件mainWorkFlow.xml

<camelContext id="mainWorkFlow">
    <route id="main">
        <from id="_inRequest" uri="cxf:bean:exposedWS"/>
        <to id="_validation" uri="inputData.xsd"/>
        <!-- Call route in another context for transformation data received to a backend service data model -->
        <to id="_toTransformationInRoute" uri="direct-vm:appTransformationInRoute"/> 
        <!-- Call backend service -->
        <to id="_wsBE" uri="cxf:bean:backendWS"/>
        <!-- Call route in another context for transformation data from backend service response to exposed service data model -->
        <to id="_toTransformationOutRoute" uri="direct-vm:appTransformationOutRoute"/>
    </route>
</camelContext>
Run Code Online (Sandbox Code Playgroud)

文件appContextTransformationIn_context.xml

<camelContext id="appContextTranformationIn">
    <endpoint id="reqTrans" uri="dozer:...req_transformation.xml"/>
    <!--
        Data forman generated automatically by dozer
        If necessary, here I could use dataFormat, onException and interceptor
    -->
     <dataFormats>
        <jaxb contextPath="some.package" id="someID"/>
    </dataFormats>
    <!--  -->
    <route id="tranformationIN">
        <from uri="direct-vm:appTransformationInRoute"/>
        <to id="_to1" uri="ref:reqTrans"/>
    </route>
</camelContext> 
Run Code Online (Sandbox Code Playgroud)

文件appContextTransformationOut_context.xml

<camelContext id="appContextTranformationOut">
    <endpoint id="reqTrans" uri="dozer:...resp_transformation.xml"/>
    <!--
        Data forman generated automatically by dozer
        If necessary, here I could use dataFormat, onException and interceptor
    -->
    <dataFormats>
        <jaxb contextPath="some.package" id="someID"/>
    </dataFormats>
    <route id="tranformationOUT">
        <from uri="direct-vm:appTransformationOutRoute"/>
        <to id="_to1" uri="ref:respTrans"/>
    </route>
</camelContext> 
Run Code Online (Sandbox Code Playgroud)

问题 Spring Bootk 不喜欢在其中运行多个camelcontext :/* Routes tranformationIN (appContextTranformationIn) 和 tranformationOUT (appContextTranformationOut) 将在一个camelContext 中,但Spring Boot 的问题是相同的。

bur*_*rki 6

您可以重用 Camel Context 中所有其他路由中的每条路由。这只是您的路线设计方式的问题

您可以在一条大路线上构建完整的处理工作流程。但是如果你构建第二个工作流,它就不能使用第一条路线的任何东西,它根本不能重用。

但是,如果您使用许多小路线构建相同的工作流,其中每条路线都有一个特定的任务要做,您可以构建第二个工作流,该工作流几乎可以使用第一个工作流的每个块。

通常,这些小路线如下所示:

from(direct:validation)
    .bean(...)
Run Code Online (Sandbox Code Playgroud)
  • 有一个direct端点可以从其他所有路由(同步)轻松调用它们
  • 他们只做一项任务
  • 它们没有to()“退出”,因为它们是请求/回复,因此它们在路由完成后返回给调用者

如果你像这样构建可重用的块,你可以从每个“主”路由调用它们。

from(...)
    .to("direct:validation")
    .to("direct:transform")
    .to("direct:enrich")
    ...
Run Code Online (Sandbox Code Playgroud)

ADDITION 由于更多信息有问题

为了您的第一次尝试:不能使用dataFormatrouteContext。您必须将其移动到 ,camelContext然后从routeContext.

来自Camel Docs 的片段:

注意:当您使用routeContext那么他们是分开的,而不能重用现有的onExceptioninterceptdataFormats和类似的跨部门在定义的功能camelContext。换句话说,routeContext当前是孤立的。

为了您的第二次尝试:如果您使用Spring启动,为什么坚持使用XML路线?图形编辑器可能不错,但是 Java 路由不存在您遇到的整个问题。Spring Boot 是从 Spring XML 配置转向 Java 配置的主要驱动力之一。

即使您坚持使用 Spring XML 配置,但用 Java 编写路由,也不会有问题。您可以轻松地将所有 RouteBuilder 导入 Camel Context。

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <routeBuilder ref="myMainRoute" />    
    <routeBuilder ref="mySpecificRoute1" />    
    <routeBuilder ref="mySpecificRoute2" />    
</camelContext>
Run Code Online (Sandbox Code Playgroud)