技术开发 频道

利用现有服务构建SOA应用

【IT168 技术】  petals ESB是一个开源的JBI(Java Business Integration)容器,本文介绍如何利用它将异构服务连接起来,构建一个SOA架构的Web应用。

  JBI规范充分利用了SOA的非常好的概念,并且为利用现有服务组合应用程序的方法统一了标准。JBI基本上实现了ESB概念的标准化。用Petals JBI容器构建SOA应用程序相当简单:使用一些标准的JBI绑定或者引擎组件,编写几个XML描述来解释如何连接到你的服务,然后把它们部署到Petals JBI容器里面。有了这样一种容器,问题就变成了编写或者使用粒度很细的相关服务,而不是对它们进行组合。

  由于全球性网络的发展、异构信息系统的增加以及需求的灵活多变,传统的应用架构正在不断受到挑战。如今人们不再从事这些工作了:构建全新的应用程序、为遗留系统开发特定适配件,或者改写现有的应用程序。而是主要在Web服务连接的推动下,向面向服务的架构(SOA)转移。

  SOA旨在把信息系统的现有功能作为“服务”来提供,这些服务可以通过松散耦合的方式来访问,独立于技术平台。应用程序被看成是对这些服务的请求进行编制(orchestration)。

  企业服务总线(ESB)是SOA的实现,它其实是连接异构服务、对这些服务进行编制的中间件。与这些概念相关的Java业务集成规范(JBI)为集成定义了标准框架。

  本文借助Petals ESB这种开放源代码JBI容器来描述如何连接现有的异构服务、构建网上旅行社的Web应用程序。

  Java业务集成

  Java业务集成规范定义了组合集成组件的标准手段,目的在于创建集成解决方案,能够在企业信息系统里面实现SOA。这些组件插入到JBI环境后,可以通过JBI以松散耦合的方式来提供或者使用服务。然后,JBI环境发送这些组件之间交互的消息。

  两种组件可以插入到JBI环境:服务引擎提供了环境中的逻辑,譬如可扩展样式表语言(XSL)转换或者业务流程执行语言(BPEL)编制等;绑定组件是连接外部服务或者应用程序的“连接件”,它们允许与各种协议进行联系,譬如简单对象访问协议(SOAP)、Java消息服务(JMS)、远程方法调用(RMI)或者电子商务可扩展标记语言(ebXML)。

  这些可配置组件能够在异构服务之间进行联系。JBI规范引入了服务组合件(Service assembly),它定义了这些组件及组件之间联系的配置。组件(绑定或者引擎)的目的在于提供内外服务。JBI环境中提供的每项服务可通过服务端点即服务地址来加以访问。

  组件之间交换的消息被称为交换消息(message exchanges)。组件之间的交换模式是发送-接收消息模式。

  使用JBI的网上旅行社应用程序

  旅行社网站允许用户预定航班和铺位,发送电子邮件给用户确认这些预定。为了提供这项功能,网站向工作流引擎发送由用户提供、使用XML格式的所有信息。然后,该工作流引擎连接至航空公司、预定航班,然后连接到酒店连锁店预定房间。它通过邮件引擎向用户发送用于确认的电子邮件。

  即使这个流程期间交换的数据是XML,但不同服务请求或者提供的XML模式也各不相同。因而,可扩展样式表语言转换(XSLT)引擎被用来处理从XML转换成另一种格式的工作。

  本文稍后会讨论这个业务流程。不妨先看一下图1,该图显示了应用程序是如何使用Petals ESB构建而成的。

  现在先定义一下这种架构的不同关键部分:

  1.服务组合件

  服务组合件是一个描述符,它可对与应用程序进行集成的JBI组件进行配置。服务组合件作为简单的ZIP存档部署在JBI容器上。该容器分析这个存档里面的所有内容,并且配置受到影响的组件。组件配置称为服务单元(service unit)。我们利用服务单元配置组件时,把工件(artifact)部署在上面。需要注意的是,服务单元的内容对容器来说是不透明的,只是提供给了组件。如果服务组合件包含服务之间的关系定义(也叫连接),容器可以生成它们。连接可以被认为是真实服务端点的化名。

  服务组合件是一个ZIP存档,包含有定义了服务单元提供给哪个组件的XML描述文件以及服务之间的关系。服务组合件还含有部署到组件上的每个服务单元,这些服务单元也是ZIP存档。(如图2所示)

  图2 服务组合件

  概括来讲,服务组合件的作用就是定义一组服务之间的连接关系,用SOA的方式构建应用程序。如果多个服务组合件都部署在容器上,多个应用程序就可以在同一批服务上运行,并共享这些服务。

  2.服务单元

  服务单元是部署到JBI组件上的一组元素。服务单元含有组件能够读取的XML描述符以及组件需要的任何工件。譬如说,XSLT引擎的服务单元含有XSL样式表,而描述文件告诉该组件:如果某个服务端点上收到消息,就必须使用这个样式表。

  ESB可把服务单元存档展开到目录中、调用组件的服务单元管理器(JBI组件的一部分) 从而告知新的服务单元可以使用,并且表明服务单元展开所在的目录。组件的服务单元管理器把这个新服务注册到JBI环境,并配置组件,以便使用与已注册服务端点相关的工件。组件收到特定服务端点的消息后,它就知道使用哪个工件了。(如图3、4、5所示)

  图3 服务单元

  3.连接

  连接在服务组合件的描述符里面加以定义。可以把它看成是真实服务端点的化名。譬如说,某组件可以明确“我想发送消息到名为My Endpoint的服务端点”,而连接明确My Endpoint其实就是My Real Endpoint。因而,如果组件发送消息到My Endpoint,其实发送到了My Real Endpoint。

  使用这种机制的意义在于,可以动态重新配置组件之间的关系。譬如说,某组件(如旅行社的工作流引擎)经配置后,在服务端点名称是“airline service endpoint”的地方调用服务。然后视旅行社与航空公司的合作关系而定,连接会把航空公司服务端点与MyLowCostAirlineCompanyEndpoint或者AnotherAirlineCompanyEndpoint联系起来。服务的使用者不需要改变什么,即可连接到相应服务。通过部署含有不同连接的各种服务组合件,应用程序就可以动态改变使用的服务(如图6所示)。

  旅行社的应用程序

  旅行社应用程序的全局流程如下所示:

  1.网站通过SOAP请求发送用户的预定请求到SOAP绑定组件。该信息名为网站XML内容。请注意:这种通信在JBI外面进行。

  2.现在,我们进入JBI环境。SOAP绑定组件经配置后,通过交换消息发送网站XML内容到端点BookingWorkflow-EndPoint(由BPEL引擎负责)。

  3.BPEL引擎发送网站XML内容到XSLT_1_Endpoint(由XSLT引擎负责)。

  4.XSLT引擎把网站XML内容转换成航空公司服务能识别的一种格式,然后作为航班请求XML返回。

  5.BPEL引擎发送网站XML内容到XSLT_2_Endpoint(由XSLT引擎负责)。

  6.XSLT引擎把网站XML内容转换成酒店服务能识别的一种格式,然后作为酒店请求XML返回。

  7.BPEL引擎发送航班请求XML到AirLineEndpoint,作为MyAirLineCom-panyEndpoint来解析(由SOAP绑定组件负责)。

  8.SOAP绑定组件经配置后,通过SOAP请求发送航班请求XML到MyAirLineCompany Web服务(在JBI外面进行)。结果就是得到确认的航班响应XML,并返回给BPEL引擎。

  9.BPEL引擎发送酒店请求XML到HotelEndpoint,作为MyHotelEndpoint来解析(由RMI绑定组件负责)。

  10.RMI绑定组件经配置后,通过RMI调用发送酒店请求XML到MyHotel RMI服务器(在JBI外面进行)。结果就是得到确认的酒店响应,并返回给BPEL引擎。

  11.由于两次预定,BPEL引擎把航班响应XML和酒店响应XML连接成航班-酒店响应XML。然后,它发送这个XML到XSLT_3_Endpoint(由XSLT引擎负责)。

  12.XSLT引擎把航班-酒店响应XML转换成概述了两次预定的文本。这个电子邮件XML返回给旅行社的工作流引擎。

  13.BPEL引擎发送电子邮件XML到EmailEndpoint(由电子邮件绑定组件负责)。

  14.电子邮件绑定组件发送电子邮件和电子邮件XML给用户(在JBI外面进行)。至此,整个流程完成。

  组件

  应用程序所需的JBI组件包括:SOAP绑定组件(与网站和航空公司的Web服务通信)、JMS绑定组件(与酒店的JMS服务通信)、XSLT引擎(XML转换)、电子邮件引擎(发送确认电子邮件给用户)以及BPEL引擎。这些JBI组件使用Petals JBI容器来分发。

  为了构建这个应用程序,我们只要把这些组件安装到JBI容器里面即可。

  至此,架构如图7所示。

  图7 组件安装后

  请注意:邮件引擎以原生方式把其单一服务端点提供给JBI环境,因为它不需要配置,总是执行同一项任务(实际上就是发送电子邮件)。

  组件安装完毕,我们必须进行配置。因而,我们需要组建把这些元素联系起来的服务组合件。下面描述的服务单元构成了这个服务组合件。

  网站服务单元

  创建部署到SOAP绑定组件(SOAP BC)上的服务单元。这个服务单元定义了将映射到内部服务端点WorkflowEndpoint的http://travel.com/workflowService Web服务。

  有了这个服务单元,SOAP BC可以使用WorkflowEndpoint服务端点:

