向 SOA 转型,第 2 部分: 在 IBM Rational Software Architect 中
为 Business Process-to-Service Model 转换特性创建一个自定义扩展
 

2009-08-12 作者:Natalia Balaba-Liaskovski 来源:IBM

 
本文内容包括:
一个典型的开发周期涉及到分析和捕获业务目标的业务分析(Business Analysis) 模型的创建,然后将其转换为一个软件体系结构模型。IBM ®Rational® Software Architect 中的 Business Process-to-Service Model SOA 转换特性有助于您创建这一模型。本文提供了一个入门示例,向您详细演示如何创建一个自定义的过程分解(process decomposition),用于将您的业务处理过程转换为一个服务模型。本文所面向的是那些对如何创建转换扩展比较熟悉的读者。

Business Process-to-Service Model 转换特性概述

IBM Rational Software Architect 中的 Business Process-to-Service Model 转换特性包括主体转换和三个默认的扩展。

主体转换创建一个统一建模语言控件(Unified Modeling Language Component)来描述服务提供者(Service Provider)。转换还通过端口对组件进行组装,每一个表现界面或者是被服务所提供,或者是被服务所需要。最终,一个 CollaborationUse 元素被创建出来,它将体系结构模型中的服务所表现的组件同业务分析模型(Business Analysis Model)中的协作(Collaboration)链接起来。组件上的每一个端口都将被绑定到适当的角色。CollaborationUse 元素,同端口和角色绑定一起,表现为一个协议验证段。该合同确认允许跟踪到业务分析(Business Analysis),确认组件按照业务分析模型中所指定的处理过程得以实现。

图 1. 转换工具的主要输出包括:端口、协议验证段、CollaborationUse 元素以及角色绑定。
转换工具的主要输出

主体转换并不提供它所生成的组件的任何内部分解。其原因就在于这些细节依靠执行和配置域的决定和约束。

创建内部分解的任务落到了主体转换的扩展肩上。每一个扩展都创建其自己的业务处理过程的分解,并且描述它的内部工作。尽管很少有这样的扩展被提供,但是您能够通过创建和注册自定义的扩展来创建不同的服务分解,从而满足这些特定的需要。

自定义扩展场景

在这个例子中,假设您已经为新的服务创建了一个业务分析(Business Analysis)模型,并且将遗产服务综合到解决方案之中。这一模型描述了通过共同工作来创建一个 Medical Marketplace 一族服务。这个 Medical Marketplace 呈现出各种各样的医疗服务。提供服务的每一个客户请求都将被处理,并且一个适当的服务将被选中来提供给客户端。当服务被执行时,付款将被收集,并且客户反馈将被提交到市场数据库(请参见图 2 所示)。

图 2. Medical Marketplace 的 Business Analysis Model 的业务处理过程。
Medical Marketplace 的 Business Analysis Model 的业务处理过程

我们来关注以下付款收集(Payment Collector)服务,它负责在医疗服务被提供之后开列账单以及收集付款。它要求某些种类的簿记保存有关交易的记录。它将日志(Logger)服务用于这些目的。这些服务的目的是有效利用现已存在的 Java™ 代码。

假设现有遗传下来的账单(Billing)和日志(Logging)服务。账单(Billing)服务表现了一个被称作 Billing 的 Java 接口。这里有一个通过 com.acme.billing.MedicalBilling Java 类的具体执行。MedicalBilling 使用由另一个遗产库所定义的日志(Logging)服务:com.acme.logging(请参见图 3 所示)。

图 3. Java 遗产库包含了 Billing 和 Logging 服务的 Java 执行。
Java 遗留库

完整的 SOA 解决方案被配置在服务组件定义语言(Services Component Definition Language,SCDL)中。自定义扩展的目的是生产一个被连接到基于 Java 的遗产库的 SCDL 模块。

将业务处理过程扩展为一个服务模型所需要的基本步骤

  1. 创建一个 Eclipse 插件程序项目。
  2. 创建一个转换类(请参见列表 1 中的例子)。
列表 1. 创建一个转换类的代码。
 
                
package com.ibm.xtools.transform.cfm.example.transform;

