内容


使用可重用资产构建 SOA 应用程序,第 3 部分

WS 响应模板模式

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 使用可重用资产构建 SOA 应用程序,第 3 部分

敬请期待该系列的后续内容。

此内容是该系列的一部分:使用可重用资产构建 SOA 应用程序,第 3 部分

敬请期待该系列的后续内容。

引言

本系列前面的文章中,我们介绍了 SOA Implement and Optimize Services Recipe,并对参考示例进行了讨论,以说明可以如何应用此菜谱。该参考使用模型驱动的开发方法(Model-driven development,MDD),并利用 IBM Rational Software Architect 建模功能来开发用例模型、分析模型、设计模型和服务模型。本文说明如何修改现有服务;这是 SOA Implement and Optimize Services Recipe 中的一个重要步骤。

通常已经存在提供核心功能的遗留应用程序。要修改现有服务,必须将此应用程序作为服务提供,而且此服务必须遵循与原始应用程序需求不同的一系列非功能需求。

我们使用 SOA Implement and Optimize Services Recipe 和参考示例来说明软件模式能够如何满足这些新的非功能需求。通过使用软件模式来满足非功能需求,可帮助开发人员和架构师构建一个体系结构一致的服务,从而严格遵守软件开发最佳实践和原则。

修改现有服务

从我们在本系列第 2 部分所讨论的库存系统用例分析中了解到,一个现有的遗留 Catalog 应用程序提供用于访问 Catalog 信息的 Java™ 接口。现在我们必须将此遗留应用程序作为服务公开。在我们的菜谱中,这是一个过程示例,此过程包含重用现有服务或应用程序的四个步骤:

  1. 检查服务模型
  2. 检查服务的非功能需求
  3. 检查遗留应用程序分析/设计模型
  4. 基于非功能需求应用恰当的模式

SOA Implement and Optimize Services Recipe 为其中的每个步骤均提供了参考示例。

  • 以 Rational Software Architect 资产的形式提供了 Catalog 服务及相关消息表示形式的服务模型,可导入到 Rational Software Architect UML 模型项目中。
  • 对于库存系统用例的非功能需求,Rational RequisitePro 需求管理文件是以可重用资产规范(Reusable Asset Specification,RAS)资产的形式提供的。不过,此需求文件应该通过网络上的共享访问形式提供。图 3 显示了在打开参考示例的这个 Rational RequisitePro 需求管理文件后,Rational Software Architect 内的 Rational RequisitePro Requirement Explorer 的情况。
  • 遗留 Catalog 的设计模型;此设计模型作为 RAS 资产提供,可导入到 Rational Software Architect UML 模型项目中。

检查服务模型

Catalog 服务模型

图 1 显示了 Catalog 服务模型。该模型包含两个操作:

  • getCatalog() 操作接受一个主键作为参数,并返回 Catalog
  • getCatalogs() 操作接受一个主键数组为参数,并返回 Catalog 数组
图 1. Catalog 服务 UML 模型
Catalog 服务 UML 模型
Catalog 服务 UML 模型

Catalog 消息模型

图 2 显示了 Catalog 消息模型。对于此模型,以下内容非常清楚,无须赘述:

  • 每个 Catalog 消息包含多个 CatalogItem 消息
  • 每个 CatalogItem 消息包含多个 FeatureValue 消息
  • 每个 FeatureValue 消息包含一个 Feature 消息
图 2. Catalog 消息 UML 模型
Catalog 消息 UML 模型
Catalog 消息 UML 模型
图 3. Rational Software Architect 中的 Rational RequisitePro Requirements Explorer
Rational Software Architect 中的 Rational RequisitePro Requirements Explorer

检查非功能需求

本系列的第 2 部分对 Catalog 服务模型文件进行了详细的讨论。

Rational RequisitePro 为该 Catalog 模型跟踪非功能需求。Rational Software Architect 提供了 Rational RequisitePro Client,可显示用例与功能需求及非功能需求间的映射。以下是 Catalog 服务的非功能需求:

  • 互操作性:Catalog 服务需要由多个客户机实现进行访问。
  • 可维护性:现有 Catalog 服务非常粗粒度,但客户机调用通常将仅需要所提供的信息的一个子集。
  • 性能:Catalog 服务需要在一定时间限制内完成操作。
  • 可跟踪性:Catalog 服务的所有调用都必须能够跟踪。

检查遗留 Catalog 设计模型

