【问题标题】:Encapsulate backend specifics with custom Camel component that wraps existing component使用包装现有组件的自定义 Camel 组件封装后端细节
【发布时间】:2018-12-16 22:11:21
【问题描述】:

我们有不同的后端(主要是 SOAP,所以我将重点介绍这一点)每个都有其自己的细节(安全性、默认超时、错误处理等)。

另一方面,我们有许多集成服务来协调对这些后端的调用。例如,“服务 A”首先调用“后端 1”,然后使用 SOAP 请求调用“后端 2”。最后,它使用两个后端的响应来创建响应。

有很多像“服务 A”这样的服务,每个服务都有一个单独的编排。它们中的每一个都是具有自己的存储库的单独项目,并被部署为一个小型 Spring-Boot 单元。

假设 10 个服务中有 4 个调用“后端 1”。它们不一定调用“后端 1”的同一个服务,但它们都需要实现同一个后端的细节。例如发送特殊标头、特定安全令牌、为此后端使用重试策略等。

为避免每个集成服务重复“后端 1”或“后端 2”的细节,我想以某种方式封装这些细节

因为我们使用 Apache Camel,我假设我可以使用 自定义 Camel 组件来做到这一点。但由于组件通常集成新型后端,我不知道我是否应该应该这样做,或者这是一个坏主意。我的后端类型(例如 SOAP)已经作为组件存在,我只是用细节包装它们。

例如,要“封装”一个 SOAP 后端,我可以创建一个自定义组件,该组件委托给 CXF 组件,以创建具有该后端通用特性(标头、安全性等)的具体服务端点.

在骆驼路线中,端点可能看起来像这样

MyBackend://serviceUri?option1=value1

它会在后台创建

cxf://serviceUri?backendSpecific1=valueA&backendSpecific2=valueB&option1=value1

或者还有其他更适合此用例的扩展点吗?

【问题讨论】:

    标签: apache-camel integration


    【解决方案1】:

    有一种方法可以在某种程度上实现这一目标。它称为端点重用。让我带您了解一下我通常如何解决此类问题。

    我通常在我的 camel-context.xml 中声明我的所有 SOAP 和 JMS 端点。然后,我为每条路由创建 xml 文件,并从那里引用我的 camel-context.xml 中定义的端点。

    这是我的 camel-context.xml 的一个简短示例,请注意 routeContextRef 元素:

    <bp:blueprint
        xmlns="http://camel.apache.org/schema/blueprint"
        xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
        xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
        http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
        http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd
        http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd
        http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0 http://aries.apache.org/schemas/blueprint-ext/blueprint-ext-1.2.xsd">
    
    <camelContext id="foo-bar" trace="{{camel.context.trace}}" autoStartup="true" useMDCLogging="true" useBreadcrumb="true" depends-on="jms" threadNamePattern="#camelId#-thread-#counter#" managementNamePattern="#camelId#-#version#" allowUseOriginalMessage="false" streamCache="false">
    
        <routeContextRef ref="foo-bar-routes"/>
    
        <endpoint id="jms-gateway-v1" uri="jms:queue:Foo.Bar.System.Evt.1.0.T" />
        <endpoint id="rs-gateway-v1" uri="cxfrs://bean://rs-gateway-impl-v1" />
    
    </camelContext>
    

    然后我创建一个 foo-bar-routes.xml 并从那里引用端点,如下所示:

    <bp:blueprint xmlns="http://camel.apache.org/schema/blueprint"
    xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ers="http://www.fooxml.com/events/resourceitem/service/v1"
    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
        http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
    
    <routeContext id="foo-bar-routes">
        <!-- 
            This route receives an event from the JMS queue
         -->
        <route id="jms-gateway-route-v1">
            <from ref="jms-gateway-v1" />
    
            <to ref="rs-gateway-v1" />
        </route>
    </bp:blueprint>
    

    简而言之,我将我的 SOAP 和 JMS 组件包装在端点定义中,然后在自己的 xml 文档中定义的路由中重用它们。我可以在另一个 XML 文件中添加第二条路由,然后在该路由中重用端点,只需添加、冲洗和重复即可。

    我知道 JavaDSL 具有类似的功能,因此使用 JavaDSL 也可以实现。

    【讨论】:

    • 感谢@Namphibian,这是一个很好的例子。但就我而言,我不需要在项目中重用相同的端点,而是在许多单独的项目中重用相同的后端细节。我将进一步改进我的问题以更好地解释这一点。
    猜你喜欢
    • 2017-05-02
    • 1970-01-01
    • 2018-05-13
    • 2023-03-06
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2017-11-28
    • 2021-03-30
    相关资源
    最近更新 更多