import com.ibm.xtools.transform.cfm.example.rules.MyPopulateComponentRule;
import com.ibm.xtools.transform.core.Transform;

public class MyTransform
    extends Transform {

   //id of the transformation 
 public static final String TRANSFORM_ID = 
"com.ibm.xtools.transform.cfm.example.transform.MyTransformId"; 

    public MyTransform() {
        super(TRANSFORM_ID); // instantiate transformation using id
        add(new MyPopulateComponentRule());//program transformation with this rule
   
    }
}

注释:
当创建一个扩展号的时候,请尽量做到唯一性。这一点是非常重要的,这是因为当转换配置指明一个处理过程应当使用一个扩展号被转换的时候,具有那个扩展号的扩展将被选中,并且被用于转换该处理过程。

  1. 将功能性编入 MyPopulateComponentRule 的代码。列表 2 中的代码强调了这一规则的关键功能。
列表 2. 用于 MyPopulateComponentRule 的代码。
 
                
public class MyPopulateComponentRule extends ModelRule {

/*
* canAccept method asserts wither  or not the extension is applicable
*/
public boolean canAccept(ITransformContext context) {

// the rule will be invoked if the current node on the source side is 
// an instance of UML Collaboration and the node on the target side 
// is instance of UML Component
return context.getSource() instanceof Collaboration
				& context.getTarget() instanceof Component;
}

/*
* createTarget method will perform additional (to main)  transformation of the 
Collaboration(service) in the source
*  model to the elements in the target model
*/
protected Object createTarget(ITransformContext context) throws Exception {

Component collaborationComponent = (Component) context.getTarget();
Component java_adapter = createJavaConverter(collaborationComponent);

assert (java_adapter != null);

Property attribute = collaborationComponent.createOwnedAttribute(
				"java_adapter", java_adapter);

for (Iterator e = collaborationComponent.getOwnedPorts().iterator(); e.hasNext();) {
  Port port = (Port) e.next();

  // there will only one port that provides interface to the outside.
  if (!port.getProvideds().isEmpty()) {
Port in_port = java_adapter.createOwnedPort("in_" + port.getName(), null);

Interface anInterface = (Interface) port.getProvideds().get(0);
addProvidedInterface(anInterface, in_port);

createConnector(collaborationComponent, port, in_port, null, attribute, 
ConnectorKind.DELEGATION_LITERAL);
} else if (!port.getRequireds().isEmpty()) {

Interface anInterface = (Interface) port.getRequireds().get(0);

Type type = createUsage(java_adapter, anInterface);
Port out_port = java_adapter.createOwnedPort("out_" + port.getName(), type);
createConnector(collaborationComponent, out_port, port, attribute, null, 
ConnectorKind.DELEGATION_LITERAL);
	}
}

return collaborationComponent;
}

/*
* auxiliary method – creates java adapter component for the role, 
which represents Collaboration (service) itself
*/
private Component createJavaAdapter(Component collaborationComponent) {

for (Iterator e = collaborationComponent.getOwnedPorts().iterator(); ehasNext();) {
Port port = (Port) e.next();

if (!port.getProvideds().isEmpty()) {
return (Component) collaborationComponent..createPackagedElement(port.getName() + 
"Adapter",UMLPackage.Literals.COMPONENT);

		}
	}

return null;
}
…

}

Create the extension condition class:
 
/**
 * com.ibm.xtools.transform.cfm.example.condition.MyExtensionCondition
 */

public class MyExtensionCondition
    extends TransformCondition {

    public MyExtensionCondition() {
        super();
    }

    protected boolean isContextSatisfied(ITransformContext context) {

        return (context.getSource() instanceof Collaboration)
            & CommonConfigUtil.getExtensionIdFor(
                (Collaboration) context.getSource(), context).equals(
                MyTransform.TRANSFORM_ID);
    }

}

该条件将在运行时被使用,来断定一个业务处理过程是否使用您自定义的转换被配置、被转换。

  1. 将您的扩展注册到一个 XML 插件程序文件中。列表 3 显示了一个声明自定义扩展的例子。
