使用包装现有组件的自定义骆驼组件封装后端细节

时间:2018-07-09 09:13:44

标签: apache-camel integration

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

另一方面,我们有很多集成服务,可以协调对这些后端的调用。例如,“服务A”首先使用SOAP请求调用“后端1”,然后调用“后端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

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

1 个答案:

答案 0 :(得分: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来实现。