23、企业服务总线(ESB)中的企业集成模式

企业服务总线(ESB)中的企业集成模式

在企业服务总线(ESB)的应用场景中,存在多种企业集成模式,这些模式能够帮助我们更高效地处理消息、路由信息以及实现系统间的集成。下面将详细介绍几种常见的集成模式及其应用。

1. MyReceiver 类

MyReceiver 类的代码如下:

public class MyReceiver extends TransformComponentSupport
                       implements MessageExchangeListener
{
   private String name;
   public void setName(String name){this.name = name;}
   public String getName(){return name;}
   protected boolean transform(MessageExchange exchange, 
             NormalizedMessage in,NormalizedMessage out)
                               throws MessagingException 
   {
      NormalizedMessage copyMessage = exchange.createMessage();
      getMessageTransformer().transform(exchange, in, copyMessage);
      Source content = copyMessage.getContent();
      String contentString = null;
      if (content instanceof DOMSource)
      {
         contentString = XMLUtil.node2XML(((DOMSource) 
                                   content).getNode());
      }
      if (content instanceof StreamSource)
      {
         contentString = XMLUtil.formatStreamSource((StreamSource) 
                                                         content);
      }
      System.out.println("MyReceiver.transform(" + name + "). 
                          contentString = " + contentString);
      out.setContent(new StringSource(contentString));
      return true;
   }
}

MyReceiver 类的作用是打印出消息并将相同的消息回显。

部署和运行示例
  • 构建示例:
    1. 切换到 ch15\01_ContentBasedRouter 目录。
    2. 执行命令 ant ,这将编译所有文件,包括 JMS 客户端程序。
  • 测试示例:
    1. 启动 ServiceMix,执行命令 cd ch15\01_ContentBasedRouter %SERVICEMIX_HOME%\bin\servicemix servicemix.xml
    2. 在另一个命令提示符中执行 cd ch15\01_ContentBasedRouter ant run 。JMS 客户端程序控制台将打印出发送到 ESB 的消息。
2. 内容丰富器(Content Enricher)

内容丰富器的作用是用从其他源检索到的更多相关信息补充原始消息,原始消息将被修改以包含丰富的信息。

示例设计

以 Acme 在线商店为例,客户结账时输入信用卡详细信息,后端需要进行信用授权。但网页客户输入的数据可能很少,实际授权可能需要添加更多详细信息,如 SSN。内容丰富器可以从传入消息中获取客户标识数据(客户密钥),从本地资源存储中检索额外详细信息,将这些额外信息附加到原始消息中,然后路由到目标服务。

示例用例组件
组件名称 描述
JMS 客户端 正常的外部 JMS 客户端,将 XML 消息放置到 ESB 内配置的 JMS 消费者组件上。
JMS 消费者 一个 servicemix - jms,监听队列 “A”,将接收到的消息路由到内容丰富器。
内容丰富器 servicemix - eip 组件,用额外信息丰富原始消息,并将丰富后的消息放回 JMS 提供者队列。
内容追加器 自定义转换组件,提供名为 test:kerberosticket resultElement ,以便内容丰富器用此额外元素丰富原始消息。
JMS 提供者 servicemix - jms,监听队列 “B”,内容丰富器组件将其输出消息放入此队列,供 JMS 客户端拾取。
示例代码和配置

以下是 servicemix.xml 文件的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xbean.org/schemas/spring/1.0" 
       xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:test="http://cer.eip.servicemix.esb.binildas.com" 
       xmlns:eip="http://servicemix.apache.org/eip/1.0" 
       xmlns:jms="http://servicemix.apache.org/jms/1.0">
   <classpath>
      <location>.</location>
   </classpath>
   <import resource="classpath:jmx.xml" />
   <import resource="classpath:jndi.xml" />
   <import resource="classpath:security.xml" />
   <import resource="classpath:tx.xml" />
   <import resource="classpath:activemq.xml" />
   <bean id="propertyConfigurer" class="org.springframework.beans.
                    factory.config.PropertyPlaceholderConfigurer">
      <property name="location" 
                value="classpath:servicemix.properties" />
   </bean>
   <sm:container name="jbi"
                 monitorInstallationDirectory="false"
                 createMBeanServer="true"
                 useMBeanServer="true">
   <sm:activationSpecs>
      <sm:activationSpec>
         <sm:component>
            <jms:component>
               <jms:endpoints>
                  <jms:endpoint service="test:MyConsumerService"
                                endpoint="myConsumer"
                                role="consumer" 
                                soap="false" 
                                targetService="test:contentEnricher"
                                defaultMep="http://www.w3.org/2004/
                                                   08/wsdl/in-only"
                                destinationStyle="queue"
                                jmsProviderDestinationName="queue/A"
                                connectionFactory  =
                                   "#connectionFactory" />
                  <jms:endpoint service="test:MyProviderService"
                                endpoint="myProvider"
                                role="provider" 
                                soap="false" 
                                destinationStyle="queue"
                                jmsProviderDestinationName="queue/B"
                                connectionFactory=
                                   "#connectionFactory" />
                  </jms:endpoints>
               </jms:component>
            </sm:component>
         </sm:activationSpec>
      <sm:activationSpec id="servicemix-eip">
         <sm:component>
            <eip:component>
               <eip:endpoints>
                  <eip:content-enricher 
                                 service="test:contentEnricher" 
                                 endpoint="endpoint" 
                                 enricherElementName="test:subject" 
                                 requestElementName="test:principal" 
                                 resultElementName="test:credential">
                     <eip:enricherTarget>
                        <eip:exchange-target 
                                    service="test:contentAppender" />
                     </eip:enricherTarget>
                     <eip:target>
                        <eip:exchange-target 
                           service="test:MyProviderService" />
                     </eip:target>
                  </eip:content-enricher>
               </eip:endpoints>
            </eip:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="contentAppender" 
                         service="test:contentAppender">
         <sm:component>
            <bean xmlns="http://xbean.org/schemas/spring/1.0" 
                  class="ContentAppender" >
               <constructor-arg ref="jbi"/>
            </bean>
         </sm:component>
      </sm:activationSpec>
   </sm:activationSpecs>
   </sm:container> 
   <bean id="connectionFactory" 
         class="org.apache.activemq.ActiveMQConnectionFactory">
      <property name="brokerURL" value="tcp://localhost:61616" />
   </bean>
</beans>
部署和运行示例
  • 构建示例:
    1. 切换到 ch15\02_ContentEnricher 目录。
    2. 执行命令 ant
  • 测试示例:
    1. 启动 ServiceMix,执行命令 cd ch15\02_ContentEnricher %SERVICEMIX_HOME%\bin\servicemix servicemix.xml
    2. 在另一个命令提示符中执行 cd ch15\02_ContentEnricher ant run 。JMS 客户端程序控制台将打印出发送到 ESB 的消息以及内容丰富器的响应消息。
3. XPath 拆分器(XPath Splitter)

XPath 拆分器基于原始的拆分器 EAI 模式,可识别消息中的重复元素,将消息拆分并将每个元素部分作为单独的消息发布到不同的通道。

示例设计

以 Acme 在线电子商务网站为例,客户可以在购物车中添加多个商品,结账时提交一个包含多个订单项目的单个订单。为了对每个订单项目进行单独的库存检查,可以将订单路由到 XPath 拆分器,拆分器将订单拆分为单个订单项目,并将每个订单项目作为单独的消息推送到队列,然后可以使用内容路由器将每个新消息路由到各自的库存队列。

示例用例组件
组件名称 描述
JMS 客户端 正常的外部 JMS 客户端,将 XML 复合消息放置到 ESB 内配置的 JMS 消费者组件上。
JMS 消费者 一个 servicemix - jms,监听队列 “A”,将接收到的消息路由到 XPath 拆分器。
XPath 拆分器 servicemix - eip 组件,尝试将接收到的消息与配置的 XPath 匹配,根据重复元素将原始消息拆分为多个部分,并将每个部分作为单独的消息重新发布到交换目标(跟踪组件)。
跟踪组件 将接收到的消息打印到控制台。
示例代码和配置

以下是 servicemix.xml 文件的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xbean.org/schemas/spring/1.0" 
       xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:test="http://xslt.servicemix.apache.binildas.com" 
       xmlns:eip="http://servicemix.apache.org/eip/1.0" 
       xmlns:jms="http://servicemix.apache.org/jms/1.0">
   <classpath>
      <location>.</location>
   </classpath>
   <import resource="classpath:jmx.xml" />
   <import resource="classpath:jndi.xml" />
   <import resource="classpath:security.xml" />
   <import resource="classpath:tx.xml" />
   <import resource="classpath:activemq.xml" />
   <bean id="propertyConfigurer" 
         class="org.springframework.beans.factory.config.
                          PropertyPlaceholderConfigurer">
      <property name="location" 
                value="classpath:servicemix.properties" />
   </bean>
   <sm:container name="jbi"
                 monitorInstallationDirectory="false"
                 createMBeanServer="true"
                 useMBeanServer="true">
    <sm:activationSpecs>
      <sm:activationSpec>
         <sm:component>
            <jms:component>
               <jms:endpoints>
                  <jms:endpoint service="test:MyConsumerService"
                                endpoint="myConsumer"
                                role="consumer" 
                                soap="false" 
                                targetService="test:xpathSplitter" 
                                defaultMep="http://www.w3.org/2004/
                                                   08/wsdl/in-only"
                                destinationStyle="queue"
                                jmsProviderDestinationName="queue/A"
                                connectionFactory=
                                   "#connectionFactory" />
               </jms:endpoints>
            </jms:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec id="servicemix-eip">
         <sm:component>
            <eip:component>
               <eip:endpoints>
                 <eip:xpath-splitter service="test:xpathSplitter" 
                                     endpoint="xpathSplitterEndpoint"
                                     xpath="/hello/*" >
                     <eip:target>
                        <eip:exchange-target service="my:trace" />
                     </eip:target>
                  </eip:xpath-splitter>
               </eip:endpoints>
            </eip:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="trace" service="my:trace">
         <sm:component>
            <bean class="org.apache.servicemix.components.
                                  util.TraceComponent" />
         </sm:component>
      </sm:activationSpec>
   </sm:activationSpecs>
   </sm:container>
   <bean id="connectionFactory" 
         class="org.apache.activemq.ActiveMQConnectionFactory">
      <property name="brokerURL" value="tcp://localhost:61616" />
   </bean>
</beans>

配置的 XPath 为 /hello/* ,将 hello 元素内的每个元素拆分为单独的消息。

部署和运行示例
  • 构建示例:
    1. 切换到 ch15\03_XPathSplitter 目录。
    2. 执行命令 ant
  • 测试示例:
    1. 启动 ServiceMix,执行命令 cd ch15\03_XPathSplitter %SERVICEMIX_HOME%\bin\servicemix servicemix.xml
    2. 在另一个命令提示符中执行 cd ch15\03_XPathSplitter ant run 。JMS 客户端程序控制台将打印出发送到 ESB 的消息,ESB 端会将消息按配置拆分。
4. 静态接收者列表(Static Recipient List)

静态接收者列表可检查传入消息,并根据接收者列表中指定的接收者数量,将消息转发到与接收者关联的所有通道。

示例设计

以 Acme 后端系统为例,当接收到确认订单时,需要将订单分发给包装系统、运输系统和库存系统。可以配置一个静态接收者列表,指定运输队列、包装队列和用于库存系统的内容路由器队列,所有这些 LOB 系统将接收相同的订单以启动相关业务流程。

示例用例组件
组件名称 描述
JMS 客户端 正常的外部 JMS 客户端,将 XML 复合消息放置到 ESB 内配置的 JMS 消费者组件上。
JMS 消费者 一个 servicemix - jms,监听队列 “A”,将接收到的消息路由到静态接收者列表。
静态接收者列表 servicemix - eip 组件,将接收到的消息转发到接收者列表中配置的所有接收者(不同的接收器组件实例)。
接收器组件 将接收到的消息打印到控制台。
示例代码和配置

以下是 servicemix.xml 文件的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xbean.org/schemas/spring/1.0" 
       xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:test="http://xslt.servicemix.apache.binildas.com" 
       xmlns:eip="http://servicemix.apache.org/eip/1.0" 
       xmlns:jms="http://servicemix.apache.org/jms/1.0">
   <classpath>
      <location>.</location>
   </classpath>
   <import resource="classpath:jmx.xml" />
   <import resource="classpath:jndi.xml" />
   <import resource="classpath:security.xml" />
   <import resource="classpath:tx.xml" />
   <import resource="classpath:activemq.xml" />
   <bean id="propertyConfigurer" 
         class="org.springframework.beans.factory.config.
                          PropertyPlaceholderConfigurer">
      <property name="location" 
                value="classpath:servicemix.properties" />
   </bean>
   <sm:container name="jbi"
                 monitorInstallationDirectory="false"
                 createMBeanServer="true"
                 useMBeanServer="true">
   <sm:activationSpecs>
      <sm:activationSpec>
         <sm:component>
            <jms:component>
               <jms:endpoints>
                  <jms:endpoint service="test:MyConsumerService"
                                endpoint="myConsumer"
                                role="consumer" 
                                soap="false" 
                                targetService="test:recipients" 
                                defaultMep="http://www.w3.org/2004/
                                                   08/wsdl/in-only"
                                destinationStyle="queue"
                                jmsProviderDestinationName="queue/A"
                                connectionFactory  =
                                   "#connectionFactory" />
               </jms:endpoints>
            </jms:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec id="servicemix-eip">
         <sm:component>
            <eip:component>
               <eip:endpoints>
                  <eip:static-recipient-list 
                                   service="test:recipients" 
                                   endpoint="endpoint">
                     <eip:recipients>
                        <eip:exchange-target 
                           service="test:receiver1" />
                        <eip:exchange-target 
                           service="test:receiver2" />
                        <eip:exchange-target 
                           service="test:receiver3" />
                     </eip:recipients>
                  </eip:static-recipient-list>
               </eip:endpoints>
            </eip:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="receiver1" 
                         service="test:receiver1">
         <sm:component>
            <bean xmlns="http://xbean.org/schemas/spring/1.0" 
                  class="MyReceiver" >
               <property name="name">
                  <value>1</value>
               </property>
            </bean>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="receiver2" 
                         service="test:receiver2">
         <sm:component>
            <bean xmlns="http://xbean.org/schemas/spring/1.0" 
                  class="MyReceiver" >
               <property name="name">
                  <value>2</value>
               </property>
            </bean>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="receiver3" 
                         service="test:receiver3">
         <sm:component>
            <bean xmlns="http://xbean.org/schemas/spring/1.0" 
                  class="MyReceiver" >
               <property name="name">
                  <value>3</value>
               </property>
            </bean>
         </sm:component>
      </sm:activationSpec>
   </sm:activationSpecs>
   </sm:container>
   <bean id="connectionFactory" 
         class="org.apache.activemq.ActiveMQConnectionFactory">
      <property name="brokerURL" value="tcp://localhost:61616" />
   </bean>
</beans>

配置了三个接收者: test:receiver1 test:receiver2 test:receiver3

部署和运行示例
  • 构建示例:
    1. 切换到 ch15\04_StaticRecipientList 目录。
    2. 执行命令 ant
  • 测试示例:
    1. 启动 ServiceMix,执行命令 cd ch15\04_StaticRecipientList %SERVICEMIX_HOME%\bin\servicemix servicemix.xml
    2. 在另一个命令提示符中执行 cd ch15\04_StaticRecipientList ant run 。JMS 客户端程序控制台将打印出发送到 ESB 的消息,ESB 控制台将显示消息已分发到所有三个接收者。
5. 窃听器(Wiretap)

窃听器是一种简单的接收者列表,插入消息通道时,会将每个传入消息发布到主通道以及辅助通道。

示例设计

以 Acme 在线商店的信用卡支付审计为例,信用卡信息到达后端系统时,可以使用窃听器将消息发布到主通道以及辅助审计模块,审计模块将所需信息写入不可擦除磁盘。

示例用例组件
组件名称 描述
HTTP 客户端 外部 HTTP 客户端,将 XML 消息放置到 ESB 内配置的 HTTP 连接器组件上。
HTTP 连接器 ServiceMix HTTP 组件,监听端口 8912,将接收到的消息路由到窃听器。
窃听器 servicemix - eip 组件,将接收到的消息转发到主目标(回声组件)和监听器(跟踪组件),可处理所有四种标准 MEPs,但只能向监听器发送 In - Only MEP。
回声组件 窃听器的主目标,参与 In - Out MEP,将请求回显到窃听器,再到窃听器的消费者组件(HTTP 连接器)。

通过以上几种企业集成模式,可以在 ESB 中实现消息的处理、路由和集成,满足不同业务场景的需求。在实际应用中,可以根据具体业务需求选择合适的模式,并按照相应的步骤进行配置和部署。

企业服务总线(ESB)中的企业集成模式

示例代码和配置

以下是 servicemix.xml 文件的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xbean.org/schemas/spring/1.0" 
       xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:test="http://xslt.servicemix.apache.binildas.com" 
       xmlns:eip="http://servicemix.apache.org/eip/1.0" 
       xmlns:http="http://servicemix.apache.org/http/1.0">
   <classpath>
      <location>.</location>
   </classpath>
   <import resource="classpath:jmx.xml" />
   <import resource="classpath:jndi.xml" />
   <import resource="classpath:security.xml" />
   <import resource="classpath:tx.xml" />
   <import resource="classpath:activemq.xml" />
   <bean id="propertyConfigurer" 
         class="org.springframework.beans.factory.config.
                          PropertyPlaceholderConfigurer">
      <property name="location" 
                value="classpath:servicemix.properties" />
   </bean>
   <sm:container name="jbi"
                 monitorInstallationDirectory="false"
                 createMBeanServer="true"
                 useMBeanServer="true">
    <sm:activationSpecs>
      <sm:activationSpec>
         <sm:component>
            <http:component>
               <http:endpoints>
                  <http:endpoint service="test:MyHttpClientService"
                                 endpoint="myHttpClient"
                                 role="consumer" 
                                 soap="false" 
                                 targetService="test:wiretap" 
                                 defaultMep="http://www.w3.org/2004/
                                                    08/wsdl/in-out"
                                 port="8912" />
               </http:endpoints>
            </http:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec id="servicemix-eip">
         <sm:component>
            <eip:component>
               <eip:endpoints>
                  <eip:wiretap 
                                 service="test:wiretap" 
                                 endpoint="wiretapEndpoint">
                     <eip:target>
                        <eip:exchange-target 
                           service="test:echo" />
                     </eip:target>
                     <eip:listener>
                        <eip:exchange-target 
                           service="my:trace" />
                     </eip:listener>
                  </eip:wiretap>
               </eip:endpoints>
            </eip:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="echo" 
                         service="test:echo">
         <sm:component>
            <bean class="org.apache.servicemix.components.
                                  util.EchoComponent" />
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="trace" 
                         service="my:trace">
         <sm:component>
            <bean class="org.apache.servicemix.components.
                                  util.TraceComponent" />
         </sm:component>
      </sm:activationSpec>
   </sm:activationSpecs>
   </sm:container>
   <bean id="connectionFactory" 
         class="org.apache.activemq.ActiveMQConnectionFactory">
      <property name="brokerURL" value="tcp://localhost:61616" />
   </bean>
</beans>
部署和运行示例
  • 构建示例:
    1. 切换到 ch15\05_Wiretap 目录。
    2. 执行命令 ant
  • 测试示例:
    1. 启动 ServiceMix,执行命令 cd ch15\05_Wiretap %SERVICEMIX_HOME%\bin\servicemix servicemix.xml
    2. 在另一个命令提示符中执行 HTTP 请求,将 XML 消息发送到 http://localhost:8912 。HTTP 客户端将收到回声组件的响应,同时跟踪组件会将消息打印到控制台。

总结与对比

为了更清晰地了解这些企业集成模式的特点和适用场景,下面通过表格进行总结对比:
| 模式名称 | 功能描述 | 适用场景 | 关键配置 |
| ---- | ---- | ---- | ---- |
| MyReceiver 类 | 打印消息并回显相同消息 | 简单的消息测试和验证 | 配置 JMS 客户端和端点 |
| 内容丰富器 | 用额外信息丰富原始消息 | 消息数据不足,需要补充信息的场景 | 配置 enricherElementName requestElementName resultElementName |
| XPath 拆分器 | 根据 XPath 拆分消息 | 处理包含重复元素的复合消息 | 配置 XPath 表达式 |
| 静态接收者列表 | 将消息转发到多个接收者 | 需要将同一消息分发给多个系统的场景 | 配置接收者列表 |
| 窃听器 | 将消息发布到主通道和辅助通道 | 需要对消息进行审计或监控的场景 | 配置主目标和监听器 |

模式选择建议

在实际应用中,选择合适的企业集成模式至关重要。以下是一些选择建议:
- 消息验证和回显 :如果只是简单地验证消息是否正确传输,可以使用 MyReceiver 类。
- 数据补充 :当消息中的数据不足以进行后续处理时,内容丰富器是一个不错的选择。
- 复合消息处理 :对于包含重复元素的复合消息,如订单列表、乘客名单等,XPath 拆分器可以将其拆分为单个元素进行处理。
- 多系统分发 :如果需要将同一消息分发给多个系统,静态接收者列表可以满足需求。
- 消息审计和监控 :在需要对消息进行审计或监控的场景下,窃听器可以将消息复制到辅助通道进行处理。

流程图示例

下面是一个简单的 mermaid 流程图,展示了内容丰富器的工作流程:

graph LR
    A[JMS 客户端] -->|发送消息| B[JMS 消费者]
    B -->|路由消息| C[内容丰富器]
    C -->|获取额外信息| D[内容追加器]
    D -->|返回额外信息| C
    C -->|丰富消息| E[JMS 提供者]
    E -->|消息输出| F[JMS 客户端]

通过以上介绍,我们对企业服务总线(ESB)中的几种常见企业集成模式有了更深入的了解。这些模式可以帮助我们更好地处理消息、路由信息以及实现系统间的集成。在实际应用中,根据具体业务需求选择合适的模式,并按照相应的步骤进行配置和部署,能够提高系统的效率和可靠性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值