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

时间:2018-06-12 13:26:30

标签: java spring spring-boot apache-camel

我正在尝试使用routeContext在同一个camelContext中重用Camel路由,但我发现使用onException,intercept,dataFormats存在限制,如How do I import routes from other XML files所述

另一种选择是使用许多camelContext和vm-direct端点进行通信,但是只有一个带有Spring Boot的camelContext有限制。在这个替代方案中,我发现了这篇文章How to configure multiple Camel Contexts in the Spring Boot application

还有其他方法可以在没有任何限制的情况下共享路线吗?

Multiple camel context not accepted in Spring Boot Came single configl xml model ?

相关的问题

添加了更多信息

我希望在一条大路线上建立一个完整的处理工作流程,其中包含许多小路线,其中每条路线都有特定的任务要做。我更喜欢使用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>

文件 tranformationIN_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>

文件 tranformationOUT_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>

看起来我们不能在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}'...

第二次尝试:许多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>

文件 appContextTranformationIn_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> 

文件 appContextTranformationOut_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> 

问题     Spring Bootk不喜欢在其中运行多个camelcontext:/     路由tranformationIN(appContextTranformationIn)和tranformationOUT(appContextTranformationOut)将在一个camelContext中,但Spring Boot的问题也是如此。

1 个答案:

答案 0 :(得分:3)

您可以在每个其他路由中重用Camel Context中的每个路由。这只是您的路线如何设计的问题。

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

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

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

from(direct:validation)
    .bean(...)
  • 有一个direct端点可以轻松地从其他所有路径(同步)调用它们
  • 他们只完成一项任务
  • 他们没有to()“退出”,因为他们是request/reply因此他们会在路线完成后返回来电

如果您构建这样的可重复使用的块,您可以从每个“主”路径调用它们。

from(...)
    .to("direct:validation")
    .to("direct:transform")
    .to("direct:enrich")
    ...

由于有问题的更多信息而增加

第一次尝试:您无法在dataFormat中使用routeContext。您必须将其移至camelContext并仅从routeContext引用它。

来自Camel Docs

的摘录
  

注意:当您使用routeContext时,它们会被分开,并且无法重复使用{{1}中定义的现有onExceptioninterceptdataFormats和类似的交叉切割功能}}。换句话说,camelContext目前是孤立的。

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

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

routeContext