列表 3. 一个声明自定义扩展的 XML 插件程序文件的代码示例。
 
                
<?xml version="1.0" encoding="UTF-8"?>
  <?eclipse version="3.2"?>
  <plugin>
  <extension
  point="com.ibm.xtools.transform.core.transformationExtensions">
  
  <TransformationExtension
  author="you"
  description="my custom extension"
  document="optional"
  enabled="true"
  id="com.ibm.xtools.transform.cfm.example.transform.MyTransformId"
  name="My custom extension"
  targetTransformation="com.ibm.xtools.transform.cfm.wbm.transforms.MainTransform"
  version="1.0.0">
  
  <TransformDefinition
  acceptCondition="com.ibm.xtools.transform.cfm.example.condition.MyExtensionCondition"
  class="com.ibm.xtools.transform.cfm.example.transform.MyTransform"
  id="com.ibm.xtools.transform.cfm.example.transform.MyTransformId"/>
  
  <ExtendTransform
  targetTransform="com.ibm.xtools.transform.cfm.wbm.transforms.OwnedBehaviorTransform"> 
  
  <AddTransform id="com.ibm.xtools.transform.cfm.example.transform.MyTransformId"/>
  </ExtendTransform>
  </TransformationExtension>
  </extension>
  </plugin>

这一例子自定义扩展的目标是 Business Process-to-Service Model 主体转换:
com.ibm.xtools.transform.cfm.wbm.transforms.MainTransform

它也指定了那些扩展条件需要被用来决定扩展的能力:
com.ibm.xtools.transform.cfm.example.condition.MyExtensionCondition

最后,它指定了转换的分支,哪一个转换将通过这个扩展被扩展:
com.ibm.xtools.transform.cfm.wbm.transforms.OwnedBehaviorTransform

配置自定义的扩展

  1. 配置转换。
  2. 在您完成前述各个步骤之后,将您的插件程序导出到您的插件程序目录下,并且重新启动 Rational Software Architect。

您的自定义扩展将可以用于从 Configuration UI (用户接口)中进行选择,如图 4 中所示。

图 4. 配置一个带有自定义扩展的转换。
配置一个带有自定义扩展的转换
  1. 配置一种处理过程,用来使用自定义的扩展。
  2. 保存配置,并且运行转换。
  3. 处理输出、继续建模、授权到遗留代码(请参见图 5 所示)。
图 5. 被转换的付款收集器(Payment Collector),使用自定义的扩展分解。
被转换的付款收集器(Payment Collector),使用自定义的扩展分解

为了自定义的扩展而被创建的分解如图 5 中所示。现在,可以继续下一步的操作。

授权调用 Java 库的服务

Java 适配器的作用是授权到 Java 库的调用。以建模:

  1. 通过键入 BillingComponent 为付款收集器(Payment Collector)创建第二个属性(部分),并且添加两个端口:
    • myRoleAdapter 添加第一个端口,设置被需要的接口为:
      com.acme.billing.Billing
    • Billing 组件 添加第二个端口,设置其类型为:
      com.acme.billing.MedicalBilling (请参见图 6 所示)。
  2. 连接两个端口。
图 6. 将扩展适配到遗留代码。
将扩展适配到遗留代码

注释:

账单(Billing)服务需要另外一种被称作日志(Logger)的服务。如果 Logger 服务的执行同 Billing 一样可用的话,那么您就能够以同样的方式建模 Logger 和 Billing。否则的话,它就被作为 myRoleAdapter 组件的一部分功能被建模。

这一模型现在能够被 SOA 转换来使用,创建配置产品。SOA Transformation 将把 Payment Collector 组件转换到一个 IBM®WebSphere® Integration Developer 业务集成模型项目中。用于 Java 适配器和 Medical Billing 的部分将被修改到那个模块内部的一个 Service Component Architecture (SCA)组件中。为 MedicalBilling 而创建的 SCA 将把组件实现参考内容指向 Java 遗留库。

总结以及第 3 部分内容展望

正如您从本文中所学到的,Business Process-to-Service Model 转换特性支持在 WebSphere Business Modeler 中的业务分析建模和 UML 中的设计建模之间搭建的桥梁。具有特定配置域和执行域需求的业务,能够适应这一转换来满足它们的需要。由转换所创建的产品能够在 Rational Software Architect 中被进一步的建模。它还能够通过使用由 Rational Software Architect 所提供的 SOA 转换工具被转换到一个 WebSphere Integration Developer 项目中。