图 4 显示了遗留 Catalog 应用程序/服务的 UML 视图。此应用程序是一个 Java 组件,公开了一个 Java 接口。查看此接口时,将看到 getCatalog() 和 getCatalogs() 操作是非常粗粒度的操作,会分别返回整个 Catalog 和 Catalog 列表。也可以从 SOA Implement and Optimize Services Recipe 访问遗留 Catalog 设计模型,但在本文中并不需要它。

图 4: 遗留 Catalog 应用程序设计模型
遗留 Catalog 应用程序设计模型
遗留 Catalog 应用程序设计模型

应用恰当的模式

通过使用分析和设计模型,架构师或开发人员将能够应用恰当的模式来满足相关的非功能需求。

将使用三个模式来构造 Catalog 服务:

  • WS 响应模板模式规范详细说明了上下文、问题和可重复的解决方案。它提供了服务接口灵活性和可维护性。有关 WS 响应模板模式规范的信息,请参见参考资料部分。
  • 请求端缓存模式 (Requestor Side Caching Pattern) 规范可改进服务性能。有关 WS 响应模板模式规范的信息,请参见参考资料部分。
  • 日志记录 (Logging) 模式提供了服务调用可跟踪性。

在详细讨论这些模式前,考虑以下所示的 n 层体系结构将有所帮助。简单的三层体系结构将包括表示层、业务层和持久层。在 SOA 环境中,我们可以将业务层进一步划分为服务层、控制器层和实体/对象管理层。此分层情况如图 5 中所示。会话 Facade、消息 Facade 和业务委托等核心 JavaBean™ 模式属于控制器层。图 5 显示了这些模式在 n 层体系结构中的应用位置。

图 5. 模式规范和结构
模式规范和结构
模式规范和结构

WS 响应模板模式

对 Catalog 服务模型的分析表明 Catalog 服务接口将返回整个 Catalog。虽然这可能会为有些客户机应用程序带来好处,但对我们的应用程序而言,此接口太粗粒度了。非功能需求之一是使得此 Catalog 服务正常运行,并能与其他服务和客户机进行互操作。

非功能需求

WS 响应模板模式能满足以下非功能需求:

  1. 服务必须能够与其他服务互操作。
  2. 服务在大多数情况下提供对粗粒度接口的细粒度访问。
  3. 接口应该在接口定义中提供一定的灵活性,同时考虑到值对象的改变。

为了满足这些非功能需求,我们将使用 WS 响应模板模式。有关 WS 响应模板模式规范的信息,请参见参考资料部分。作为补充,下面给出了类关系图和序列关系图。在模式规范的上下文中,这些关系图更有意义。请参见侧栏中有关模式规范和模式实现的讨论。WS 响应模板模式规范详细说明了上下文、问题和模式提供的可重复解决方案。

类关系图

图 6 显示了 WS 响应模板模式的类关系图。

图 6. WS 响应模板类关系图
WS 响应模板类关系图
WS 响应模板类关系图

序列关系图

图 7 显示了 WS 响应模板模式的序列关系图。

  • 客户机将通过使用提供的可识别 WS 响应模板的 WSDL 调用服务。请求方将使用密钥和请求模板调用 WS 响应模板实现。
  • 密钥唯一地标识所需的值对象。
  • 请求模板告知服务实现响应中需要哪个已断开连接的信息子集。
  • 服务实现查询使用密钥查询提供程序,并获得与该密钥关联的对应值对象。
  • 现在将调用称为导航器的运行时组件——模式中提供了一个不受支持的实现。导航器将获取作为输入的请求模板和值对象,并返回响应模板。
  • 响应模板中包含值对象信息图的安全子集,这些信息图是用户在请求模板中请求的。响应模板返回给请求方。
图 7. WS 响应模板序列关系图
WS 响应模板序列关系图
WS 响应模板序列关系图

应用 WS 响应模板模式

Web 服务响应模板模式实现可以通过使用菜谱导入到 Rational Software Architect 中。首先,导航到菜谱中的“Apply patterns to a service implementation”部分,展开并选择“Applying the WS response template pattern”部分。在此步骤下找到资产并选择导入。请参见图 8

通过观看下载部分提供的 flash 文件,可以了解如何应用和使用此模式。

图 8. 导入 WS 响应模板模式实现
导入 WS 响应模板模式实现
导入 WS 响应模板模式实现

