用JBI实现在线旅行社 本文实现的在线旅行社可以提供用户预订机票和旅店,并向用户发送邮件确认用户的预约。为实现这一功能,网站将向工作流引擎发送用户以XML格式提供的所有信息,然后该工作流引擎会联系航空公司订购机票,并向旅店连锁机构预订房间,最后它会通过邮件引擎向用户发送一封确认信。 尽管此过程中所使用的数据交换格式是XML,但各种服务请求或提供的XML模式不尽相同。因此,可扩展样式表转换语言(XSLT)引擎就被用来进行从XML向其它格式的转换。 后文会详细讨论这个业务过程,这里先看图1。图1描述怎样使用Petals ESB构建整个应用。 图1 应用架构 现在我们来讨论该架构的各个关键组成部分。 服务装配器 服务装配器(service assembly)描述如何配置一个JBI组件使其能集成到应用中。它以一个简单的zip压缩包方式部署在JBI容器中。容器分析压缩包中的所有内容,并根据这些内容配置相关的组件。组件的配置即是一个服务单位(service unit)。当我们使用服务单位来配置一个组件时,我们称之为部署一个配置(artifact)。请注意,服务单位的内容对容器来说是不透明的,它只提供给组件。 如果服务装配器包含对服务之间关系的定义(即连接,connections),容器就会创建这些连接。可以视连接为真正的服务终端别名。 如图2,服务装配器是一个zip压缩包,它包含XML描述符文件,定义向哪个组件提供服务单位以及服务之间的连接。服务装配器还包含要向各个组件部署的服务单位。这些服务单位也是zip压缩包。 图2 服务装配器 简单地说,服务装配器的作用就是定义一系列服务之间的关系,从而以SOA的方式创建应用。如果容器中有多个服务装配器,那么这些服务装配器应该可以在同样的服务上运行,并共享这些服务。 服务单位 服务单位是一系列部署到JBI组件中的元素。它包含一个组件能够读取的XML描述符,以及任何组件可以获取的配置。比如,一个XSLT引擎的服务单位包含一个XSL样式表,描述符文件告诉组件如果接收到某个特定服务终端发来的消息就必须使用该样式表。
图3 服务单位 ESB将服务单位包放在一个目录里,然后告诉组件的服务单位管理器(JBI组件的一部分)有新的服务单位可以调用,并指出存放服务单位的目录位置。组件的服务单位管理器把新服务注册到JBI环境中,然后配置组件以使用已注册的服务终端。
图4 在组件上配置服务单位 当组件收到调用某个服务终端消息的时候,它就会知道该用哪一个配置。 图5 为特定服务终端使用配置 连接器 连接器是在服务配置器的描述符里定义的,可以视其为真正的服务终端的别名。比如,一个组件可以描述“我要向一个称作My Endpoint的服务终端发送一条消息”,连接器就可以认为My Endpoint实际上就是My Real Endpoint。这样,当组件向My Endpoint发送消息时,消息就会被发送到My Real Endpoint。 使用这样一种机制的意义在于,可以动态地对组件之间的连接进行重新配置。比如,配置一个组件——旅行社的工作流程引擎——来调用叫做“航空服务终端”的服务。后来,由于旅行社与航空公司合作关系的变化,连接器要把航空服务终端连接到“低消费的航空公司终端”或“另一个航空公司终端”。服务使用者不需要做出任何变更,通过部署包含不同连接器的各种服务配置器,应用就会动态地更改所使用的服务。 图6 更换一个连接器
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发送到“航空服务终端”,解析为“我的航空公司终端”(在SOAP绑定组件上)。
8. SOAP绑定组件的配置会通过发送一个SOAP请求把航空服务请求XML发送到“我的航空公司”Web服务(在JBI外部);然后得到经过确认的航空服务响应XML,并被返回BPEL引擎。
9. BPEL引擎把旅店服务请求XML发送到“旅店终端”,解析为“我的旅店终端”(在RMI绑定组件上)。
10. RMI绑定组件的配置会以RMI调用的形式把旅店服务请求XML发送到“我的旅店”RMI服务器(在JBI外部);然后得到经过确认的旅店服务响应XML,并被返回BPEL引擎。
11. 根据这两项预订,BPEL引擎把航空服务响应XML和旅店服务响应XML合并为航空/旅店服务响应XML;然后把这个XML发送到XSLT_3_Endpoint(在XSLT引擎上)。
12. XSLT引擎把航空/旅店服务响应XML转换为概述这些预订的文本;然后以邮件XML的格式返回到旅行社工作流引擎。 13. BPEL引擎把邮件XML发送到邮件终端(在邮件绑定引擎上)。
14. 邮件绑定引擎把邮件XML发送给用户(在JBI外部)。过程结束。 组件 应用所需的JBI组件有SOAP绑定组件(与网站和航空公司的Web服务进行通信)、JMS绑定组件(与旅店JMS服务进行通信)、XSLT引擎(XML转换)、邮件引擎(向客户发送确认邮件)和BPEL引擎。这些JBI组件都是用Petals JBI容器进行配置的。 要创建应用,只要把这些组件安装到JBI容器。到此,架构应该是如图7所示的样子: 图7 组件安装后 这里注意,邮件引擎在本地向JBI环境开放它唯一的服务终端,因为它不需要任何配置,并且总是执行同样的任务(实际上就是发送邮件)。 组件安装后,我们必须对它们进行配置。因此,我们要创建能把这些元素连接到一起的服务装配器。服务装配器由以下所述服务单位构成。 网站服务单位 创建一个服务单位部署到SOAP绑定组件上(SOAP BC)。这个服务单位定义了http://travel.com/workflowService的Web服务,并将指向内部的WorkflowEndpoint服务终端。 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就把它传送到BookingWorkflowEndpoint服务终端,也就是应用的工作流引擎。 预订流程服务单位 这是用来部署到BPEL引擎上的服务单位。这个服务单位包含一个预订流程的BPEL定义,定义列出工作流程引擎必须调用的各种服务终端。这个流程定义是指向内部的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> 预订流程的BPEL文件描述了这个过程并储存在服务单位中。 航空公司Web服务单位 另一个要部署到SOAP BC上的服务单位是航空公司的Web服务单位。这个服务单位定义了将指向外部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就将其传送到外部的http://myairline.com/flightBookingService Web服务,也就是航空服务预订的Web服务。 旅店JMS服务单位 旅店JMS服务单位跟航空服务单位相似。JMS BC提供负责向旅店JMS服务器转发消息的MyHotelEndpoint服务终端。 XSLT服务单位 XSLT引擎用于三种转换: * 把网站的初始XML转换为航空服务请求XML * 把网站的初始XML转换为旅店服务请求XML * 把航空/旅店服务响应XML转换为邮件XML 因此,必须有这三个服务单位,并且包含一个正确描述转换的XSL样式表。XSLT引擎将通过三个服务终端提供三种服务。 航空公司与旅店的连接器 如前面所述,我们可以使用各个连接器独立地把应用的工作流引擎连接到航空公司和旅店服务,并且通过部署新的服务装配器动态地配置这些连接。 比如,一个指向MyLowCostAirLineCompany的连接器: <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。
图9 部署应用服务装配器 组件注册相应的服务终端,容器配置好连接器,然后应用就可以投入使用。 图10 配置好的容器 总结 JBI规范有效地利用SOA的理念,产生出一套利用当前服务来组合应用的标准方法。从根本上讲,JBI把ESB的概念标准化。 利用Petals JBI容器构建SOA应用非常简单:使用一些标准的JBI绑定或引擎组件,写几个XML描述文件解释怎样连接到服务,然后把它们部署到Petals JBI容器里就可以了。 有了这样一个容器,就无需再解决装配的难题,只需寻找合适的粒度编写或者使用相关的服务即可。
作者:IT168