您能够在本系列文章的下一部分(第 3 部分:UML 到 SOA)中找到更多关于 SOA 转换的信息。那篇文章详细解释了如何使用包含在 Rational Architect Version 7.0.0.2 及其以后版本中的 UML-to-SOA 转换工具从软件服务的 UML 模型转换到特定域的 SOA 实现。这一工具将把用于特定软件执行和运行时间的不同转换扩展汇集到一起。

参考资料

学习
  • 您可以参阅本文在 develperWorks 全球网站上的 英文原文
  • 本系列的第 1 部分:向 SOA 转型,第 1 部分:利用 IBM WebSphere Business Modeler 和 IBM Rational Software Architect 从业务过程转换成服务模型架构
  • 本系列的第 3 部分:向 SOA 转型,第 3 部分:从 UML 到 SOA
  • 进一步获取有用的信息,请您阅读由 Jim Amsden 撰写的有关开发基于面向服务的体系结构(SOA)的软件的系列文章:
    • SOA 建模,第 1 部分: 服务识别。介绍了如何利用由 IBM Software Service Profile 扩展的 UML 模型设计与商业需求有联系的 SOA 解决方案,但独立于解决方案实现。作者介绍了商业目的和目标,以及满足那些目标的商业过程,然后介绍了如何使用这些过程来确定执行服务所表示的需求所必需的业务相关的服务。
    • SOA 建模,第 2 部分: 服务规范。作者通过详细地对每个服务的规范进行建模来继续定义 SOA 解决方案。这些规范将定义服务的消费者和生产者之间的约定。这些约定包括所提供的和所需要的接口,在服务规范中那些接口所扮演的角色,以及那些角色如何交互的规则或协议。
    • SOA 建模,第 3 部分: 服务实现。第三篇文章介绍了如何实际地实现基于 SOA 的 Web 服务。服务实现决定什么组件将提供什么服务。该决策在服务可用性、分布、安全性、事务范围,和耦合方面有重要的含意。在制定了这些决策之后,您可以对如何实现每个服务的功能,以及如何实际地使用所需的服务进行建模。然后您可以使用 IBM Rational Software Architect 中包含的 UML 到 SOA 的转换特性来创建可以用于 IBM WebSphere Integration Developer 中实现、测试、和部署已完成的解决方案的 Web 服务实现。
    • SOA 建模,第 4 部分: 服务合成。第四篇文章介绍了如何汇集并连接“第 3 部分. 服务实现”中建模的服务提供者,并编排它们的交互来提供针对商业需求的完整解决方案。结果的组件将成为组成 Invoicer、Productions,和 Shipper 组件所提供的,用来提供处理订购单的服务功能的服务的服务参与者。它还介绍了该服务参与者如何实现原始的商业需求。
    • SOA 建模,第 5 部分: 服务实现。在这系列的最后一篇文章中,作者介绍了如何创建一个与服务模型中所获取的架构和设计决策相一致的实际的实现。我们将通过利用模型驱动的开发和 IBM Rational Software Architect UML-to-SOA 的转换特性来由 SOA 模型创建 Web 服务来生成具体平台的实现。
  • 请您浏览:developerWorks 上的 SOA 和 Web 服务专区 来获得您所需要的资源,从而提高您在面向服务的体系结构方面的技巧。
  • 请您访问 IBM.com 上的 IBM Service-Oriented Architecture (SOA) 解决方案
  • 请您访问:developerWorks 上的 Rational 软件专区 来获得 Rational 软件交付平台产品的技术资源和最佳实践。
  • 请您订阅:developerWorks Rational 专区时事通讯 来保持同 developerWorks Rational 内容的同步更新。每周您都将收到有关 Rational 软件交付平台的最新技术资源和最佳实践的更新信息。
  • 请您订阅:Rational Edge 中文版 来获得有效性软件开发背后的相关概念的文章。
  • 请您浏览:技术书店 来获得这些技术和其他技术主题的相关书籍。
获得产品和技术

讨论


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织