【问题标题】:Apache Camel: What is the best way to reuse Camel routes from other routes?Apache Camel:从其他路由重用 Camel 路由的最佳方法是什么?
【发布时间】:2018-06-12 13:26:29
【问题描述】:

我正在尝试使用 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>

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

文件transformationOUT_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 不喜欢在其中运行多个骆驼上下文:/ * 路由 tranformationIN (appContextTranformationIn) 和 tranformationOUT (appContextTranformationOut) 将在一个 camelContext 中,但 Spring Boot 的问题相同。

【问题讨论】:

  • 你真的需要将这些路由导入到某个路由类中吗?一旦他们通过 Spring/Camel 注册,您应该能够通过 .to(...) 定向到他们或通过您的路线中定义的消费者接收(即directseda,...)。你能解释一下为什么需要导入路由吗?你甚至使用 XML 配置的路由还是直接通过 Java 配置的路由(推荐从几个 Camel 版本开始)
  • 感谢您的回复!!。我添加了更多信息。

标签: java spring spring-boot apache-camel


【解决方案1】:

您可以从其他每条路线中重复使用骆驼上下文中的每条路线。这只是您的路线是如何设计的的问题。

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

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

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

from(direct:validation)
    .bean(...)
  • 有一个 direct 端点可以轻松地从其他所有路由(同步)调用它们
  • 他们只做一项任务
  • 他们没有to()“exit”,因为他们是request/reply,因此当路由完成时他们会返回给调用者

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

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

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

致您的第一次尝试:您不能在routeContext 中使用dataFormat。您必须将其移动到 camelContext 并从 routeContext 中引用它。

来自Camel Docs的片段:

注意:当您使用routeContext 时,它们会被分离,并且不能重复使用现有的onExceptioninterceptdataFormats 以及camelContext 中定义的类似横切功能。换句话说,routeContext 当前是隔离的。

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

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

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <routeBuilder ref="myMainRoute" />    
    <routeBuilder ref="mySpecificRoute1" />    
    <routeBuilder ref="mySpecificRoute2" />    
</camelContext>

【讨论】:

  • 感谢您的回复!!。我添加了更多信息。
  • 我已经扩展了我的答案
猜你喜欢
  • 2019-11-28
  • 2016-09-29
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-14
  • 2014-05-23
  • 1970-01-01
相关资源
最近更新 更多