内容


IBM WebSphere 开发者技术期刊

WebSphere Integration Developer 指导教程——第 2 部分

使用 WebSphere Integration Developer 进行 SOA 开发

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: IBM WebSphere 开发者技术期刊

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

此内容是该系列的一部分:IBM WebSphere 开发者技术期刊

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

摘自 IBM WebSphere 开发者技术期刊

以面向服务的方式构建应用程序

在本系列的第 1 部分中,我们通过介绍 IBM® WebSphere® Integration Developer 及其附带的各种工具,为您提供了该产品的概况。在第二篇文章中,您将了解编程模型以及工具使用环境。为将此主题的各个方面结合起来进行讨论,我们将描述一个简单的应用程序并演示如何使用 WebSphere Integration Developer 构建该应用程序。

相信您一定已经听说过面向服务的体系结构 (SOA) 这一术语。但什么是 SOA,以及更重要的问题,它对业务集成领域有什么好处?我们非常乐意回答您的问题。WebSphere Integration Developer 应用程序是通过面向服务的体系结构进行实现的,因此我们首先讨论什么是 SOA 以及遵循这种体系结构模式对于我们的应用程序会有何好处。

理想情况下,您希望能重用现有的 IT 资产作为构件或组件来构建新的应用程序。每个构件都是一个服务,这意味着您可通过标准方法来访问服务而不必关注其具体实现及其位置。在 SOA 中,业务逻辑从基础结构中被分离出来,因此开发人员可以把精力集中在实现上,而无需关注如何访问服务。

简而言之,服务是一些黑盒,您并不关注其内部情况,只要它们能够按照所声明的情况进行工作。一旦您拥有这些黑盒,接下来的关键步骤就是将它们连接起来构成完整的应用程序。这些黑盒可以是 Java™ 技术、业务流程执行语言 (BPEL)、到遗留系统的连接或适配器以及到业务合作伙伴所提供的 Web 服务的连接。它们就是您的服务构造块。

服务通常是无状态的,这意味着您无需担心是否按特定顺序或在具体的上下文中调用它们。而且,您可能打算要合成业务合作伙伴的服务,并以访问您自己服务的方式来访问它们。您还可能需要合作伙伴能够访问您的服务。通过 SOA,您可通过交换服务或调用新的所需服务,来方便地适应不断变化的业务环境。这使企业之间的业务交易变得更加方便。

访问服务的标准方式是什么?服务会发布其接口,这也是服务与调用方之间的协定。接口可通过某种语言进行定义,例如 Web 服务接口可通过 Web 服务定义语言(Web Services Definition Language,WSDL)进行定义。接口中包含向服务传递数据或从服务获取数据的规范。接口并不指定如何实现服务以及用什么语言来实现服务。因此,您可能具有使用 Java 实现的服务,而该服务又调用另一个使用 BPEL 实现的服务。

所有这些都是一般性的概述,听起来不错,但我们需要深入探讨如何使用 WebSphere Integration Developer 来实现面向服务的体系结构。在上一篇文章中,我们讨论了服务实现的各种方式,但对服务如何协同工作方面未作详细介绍。本文将深入介绍服务交互的详细内容。

应用程序的构造块

构造块是一种比喻说法,这对于我们理解面向服务的体系结构非常有帮助。通常情况下,您会将这些构造块堆叠在一起以构建较大的应用程序,而后者又可作为另一种构造块。通过这种方式来分析服务,就能容易地掌握 WebSphere Integration Developer 中的服务组件体系结构(Service Component Architecture,SCA)编程模型。SCA 是 SOA 的一个实现,而 WebSphere Integration Developer 是一个 Workbench,利用其提供的工具,您不仅可以直观地将构造块组装成完整的解决方案,还可以构建每个构造块的内部工作。SCA 标准化工作是 Apache Tuscany 开放源代码项目的一部分。在接下来的几部分中,将介绍关于使用服务组件体系结构对您要通过 WebSphere Integration Developer 构建的任何解决方案进行基础布局的基本知识。

模块

模块 是服务的容器,它既是 WebSphere Integration Developer Workbench 中的项目,也是 WebSphere Process Server 上的部署单元。这意味着您构建的任何解决方案都将作为一个或多个模块部署到服务器上。对那些熟悉 J2EE 的开发人员而言,模块是作为企业归档 (EAR) 文件进行打包和部署的。服务组件体系结构的优点之一是您无需关注底层的打包工作。模块提供的服务既可被其他模块使用,也可由合作伙伴或客户通过外部客户端来进行访问。模块是组件导入和导出的集合,我们将在以下几部分中进行介绍。