此操作会将 WS 响应模板模式实现安装到 Rational Software Architect 和 UML 软件服务配置文件。安装了模式后,会在 Pattern Explorer 中显示此模式,如图 9 中所示。

图 9. 显示 WS 响应模板模式的 Pattern Explorer
显示 WS 响应模板模式的 Pattern Explorer
显示 WS 响应模板模式的 Pattern Explorer

以下将介绍我们如何应用模式:Open up the SOA Inventory Service Model。可以从 Rational Software Architect 存储库获得此服务模型,且从 SOA Implement and Optimize Services Recipe 进行了引用。此模型包含 Catalog 服务和 Inventory 服务的 UML 服务模型。请确保已安装了 UML Profile for Software Services、Rational Software Architect 插件。请参见参考资料部分。如果安装 WS 响应模板模式,会自动安装 UML Profile for Software Services。

图 10. 导入 SOA Catalog Service_Design Model
导入 SOA Catalog Service_Design Model
导入 SOA Catalog Service_Design Model

图 11图 12 显示了我们所感兴趣的透视图:服务视图和消息视图。

图 11. SOA Catalog 服务设计模型视图
SOA Catalog 服务设计模型视图
SOA Catalog 服务设计模型视图

消息视图中的 CatalogItems Overview 关系图显示 Catalog 消息。双击它可打开此视图。

图 12. Catalog 消息模型
Catalog 消息模型
Catalog 消息模型

在建模透视图中,将 WS 响应模板模式从 Pattern Explorer Pallet 托盘拖放到 Catalog Message Model 上。在建模视图中,可以使用 Rational Software Architect 右上侧的快捷视图按钮找到它。如果未在其中找到,请从 Windows > Show View 中找到 Pattern Explorer。图 13 显示了进行了此操作后的消息模型关系图。

图 13. 应用 WS 响应模板模式
应用 WS 响应模板模式
应用 WS 响应模板模式

WS 响应模板模式接受四个参数:

  • AnchorMessage 参数:消息图的根消息。在我们的示例中,即 Catalog 消息。
  • ServiceSpecification 参数:将应用 WS 响应模板模式的服务规范。在我们的示例中,即 Catalog Service。
  • FilterParameter 参数:通常,这是允许对子元素进行筛选的子组合消息的属性。在我们的示例中,即为将允许按 sku 对 CatalogItems 进行筛选的 SKU 属性。
  • WSRTOperations 参数:表示服务规范上要让 WS 响应模板识别的操作。在我们的示例中,使用的是 getCatalog() 操作。

图 14 显示了应用模式后模型的情况:

图 14. WS 响应模板模式应用到 Catalog 服务模型后的情况
WS 响应模板模式应用到 Catalog 服务模型后的情况
WS 响应模板模式应用到 Catalog 服务模型后的情况

应用此模型的结果是,会生成一个新的服务模型 emx 文件。图 15 显示了这个新生成的能够识别 WS 响应模板的服务模型的内部结构。

图 15. 生成的 Catalog 服务模型
生成的 Catalog 服务模型
生成的 Catalog 服务模型

通过查看这个生成的服务模型,可以发现以下事实:

  • 消息视图中现在存在与请求和响应模板对应的独立请求和响应包。
  • 请求包中的消息图松散类型化。并不需要对其进行强类型化,因为它仅用于告知服务实现响应中所需的元素。
  • 响应包中的消息图强类型化,因为这引用从服务器返回的实际数据。

Catalog 服务接口中的方法签名也已发生了更改。getCatalog() 操作签名现在采用以下格式:getCatalog(primaryKey, requestTemplate):ResponseTemplate 。此方法返回强类型化的 Catalog 响应模板实例。此外,此方法现在接受两个请求参数:

  1. 标识 Catalog 的主键。
  2. Catalog 请求模板,此请求模板允许用户指定请求中需要哪个(已断开连接的)Catalog 信息图子集。

可以从这个新服务模型生成能识别 WS 响应模板的 WSDL 和 XSD。

  • 在服务视图中找到 CatalogComponent
  • 在鼠标右键上下文菜单中找到转换菜单项。使用 UML 到 WSRT 的转换。
  • 此转换的对话框将提示用户指定 Web 项目、生成 WSDL 和 XSD 以及 WSDL 的命名空间。使用 http://catalog.retail.ibm.com/ 作为命名空间。
图 16. UML to WSRT 对话框
UML to WSRT 对话框
UML to WSRT 对话框