< jbi version="1.0" xmlns='http://java.sun.com/xml/ns/jbi' ...>
< services binding-component="true">
< consumes service-name =" BookingWorkflowService " endpoint-name =" BookingWorkflowEndpoint " />
< petals:address> http://travel.com/workflowService < /petals:address>
< /services>
< /jbi>

 

  服务单元部署后,SOAP BC提供新的Web服务,名为http://travel.com/workflowService。对这项Web服务执行外部调用后(譬如从网站执行),SOAP BC把它传输给BookingWorkflowEnd-point服务端点,也就是应用程序的工作流引擎。

  预定流程服务单元

  创建部署到BPEL引擎上的服务单元。这个服务单元含有预定流程的BPEL定义。这个定义列出了必须由工作流引擎来调用的不同服务端点。这个流程定义映射到内部服务端点: BookingWorkflowEndpoint。

  BookingWorkflowEndpoint:

< jbi version="1.0" xmlns='http://java.sun.com/xml/ns/jbi' ...>
< services binding-component="false">
< provides service-name =" BookingWorkflowService "endpoint-name =" BookingWorkflowEndpoint " />
< petals:address> file://travel-booking.bpel < /petals:address>
< /services>
< /jbi>

 

 

  travel-booking.bpel文件包含在该服务单元里面,它描述了流程。

  航空公司Web服务的服务单元

  创造部署到SOAP BC上的另一个服务单元。这个服务单元定义了将映射到外部Web服务http://myairline.com/flightBookingService的MyAirlineCompanyEndpoint。

  有了这个服务单元,SOAP BC可以提供MyAirlineCompanyEndpoint服务端点:

< jbi version="1.0" xmlns='http://java.sun.com/xml/ns/jbi'>
< services binding-component="true">
< provides service-name =" MyAirLineCompanyService " endpoint-name =" MyAirLineCompanyEndpoint " />
< petals:address> http://myairline.com/flightBookingService < /petals:address>
< /services>
< /jbi>

 

  该服务单元部署后,SOAP BC在JBI环境里面激活MyAirlineCompanyEndpoint服务端点。JBI组件发送消息到该服务端点后,SOAP BC把它传输到外部Web服务:http://myairline.com/flightBookingService,也就是航空公司预定Web服务。

  酒店JMS服务单元

  酒店JMS服务单元看上去就像航空公司服务单元。JMS BC提供了MyHotel-Endpoint服务端点,将映射到与酒店JMS服务器交换的JMS消息。

  XSLT服务单元

  XSLT引擎用于三种转换:从网站到航班请求XML的初始XML; 初始XML转换成酒店请求XML; 航班-酒店响应XML转换成电子邮件XML。

  所以必须提供三个服务单元,每个服务单元都含有正确转换所需的XSL样式表。XSLT引擎将通过三个服务端点提供这三个服务。

  航空公司和酒店的连接

  正中我们在前面看到的那样,我们可以使用连接,把应用程序的工作流引擎与航空公司和酒店的服务独立联系起来。并且只要通过部署新的服务组合件,就可以动态重新配置这种连接。

  譬如说,与My Low Cost Airline Company的连接看上去可以这样:

< jbi version="1.0" xmlns…>
< service-assembly>
...
< connections>
< connection>
< consumer service-name ="AirLineService" endpoint-name ="AirLineServiceEndpoint"/>
< provider service-name ="MyLowCostAirLineCompany" endpoint-name ="MyLowCostAirLineCompanyEndpoint"/>
< /connection>
< /connections>
< /service-assembly>
< /jbi>

  这部分代码表明,服务使用者(应用程序的工作流引擎)使用AirlineService服务时, 实际使用的是MyLowCostAirLine服务。

  全局服务组合件

  所有这些服务单元都封装在一个服务组合件里面。服务组合件的描述文件含有连接(如图8所示)。这个服务组合件部署在Petals JBI容器里面,所有服务单元都提供给了相应组件(如图9所示)。这些组件注册了相关的服务端点,容器设定了连接,应用程序现在已可以运行了。

0
相关文章