要创建模块,请在 Business Integration 视图中右键单击并选择 New - Module。系统将为您创建的模块生成新的组装图,您可使用组装编辑器来编辑此图。Business Integration 视图位于组装编辑器左侧(如果您没有移动该视图的话),其中显示所有项目构件。图 1 显示了新创建的模块。

图 1. 新模块
新模块
新模块

组件

模块是一种较大的粗粒度构造块,后者由称为组件的较小的细粒度构造块构成,组件 是实际服务模块的组成部分。在其内部是通过第一篇文章中所描述的实现类型之一进行实现的(我们将进行简单的概述)。例如,假设您具有一个订单处理模块。在该模块中,您可能具有一个用来更新库存信息系统的库存组件和另一个检查客户信用的组件。

您可在组装编辑器中创建组件,具体做法是在调色板上选择组件,然后将其放置在组装编辑器画布上。您还可在 Business Integration 视图中将实现接口拖到画布中以创建新的组件。这意味着您可通过自顶向下的方法先定义协定再定义实现来创建组件/服务,也可通过自底向上的方法在现有表面进行拖动来进行创建。

如果您只是在主界面中工作,并已从调色板中放置新的组件,它将显示在组装图中,如图 2 所示。蓝色感叹号表示实现尚未创建。在您创建组件时,您需要提供至少一个接口,这将在下一部分中讨论。记住,接口(协定)是其他服务所能看到或使用的内容,它们不会看到或关注您是如何实现服务/组件的。

图 2. 服务组件
服务组件
服务组件

接口

对于使用服务组件的用户,所关注的是组件的接口,因为它规定了组件的使用方式。接口 是有关组件操作的规范。操作 是服务组件提供的业务功能或查询。例如,假设您具有一个 EmployeeData 组件,该组件提供员工信息查询服务。它可能只提供单个操作,如 getEmployee,即您提供员工 ID,它将返回该员工的资料。它还可能提供其他操作,如 getRetiredEmployees 或 getCurrentEmployees,并返回员工资料集合。这些操作就是 EmployeeData 服务所提供的查询功能。

一个操作中包含输入、输出和错误。在员工示例中,getEmployee 指定其输入为一个字符串,其输出为员工资料。其他两种操作可能无需任何输入(当然您可传递一些诸如限制条件之类的数据)而返回员工资料集合。接口可选择性地指定在服务调用期间出错时所引发的任何错误。例如,getEmployee 可以定义为当内部机制无法定位具有某个 ID 的记录时引发 InvalidEmployeeID 错误。在某些情况下,操作可能不包含任何输入、输出或错误,例如操作只是简单地用来触发某个动作。

您可使用 WSDL 或 Java 来定义组件的接口。注意,在使用 Java 时,操作被称为方法,错误被称为异常。使用文本来创建 WSDL 接口无疑是非常繁琐的。WebSphere Integration Developer 中提供了接口编辑器以简化组件接口创建过程,如图 3 所示。

有时,您可能需要调用外部服务(如 Web 服务),因此您还可以从合作伙伴处将现有的 WSDL 接口导入到工作区中。

图 3. 组件接口
组件接口
组件接口

引用

因此,您需要声明您的服务组件将支持什么接口。不错,但是当您需要组件实现调用另外的服务该怎么做呢?那么,我们需要做两件事。首先,其他服务组件需要声明其自身接口,同时您自己的组件需要声明将调用什么接口。这样,当您将这些黑盒连接起来时,系统将能确保某种服务所需内容就是您正在连接的服务所提供的内容。现在,我们将介绍一些技术细节来使其更加清晰。

一个组件具有一个或多个引用。在您编写服务组件的实现时,切勿直接调用另外的服务组件,这样做会在您的代码中形成对其他组件的依赖关系。您的实现应该调用引用。引用 具有名称,表示其他服务所最终具有的那些接口。最后,在您将黑盒连接在一起时,也会将引用连接到另外的黑盒上。很快,您的实现不仅知道使用哪些引用,而且不会依赖于任何特定的组件。在您组装模块时,您可完全灵活地组装可重用的部件,前提是其引用与目标组件的接口相匹配。

例如,图 4 显示了来自业务流程实现内部对 Travel Agency Partner 引用的调用,图 5 显示了 SimpleProcess 组件中引用的定义和连线。因此,在对 Travel Agency Partner 进行调用时,将使用连线另一端的服务。