我们将使用 WSDL to Java 生成器来创建 Catalog Web 服务的 Java 实现:

  • 切换到 J2EE 透视图。
  • 右键单击生成的 WSDL 文件。必须启用 Rational Software Architect Web Service 功能。要启用此功能及其他功能,请转到 Windows > Preferences > Workbench > Capabilities,并启用 Web Service Developer 和 XML Developer。
  • 禁止对 SOAPElement 使用数据绑定。Windows > Preferences > Workbench > Web Services > Code Generation > IBM WebSphere runtime。请参见图 17
  • 在 WSDL- Java 生成对话框中,选中 Test the Web Service 和 Monitor the Web Service。
  • 其余设置可以接受缺省值。
  • 注意:最好在此生成步骤前测试 IBM WebSphere® 6.0 服务器。
图 17. 禁止对 SOAPElement 使用数据绑定
禁止对 SOAPElement 使用数据绑定
禁止对 SOAPElement 使用数据绑定
图 18. WSDL to Java 转换
WSDL to Java 转换
WSDL to Java 转换

最好在此时使用 Web Service Explorer 测试这个空实现。图 19 显示了对“Catalog B”的调用,此时客户机只关心 Catalog 的名称、说明和开始日期。

图 19. 使用 Web service explorer 进行测试
使用 Web service explorer 进行测试
使用 Web service explorer 进行测试

在 SOAP 调用中,请求有两个参数:

  • 此例中 Catalog 的主键是 Catalog“B”。
  • 请求模板指示,仅应该返回名称、说明和开始日期。

如果在 WSDL to Java 生成过程中选中了监视 Web 服务对应的框,SOAP 调用请求应该出现在 TCP/IP Tunneller 中,带空白 SOAP 响应。

现在,让我们充实这个实现,以实际返回一些东西。在 getCatalog() 实现中,进行以下步骤:

  1. 调用获取 Catalog 的遗留 Catalog 应用程序,通常其签名为 getCatalog(key):Catalog
  2. 调用导航器。本文提供了一个不受支持的导航器参考实现(请参见下载部分),必须将其包含在已部署的应用程序中,以将 Catalog 请求模板和 Catalog 值对象(来自遗留 Catalog 应用程序)转换为 Catalog 响应对象。
  3. 下面给出了这个服务器端实现的完整清单(为 Catalog 服务生成的框架接口和实现)。
  4. 必须在开发期间和运行时提供 wst.server(参考导航器代码)和遗留 Catalog 应用程序(实际获取 Catalog 的应用程序)。请参见下载部分。对于开发工作,请确保这两个项目都包含在构建路径中。对于运行时,必须首先将这些项目添加到父 EAR 文件,然后在 Catalog 服务 WAR 文件中作为独立 JAR 引用。

以下清单显示了为 Catalog 服务生成的框架接口和实现:

清单 1. Catalog 服务框架接口
/**
 * IWSRTTireCatalog.java
 *
 * This file was auto-generated from WSDL
 * by the IBM Web services WSDL2Java emitter.
 * o0505.16 v2605125559
 */

package com.ibm.retail.catalog;

import com.ibm.awsdc.wst.core.InvokerException;
import com.ibm.awsdc.wst.core.WriterException;

public interface IWSRTTireCatalog extends java.rmi.Remote {
    public javax.xml.soap.SOAPElement getCatalog(javax.xml.soap.SOAPElement key, 
    javax.xml.soap.SOAPElement requestTemplate) throws java.rmi.RemoteException, 
    InvokerException, WriterException;
}
清单 2. Catalog 服务实现
						/**
 * IWSRTCatalogSpecificationBindingImpl.java
 * 
 * This file was auto-generated from WSDL by the 
 * IBM Web services WSDL2Java
 * emitter. o0526.04 v62905175048
 */

package com.ibm.retail.catalog;

import javax.xml.rpc.ServiceException;
import javax.xml.rpc.server.ServiceLifecycle;
import javax.xml.rpc.server.ServletEndpointContext;

import com.ibm.awsdc.wst.core.InvokerException;
import com.ibm.awsdc.wst.core.Navigator;
import com.ibm.awsdc.wst.core.WriterException;

