JMS和WebSphere ESB开发SOA(2)
WebSphere ESB 和服务组件体系结构
我 们在前面提到 WebSphere ESB 所使用的编程模型基于 SCA。SCA 描述了一个完整的服务编程模型,涉及到大量可采用相同的方式描述和访问的组件(即服务)。此类组件可以为 BPEL 流程、业务规则或传统 Java 组件等等。WebSphere ESB 向 SCA 模型引入了一个新的组件类型,即中介流组件。从 SCA 的角度而言,中介流组件与任何其他服务组件没有任何区别,因为中介组件具有以下特征:
- 存在于模块中(更准确地说,存在于中介模块中,它采用这种方式部署到服务器运行时中)。
- 具有接口,采用 Java 或 WSDL 描述。
- 通过导出向客户端公开,导出可以有多个不同协议的绑定(我们将在以后对此进行讨论)。
- 具有对其他服务的依赖关系(通过导入,导入也具有描述协议详细信息的绑定)。
就某种程度而言,中介流编程模型是独一无二的;它支持访问和操作关于正在处理的服务消息的绑定特定信息(通常为 Header 类型的信息)。有关 SCA 及其编程模型的详细信息以及如何通过其构建和部署组件,请参阅 Building SOA solutions with the Service Component Architecture 系列文章。(在本系列的剩下部分中,我们将假定您已具有 SCA 的基本知识,因此我们将不会对已在其他地方得到详细阐述的内容进行复述。)
中介流组件提供了一种服务组件的新实现,即中介流的实现。中介流通常使用可视流编辑器进行构建,用于通过一系列中介原语描述请求和响应消息流。这些原语可以读取和更改消息,或将其路由(“筛选”)到不同的目标位置。虽然您可以构建自己的自定义中介原语,该产品仍然提供了一系列用于以下用途的预定义原语:
- XSLT 转换
- 消息日志记录
- 消息筛选
- 数据库访问。
图 3 显示了一个使用若干中介原语实现响应流的中介流组件实现。
图 3. 中介流示例
顺便说明一下,我们将在第 2 部分详细讲解创建此类流所需的各个步骤。
WebSphere ESB 和服务消息对象
我们尚未讨论的是,消息“在总线中”时如何对其进行处理。也就是说,如何对发送到中介流组件的数据进行表示?答案是,每个消息到达中介流组件时,将立即被转换为服务消息对象。与此类似,在离开中介流组件前,会将其重新转换为消息的目标所要求的任何格式。
服 务消息对象是 Service Data Object (SDO) 规范的扩展,该规范描述了一种以独立于源的方式访问数据的方法。因此,并不会考虑消息是否通过 HTTP 或 JMS 或任何其他协议传入,也不会考虑消息是 SOAP 消息还是纯文本,而会始终将其转换为一种可由实际中介流实现(如中介原语)使用的通用格式。
因此,SCA 提供了用于调用中介流组件的编程模型,而 SMO/SDO 则表示在此组件中处理的实际消息。这二者实现了紧密的协作。
SCA 导出和导入绑定
正如前面提到的,SCA 组件使用导入和导出与外部世界通信(即,与使用组件的客户端和组件的实现使用的其他服务通信)。对 WebSphere ESB 及其中介流组件而言,可以将导出视为 ESB 的入站端口,而将导入视为出站端口。
例 如,假定您有一个现有服务使用者和一个现有服务提供者,二者通过 SOAP over HTTP 进行通信。现在您希望向此连接中插入 WebSphere ESB 中介,以便能对通过的每个消息进行记录。通过创建中介流组件,并为其提供与目标服务相同的接口,就可以实现此目标。然后为导入创建 Web 服务绑定, 以引用目标服务的 WSDL(包括端点地址),从而创建指向现有 Web 服务的导入。也就是说,已将导入“绑定”到该 Web 服务。类似地,为导出创建 Web 服务,从而生成新 WSDL 文件,并构建一个指向中介流组件的端点。最后,部署此组件,并告知服务使用者使用新端点地址。消息现在将定向到 WebSphere ESB,通过一系列中介原语,然后转发到实际的目标 Web 服务。
还记得我们曾提到每个消息都将成为总线中的一个 SMO 吗?Web 服务绑定是一段将传入 SOAP/HTTP 请求消息转换为服务消息对象的逻辑,而出站 Web 服务绑定则提供其反向逻辑;即,它将传出 SMO 转换回 SOAP/HTTP 消息。这些都是自动进行的。运行时知道入站消息的格式,因为这个消息是由相应的 WSDL 定义进行了全面的描述,运行时可以据此进行分析和处理。
为了保证正确性,自定义绑定仅处理消息的正文部分。Header 字段由基础设施自动处理,将在不需任何编程的情况下在 JMS 消息和 SMO 之间进行转换。
不 过,如果传入的消息并不遵循 SOAP 之类的特定消息协议,会发生什么呢?例如,如果有 JMS 映射消息发送到导出,则不能使用默认绑定,因为不知道此映射的格式。此时自定义绑定就派上用场了。必须以 Java 类的形式提供从传入消息到 SMO 的转换,以执行相应的分析逻辑和构建正确的 SMO。在出站端(即导入)也应该进行相同的处理。自定义绑定实现知道如何获取 SMO 并将其转换为正确的格式。
在本系列的第 2 部分和第 3 部分,我们将详细讨论自定义 JMS 绑定的示例(支持全部五种 JMS 消息类型的绑定),因此我们会再次讨论自定义绑定的话题,并演示如何将自定义绑定作为中介模块的一部分部署到运行时中。