在组装编辑器中,您可右键单击某个组件,并选择 Add - Reference 以添加新的引用。这将打开对话框并允许您为引用选择适当的接口。

图 4. 使用引用的服务调用
使用引用的服务调用
使用引用的服务调用
图 5. 组件引用
组件引用
组件引用

连线

在前面使用构造块比喻时,我们提到要堆叠构造块。更准确地说,在服务组件体系结构中,是使用连线来连接构造块。连线 是指组装图中的连接,表示某个引用被连接到某个组件。例如,在图 5 中,SimpleProcess 的 Travel Agency Partner 引用被连线到 TravelAgency 组件。连线的源端的引用接口必须与目标组件的接口相符。连线的源端可以是一个导出,目标也可以是一个导入,这将在本文中的“导入和导出”部分进行介绍。

实现

服务组件的实现 是执行服务功能的内部业务逻辑。记住,服务调用方并不知道服务的具体实现方式。事实上,它们甚至不知道是谁在提供此功能。如果您使用的是自顶向下方法,则当首先创建组件和接口之后,可在组装图中右键单击某个组件并选择 Generate Implementation 来创建实现。您可从出现的子菜单中选择适当的实现类型,例如业务流程。您还可通过选择 File - New,然后选择如业务对象、人员任务等实现类型来先创建实现。然后,您可将实现从 Business Integration 视图拖到组装图中以自动创建组件。

表 1. 组件实现类型
实现类型目的
业务流程描述完成某些业务任务所需的一系列活动。它将协调整个任务中所包含的服务和子流程。
业务状态机事件驱动的业务流程,其中为应用程序的给定部分定义一系列的状态。根据所接收的外部事件,状态机将从某个有效状态转移到另一个有效状态。在状态转移时,它可执行任务或调用服务。
业务规则组根据一系列规则或决策表(部署后可动态更改)来捕获和实现业务策略以及实践。
人工任务由人工而不是程序完成的工作单元。
Java 在比直观实现(如业务流程)更低的层次上描述业务逻辑。
选择器通过日期和时间来确定使用哪个组件。这是一种类型略微不同的组件,因为它不具有对其选定的组件的引用。组件及其使用时间将在选择器内部进行编码
映射接口映射负责从某个接口转换成另一个接口,业务对象映射将某个业务对象转换为另一个业务对象。

导入和导出

在某些时候,您将需要把某些模块的工作委派给另外的模块乃至合作伙伴的服务。问题在于,您只能在组装编辑器中对同一模块中的组件进行连线。解决方法是使用导入。导入 与组件相同,但不具有实现。导入包含一个绑定,即有关如何连接到实际服务的信息。导入在此告诉您将前往模块外部并依赖其他位置的服务来完成工作。绑定可帮助识别其他服务的位置和内容。可使用以下绑定:

  • SCA,用于绑定到 WebSphere Integration Developer 组件
  • JMS,用于绑定到 Java 消息服务
  • 无状态会话 Bean,用于绑定到 Enterprise JavaBeans
  • Web 服务,用于绑定到 Web 服务

模块中的其他组件以同样方式使用导入(即创建对它的引用)。导入必须具有与所绑定的组件相同的接口。这意味着如果导入指示它将调用某个具有接口 1 的服务(无论是什么服务),则最终该服务将按照要求实现接口 1。

导出 用于将您的模块组件作为服务或其他模块向外公开。同样,由于您不能从外部连线到模块内部,因此需要使用导出。与导入类似,导出必须具有与它们所连线的组件匹配的接口。导出可包含与导入相同的绑定(除无状态会话 Bean 外)。使用 SCA 绑定,来自其他模块的组件可对您的模块组件发出服务调用。其他绑定允许其他应用程序调用您的组件,就像它们只是另一个 Web 服务或 JMS 一样。

例如,假设您具有信用记录服务,并且将其提供给需要进行访问的业务合作伙伴。您将创建一个导出,然后进行 Web 服务绑定并将其连线到您的信用记录组件,如图 6 所示。

图 6. 将组件作为 Web 服务导出
将组件作为 Web 服务导出
将组件作为 Web 服务导出

业务对象

如前一篇文章所述,业务对象 是组件内部及之间流动数据的容器。业务对象通常被称为应用程序中的货币。业务对象可通过业务对象编辑器创建,并在服务数据对象(Service Data Object,SDO)框架基础上进行构建,该框架允许您以标准方式访问实现中的业务数据。在您定义接口操作的输入和输出时,可选择业务对象。