public class IWSRTCatalogSpecificationBindingImpl implements
	  com.ibm.retail.catalog.IWSRTCatalogSpecification,ServiceLifecycle {
	private ServletEndpointContext context;

	public javax.xml.soap.SOAPElement getCatalog(
		  javax.xml.soap.SOAPElement key,
		  javax.xml.soap.SOAPElement requestTemplate)
		  throws InvokerException, WriterException {
		Object catalog = null;
		String keystr = ((javax.xml.soap.Node) key.getChildElements().next())
			.getValue();
		System.out.println(keystr);
		// Get a refer to the legacy catalog application
		com.ibm.retail.entity.catalog.LegacyCatalogApp catalogImpl = 
		 new com.ibm.retail.entity.catalog.LegacyCatalogAppImpl();
		catalog = catalogImpl.getCatalog(keystr);
		// Nagivate the catalog to return a response template
		return Navigator.navigate(requestTemplate, catalog, context);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.xml.rpc.server.ServiceLifecycle#init(java.lang.Object)
	 */
	public void init(Object arg0) throws ServiceException {
		context = (ServletEndpointContext) arg0;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.xml.rpc.server.ServiceLifecycle#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub

	}
}

使用 Web Service Explorer 测试实现。图 20 显示了对“Catalog A”的调用,此时客户机只关心 Catalog 的名称、说明和开始日期。

图 20. 使用 Web service explorer 进行测试
使用 Web service explorer 进行测试
使用 Web service explorer 进行测试

以下是对应的 SOAP 调用请求。此请求具有两个参数:

  • 此例中 Catalog 的主键是 Catalog“A”。
  • 请求模板指示,仅应该返回名称、说明和开始日期。

如果在 WSDL to Java 生成过程中选中了监视 Web 服务对应的框,SOAP 调用请求应该出现在 TCP/IP Tunneller 中,带空白 SOAP 响应。请参见图 21

图 21. TCP/IP Tunneller
TCP/IP Tunneller
TCP/IP Tunneller

请参见下载部分,其中提供了最终的 Rational Software Architect 项目,打包为项目交换文件。要导入 Rational Software Architect,请选择 File > Import > Project Interchange。

我们实现的结果

图 22 显示了应用于 Catalog 服务模型时 WS 响应模板模式的序列关系图。

通过分析此序列关系图,可发现以下事实:

  • 客户机将通过使用提供的可识别 WS 响应模板的 WSDL 调用服务。请求方将使用密钥和请求模板调用 WS 响应模板实现。
  • 密钥唯一地标识所需的值对象。
  • 请求模板告知服务实现响应中需要哪个(已断开连接的)信息图子集。
  • 服务实现查询使用密钥的提供程序,并获得与该密钥关联的对应值对象。
  • 现在将调用称为导航器的运行时组件(模式中提供了一个不受支持的实现)。导航器将获取作为输入的请求模板和值对象,并返回响应模板。
  • 响应模板中包含类型安全的值对象信息图子集,这些信息是用户在请求模板中请求的。响应模板返回给请求方。
图 22. getCatalog() WS 响应模板序列关系图
getCatalog() WS 响应模板序列关系图
getCatalog() WS 响应模板序列关系图

此时,通过将 WS 响应模板模式应用到 Catalog 服务,我们认识到大部分工作都涉及到了解问题、标识其范围并随后使其通用化,以便在将来再次应用。

我们还看到了最基本的更改是,方法签名从 getCatalog(primaryKey):Catalog 更改为了 getCatalog(primaryKey, catalogRequestTemplate):CatalogResponseTemplate

请求方现在对从服务器返回的响应中的数据具有细粒度的控制,就传递网上的信息量而言,服务调用现在的性能更好了。这与 WS 调用特别有关系,在 WS 调用中,由于契约在本质上是基于 ASCII 的,因此增加了交换的细节。

我们的解决方案利用所使用的工具的现有功能,大部分工作都是了解问题、标识其范围并随后使其通用化,以便在将来再次应用。

结束语

在本文中,我们应用了一个模式,以得到灵活的服务模型来帮助满足该服务的一些非功能需求。我们还从更广泛的意义上说明了模式通常如何满足非功能需求。最后,通过使用 WS 响应模板,我们得到了一个为客户机提供细粒度访问(最初是粗粒度接口)的服务,并同时保持了网络最优化,并通过允许在不影响客户机的情况下进行实体更改,从而在服务接口中提供了所需的灵活性。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=SOA and web services
ArticleID=203928
ArticleTitle=使用可重用资产构建 SOA 应用程序,第 3 部分: WS 响应模板模式
publish-date=03292007