业务图 是业务对象的扩展。它们包含附加的元数据,以及变更概要和事件概要信息,各种企业信息系统资源适配器中通常需要这些信息。图 7 显示了 EmployeeInfo 业务图,我们在图 3 的 getEmployee 操作中将其用作输出。这里的动词属性用于诸如“创建”或“删除”等命令,这在某些信息系统中会用到。例如,“Creat”的动词属性可告诉后端系统获取员工对象并在其数据库中创建相应记录。

图 7. 员工业务对象和业务图
员工业务对象和业务图
员工业务对象和业务图

使用构造块

现在,我们将结合上述概念,通过 WebSphere Integration Developer 并使用面向服务的体系结构来使用和构建应用程序。构建应用程序的总体步骤包括:

  • 创建包含所有应用程序构件的模块。
  • 创建库(库为 WebSphere Integration Developer 项目的另一种形式)来保存将在模块之间共享的构件。例如,如果您要在多个模块中共享相同的(货币)业务对象,可将这些业务对象放入共享库中。
  • 创建一般业务对象来包含将在每个组件中使用或在组件之间传递的数据。
  • 创建接口作为组件之间的协定。
  • 创建组件并添加其接口。
  • 为需要使用其他组件服务的组件添加引用。
  • 为每个模块外部的服务引用添加导入,并添加导出以使每个模块的服务对其他组件可用。
  • 将每个引用连线到组件或输入。
  • 使用业务流程、业务规则、中介等实现组件。

这些步骤未进行先后顺序编号。根据具体情况,您可按不同于上表的顺序来进行操作。例如,在创建的接口中可以使用后来将定义的业务对象类型。我们曾指出,有两种方式来构建应用程序,自顶向下方法和自底向上的方法。上表中顺序只是自顶向下的方法的一个示例。选择哪种途径取决于您是已经准备好应用程序的构件,还是完全从头开始。多数情况下,您会使用自顶向下方法完成应用程序的某些部分,并使用自底向上方法完成其他部分。并且,您可能选择使用一些快捷方法,例如拖动组件接口以在两个组件之间添加连线,以及让组装编辑器为您创建引用。

简单的订单处理应用程序

现在,我们来考虑如何构建一个订单处理应用程序。我们将以大致列出如何构建应用程序的总体步骤来结束本文,在下一篇文章中我们将列出构建的具体步骤并进行测试。

为了便于说明,我们假设订单处理系统的工作方式为:当系统接收到订单之后,它将使用客户检查组件来确定帐户是否存在。如果是,则系统将发送一条消息至配送部门告知将装运订单。或者,如果帐户不存在,则不进行任何处理。系统等待运输部门确认订单已装运的响应。这并不是完整的应用程序,但它可以满足对开发流程的演示要求。

该应用程序需要三个组件:OrderProcessing、Shipping 和 CustomerCheck,如图 8 所示。这些组件将包含在 OrderProcessing 模块中。CustomerCheck 组件依赖于某个企业信息系统以获取客户状态。实际的订单装运为手动处理,因此需要附加的组件来允许员工查看需装运的订单,并允许他们表明订单已于何时装运。图 8 中的编号表示接收到订单之后的执行顺序,这里假设客户已经存在。在下一部分之后,将介绍有关每个组件及其如何工作的细节。接下来的部分列出了组件所需的业务对象。

图 8. 简单的订单处理应用程序
简单的订单处理应用程序
简单的订单处理应用程序

Order 业务对象

图 9 显示了 Order 业务对象。当该对象类型的实例被传递给 OrderProcessing 模块时,它将包含完成客户检查和装运订单所需的全部信息。在实际的应用中,您可能需要创建独立的 Customer 业务对象来保存客户 ID 字符串之外的客户信息。

图 9. Order 业务对象数据类型
Order 业务对象数据类型

OrderProcessing 组件

OrderProcessing 组件是系统的入口点,它在从客户端应用程序接收到订单之后,驱动 OrderProcessing 模块。该组件接收到一个 Order 业务对象,其中包含订单信息以及客户帐号。OrderProcessing 组件使用该帐号通过 CustomerInformation 组件来确定对应的帐户是否存在。如果存在,它将向 Shipping 组件发送一条消息以装运订单。如果帐户不存在,则整个流程结束。

图 10 显示了 ProcessOrder 组件的接口。客户端调用 placeOrder 操作以开始订单处理。该操作以 Order 业务对象作为输入。我们只要求客户端能提供订单,然后执行其他工作,因此该操作是单向的。注意,外部客户端不能直接调用 placeOrder 操作,因为只有同一模块中的组件才能与其连线。这样,外部客户端必须使用连线到 OrderProcessing 组件的独立引用。当 ShippingProcess 组件需要发送订单已装运的消息时,它将调用 orderShipped 操作。

图 10. OrderProcessing 组件接口
OrderProcessing 组件接口
OrderProcessing 组件接口

由于 OrderProcessing 组件是事件驱动的,即由正在处理的订单状态确定所允许的操作,我们将使用业务状态机来进行实现,如图 11 所示。这些事件包括:

  • 订单回执(客户端调用 placeOrder 操作)
  • 通知订单已装运(装运系统调用 orderShipped 操作)

这些状态包括:

  • 等待订单
  • 正在检查客户
  • 正在装运订单
  • 订单完成
图 11. OrderProcessing 业务状态机
OrderProcessing 业务状态机
OrderProcessing 业务状态机

在状态机中有多种方式对此应用程序进行建模,由于我们假设当接收到订单时,它将在转移到 CustomerBeingChecked 状态时自动触发客户检查,因此我们选择这种建模方式。检查结果自动触发到 OrderBeingShipped 或 OrderComplete 状态的转换,具体取决于在 CustomerBeingChecked 状态时调用 CustomerCheck 服务返回的结果值。在处于 OrderBeingShipped 状态时,Shipping 组件调用 ShippingProcess 组件的 shipOrder 操作。当接收到来自 Shipping 组件订单已装运通知时,系统自动转换到 OrderComplete 状态。

CustomerInformation 组件

图 12 显示了 CustomerInformation 组件的接口。该组件确定具有给定 customerID 的客户是否存在。

图 12. CustomerInformation 接口
CustomerInformation 接口
CustomerInformation 接口

我们使用一种简单规则来判断其是否存在:如果客户 ID 是以“gold”开头,则客户自动被认为是“存在”的。否则,客户信息系统被选中并返回其状态。该规则可以进行更改。在应用程序之后可添加额外的规则,这时该组件可使用规则组进行实现。

我们假设信息保存在某个外部企业信息系统中,并且另外的模块将包含访问该系统所需的组件。因此,该模块将使用导入而不必定义实现。在该模块中,组件的导出将包含同导入相同的 CustomerInformation 接口。

Shipping 和 ShippingTask 组件

图 13. Shipping 接口
Shipping 接口
Shipping 接口

图 13 显示了 Shipping 接口。该组件实现为业务流程,因为活动需按顺序执行。第一个活动发送订单已装运的通知到 ShippingTask 组件,该组件接口如图 14 所示。ShippingTask 组件实现为人工任务,因为需要某个人来进行订单装运。ShippingTask 组件将订单信息转发到 Web 门户,这样员工可以查看订单信息、装运订单以及对某些订单信息(如数量)进行可能的更改,然后指示订单已装运。

您可使用 IBM Rational® Application Developer 来创建 Web 门户,或者对于初学者,只需使用 WebSphere Process Server 附带的 Business Process Choreographer Explorer 作为您自己的门户即可。当组件接收到来自门户的订单已装运的通知之后,它将更新的 Order 业务对象返回至装运业务流程。

图 14. ShippingTask 接口
ShippingTask 接口
ShippingTask 接口

在 ShippingTask 组件完成其工作之后,Shipping 流程的下一活动将通过调用 orderShipped 操作发送一条消息至 OrderProcessing 组件。

完整的 OrderProcessing 模块

图 15 显示了 OrderProcessing 模块中组件是如何连线在一起的。

图 15. OrderProcessing 模块中组装的组件
OrderProcessing 模块中组装的组件
OrderProcessing 模块中组装的组件

总结

在本文中,我们介绍了 WebSphere Integration Developer 中的服务组件体系结构编程模型。然后,我们通过演示简单的订单处理模块的构建过程将这些概念融合在一起。在下一篇文章中,我们将介绍构建模块的详细步骤,并对每个步骤进行说明以帮助您完全理解如何使用 WebSphere Integration Developer 进行应用开发。


相关主题


评论

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere, SOA and web services
ArticleID=111644
ArticleTitle=IBM WebSphere 开发者技术期刊: WebSphere Integration Developer 指导教程——第 2 部分
publish-date=05112006