内容


IBM WebSphere 开发者技术期刊

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

构建面向服务的简单应用程序

Comments

系列内容:

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

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

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

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

引言

本系列的前一篇文章讨论了 WebSphere Integration Developer 的基本概念及其提供的一套工具。在该文中,我们还了解了使用面向服务的体系结构构建订单处理应用程序 (OrderProcessing) 的主要步骤。您可能此时尚未读过上一篇文章,或者已经读过了,但却记不清所有细节。不用担心,在深入了解如何实现应用程序的服务前,我们将简要进行一下回顾,从而为进行一步讨论奠定基础。

订单处理应用程序 (OrderProcessing) 从外部客户接收订单信息。然后将检查客户的声誉是否良好(最好是极为富有),如果是,则将订单转发到配送部门。当配送部门确认了订单已配送后,将输出一条消息。

要实现此应用程序,我们需要一个表示订单信息的业务对象。业务对象有时候被称为应用程序的货币,因为所有的服务都要使用业务对象。谈到服务,我们还将需要用于检索订单、检查客户信息和配送订单的服务。这些服务在图 1 中表示为三个黑框。

图 1. 一个简单的订单处理应用程序
一个简单的订单处理应用程序
一个简单的订单处理应用程序

在前一篇文章中我们了解到,可以在不知道任何服务的实际实现细节的前提下定义每个服务,并将其连接到一起。为此,我创建了一个模块 (OrderProcessing Module),然后再创建每个服务。接下来,我们标识了每个服务将支持的接口,以及其计划调用的每个其他服务的接口。最后,我们根据服务间的调用关系将各个服务连接到一起。此方法极为有用,因为它允许采用自顶向下方法设计整个应用程序,而在完成整个体系结构前都不必担心每个服务的实现。事实上,我们可以让一个设计人员设计整个面向服务的体系结构的布局,而让每个团队成员基于架构师所指定的契约(接口)实现其中的一个服务。

将要学习的内容

现在我们已经对订单处理应用程序进行了回顾,接下来就要开始着手进行构建工作了。

在以下的部分中,您将了解如何完成以下任务:

  1. 创建模块来承载将创作的所有构件。
  2. 创建业务对象来标识客户订单。
  3. 创建组件及其接口。
  4. 将组件连接到一起。
  5. 指定这些组件的实现。
  6. 在 WebSphere 测试环境中部署并测试所构建的内容。

创建 OrderProcessing 模块项目

要开始构造应用程序,将需要一个项目来承载业务对象、组件和接口。我们将创建的项目是服务组装模块项目(简称模块项目)。这是一种特殊的项目类型,可识别不同构件类型(业务对象、组件等),并能在 WebSphere Process Server 上部署和运行。

模块项目与图 1 中外部的蓝色大框对应。请注意,所有组件、接口和连接线都包含在蓝色大框中,因此将全部包含在我们的新项目模块中。

闲话少说,让我们马上开始进行实际的构建工作。

  1. 确保打开了 Business Integration 透视图。
  2. 右键单击 Business Integration 视图,并选择 New > Module
  3. 在 New Module 向导中输入 OrderProcessing 作为模块名称。
  4. 单击 Finish

WebSphere Integration Developer 将创建名为 OrderProcessing 的项目,如图 2 中所示。您可能还记得,我们在本系列的前一篇文章中讨论的不同类型的组件。Business Integration 视图会基于其类型对组件进行归类:流程组件、状态机组件等。与此类似,将基于类型对资源进行归类:业务对象位于 Data Types 下,而每个组件的接口位于 Interfaces 下。Business Integration 视图基于类别的结构非常便于查找特定类型的构件。Business Integration 视图还提供其他几个用于排序和导航构件的选项。

图 2. OrderProcessing 项目
OrderProcessing 项目
OrderProcessing 项目

创建 Order 业务对象类型

在本部分中,我们将创建业务对象来保存订单信息。Order 业务对象将在组件执行业务逻辑时在组件间进行传递。Order 业务对象将包含以下特性:

  • 订单号
  • 产品 ID
  • 订购数量
  • 下订单的客户的标识符

产品 ID 和客户 ID 可以包含文字数字数据,因此将为 string 类型。订单号和数量将为 int 类型,因为其中将仅包含整数。

要创建 Order 业务对象,请按照以下步骤进行操作:

  1. 在 OrderProcessing 项目中右键单击 Data Types 类别,并选择 New > Business Object
  2. 在 New Business Object 向导的 Name 字段中输入 Order,其余字段保留缺省值,并单击 Finish

现在已经有了业务对象,接下来要创建一些特性来保存订单信息。创建特性的操作非常方便而快捷:

  1. 确保在 Business Object Editor 中选中了 Order 业务对象。创建业务对象时,将缺省选中该业务对象。
  2. 要创建四个特性,请右键单击 Order 对象,并选择 Add Attribute。重复此操作三次。
  3. 选择 attribute1(第一个缺省名称),并将其替换为 orderNumber。单击缺省的 string 类型,并从类型列表中选择 int
  4. attribute2 重命名为 quantity,并将其类型更改为 int
  5. attribute3 重命名为 productID,并保留 string 类型。
  6. attribute4 重命名为 customerID,并保留 string 类型。
  7. 保存更改。

关闭编辑器前,让我们对其进行进一步的了解。编辑器的顶部(请参阅图 3)显示了业务对象的主要元素。我们可以使用这个区域来编辑业务对象的常见属性,包括每个特性的名称和类型。该编辑器使用 Properties 视图来显示业务对象更为高级的属性和特性。例如,可以在 Properties 视图中将特性限制为一组允许值。

图 3. 已完成的 Order 业务对象类型
已完成的 Order 业务对象类型
已完成的 Order 业务对象类型

利用 Properties 视图提供的完善的属性选择功能进行了相应操作后,请关闭 Order 的 Business Object Editor 窗口。

继续之前,让我们简单了解一下 Business Integration 视图(通常位于工作台的左上角)。应该能在 Data Types 类别下看到新创建的 Order 业务对象。我们应用程序现在就有了货币。

创建组件和接口

接下来我们要创建组件(服务),还要定义其将支持的接口和将调用的其他组件的接口。我们将实现以下组件和接口:

  • ProcessOrder 组件和接口
  • CustomerCheck 组件和接口
  • ShippingProcess 组件和接口
  • ShippingTask 组件和接口
  • CustomerInformation 导入
  • OrderProcessing 导出

ProcessOrder 组件

我们将首先创建 OrderProcessing 组件(请参阅图 1),以接收订单和开始处理订单。

  1. 在 Business Integration 视图中,通过在 OrderProcessing 项目下双击 OrderProcessing 来打开 Assembly Editor。
  2. 右键单击 Assembly Editor,并选择 Add Node - Component (with no implementation type)
  3. 右键单击我们刚刚创建的组件,并选择 Rename。将名称 Component1 更改为 ProcessOrder

图 4 显示了已完成的 ProcessOrder 组件。将显示警告标志 警告标志,因为组件尚没有实现。不要着急,我们并不完全知道将如何实现组件,也不应该知道这一点。我们仅仅在尝试确定应用程序的各个片段,并确定在应用程序的大环境中它们各自将进行什么工作。

图 4. ProcessOrder 组件
ProcessOrder 组件
ProcessOrder 组件

此时,您需要问自己“那么,这个组件需要能完成什么工作呢?”正如我们在应用程序概述中所说的,ProcessOrder 组件将基于其接收到的订单信息下订单。当对订单进行了配送之后,该组件将输出一条消息。这意味着我们能够告知此组件下订单,还必须让其知道订单已配送。捕获这个要求很简单,我们只需要为该组件创建一个接口,并标识其将支持的两个操作即可。

ProcessOrder 接口

ProcessOrder 接口有两个操作 placeOrder 和 orderShipped。这两个操作都以一个 Order 业务对象作为输入参数。placeOrder 并不会返回任何值,因为我们仅需要其启动订购过程。与此类似,orderShipped 操作也不会返回任何值,因为仅需要在被告知订单已配送后输出一条消息。

要为 ProcessOrder 组件创建接口,请执行以下步骤:

  1. 在 OrderProcessing 项目中右键单击 Interfaces 类别,并单击 New - Interface
  2. 在 New Interface 向导的 Name 字段中输入 ProcessOrder,并保留其他缺省值。
  3. 单击 Finish
  4. 在随即打开的接口编辑器中单击右键,并选择 Add One Way Operation
  5. 选择缺省 operation1 名称,并将其替换为 placeOrder
  6. 右键单击 placeOrder 操作并选择 Add Input
  7. 将名称 input1 更改为 order,然后单击 Type 单元格(其值为 string)。如图 5 中所示,将打开类型列表,其中包含您前面创建的 Order 类型。选择 Order 作为类型。
    图 5. 创建 ProcessOrder 接口
    创建 ProcessOrder 接口
    创建 ProcessOrder 接口
  8. 添加另一个单向操作,并将名称 operation2 更改为 orderShipped
  9. orderShipped 添加一个输入,将其重命名为 order,并选择 Order 作为类型。

在前面的步骤中,我们选择的是单向操作。可以选择两种操作类型,单向操作和请求-响应型操作。单向操作对应于不希望服务返回结果的情况。而请求-响应操作则用于希望与服务进行双向通信时,如需要发送查询并获取信息时,或希望发送消息启动一个操作,但需要得到响应来了解是否已成功进行了操作时。

现在可以开始为 ProcessOrder 组件准备接口了:

  1. 切换回组装关系图,右键单击 ProcessOrder 组件,并选择 Add - Interface
  2. 从接口列表中选择 ProcessOrder

现在就已经指定了第一个组件。请注意,我们仍然未实现此组件,而仅仅标识了其将完成的工作。接下来处理下一个组件。

CustomerCheck 组件和接口

将创建的下一个组件是 CustomerCheck。此组件负责接收客户 DI 并确认客户处于良好的信誉状态。这意味着定义其接口时,该组件将需要一个名为 checkCustomer 的操作。我们将需要使用此操作来返回关于客户是否处于良好信誉状态的信息。请按照以下步骤进行操作,以创建 CustomerCheck:

  1. 切换回组装关系图,并采用与处理 ProcessOrder 组件时相同的方式创建 CustomerCheck 组件。
  2. 重复前面创建 OrderProcessing 的部分中的步骤 1 到 13,以创建新接口,并将其命名为 CustomerCheck

完成了接口的创建后,接下来将添加检查客户信誉状态的操作:

  1. 在接口编辑器中单击右键,并选择 Add Request Response Operation
  2. 将名称从 operation1 更改为 checkCustomer
  3. 添加一个输入,将其名称更改为 customerID,并将类型保留为 string

请注意,我们并没有向此组件传递整个 Order 业务对象。这是因为组件仅需要客户 ID 就能检索客户的信誉状态了。接下来,让我们确保该操作返回客户信誉状态是否良好的信息:

  1. 单击右键并选择 Add Output,以添加一个输出。将名称更改为 customerOK 并选择 boolean 类型。
  2. 切换回组装关系图,并采用与向 ProcessOrder 组件添加接口相同的方式将 CustomerCheck 接口添加到 CustomerCheck 组件。

图 6 显示了已完成的 CustomerCheck 接口。

图 6. 已完成的 CustomerCheck 接口
已完成的 CustomerCheck 接口
已完成的 CustomerCheck 接口

由于 ProcessOrder 组件使用 CustomerCheck 所提供的服务,因此需要将 ProcessOrder 连接到 CustomerCheck。

  1. 使鼠标悬停在 ProcessOrder 组件的边缘上。将出现一个黄色的手柄。单击该手柄,并将其拖动到 CustomerCheck 组件。
  2. 将提示在源节点 (ProcessOrder) 上创建一个匹配引用。单击 OK,并从 Add Reference 对话框中选择 CustomerCheck 接口。

以前说过,当组件对其他组件进行服务调用时,将会使用引用达成此目的。在最后一步中,将自动为您创建引用。

ShippingProcess 组件和接口

下一个要创建的组件是 ShippingProcess,该组件将提供 ProcessOrder 组件所需的另一个服务。此组件负责协调订单配送和通知配送部门为订单分配特殊的配送 droid。为了完成此任务,我们需要 ShippingProcess 组件支持包含处理订单配送工作的操作的接口。

  1. 按照与前面相同的方式创建名为 ShippingProcess 的组件。
  2. 使鼠标悬停在 ProcessOrder 组件的边缘,并将手柄拖动到刚刚创建的 ShippingProcess 组件。出现询问是否创建匹配引用的提示时,请单击 OK
  3. 尚未为 ShippingProcess 组件创建接口,因此不要在 Add Reference 对话框中选择现有接口,而要单击 New
  4. 在随即打开的 New Interface 向导中,输入 Shipping 作为其名称,并单击 Finish。这将关闭向导并回到 Add Reference 对话框。
  5. 在 Add Reference 对话框中,会缺省选中刚刚创建的 Shipping 接口,因此直接单击 OK

现在需要屏住呼吸看看我们刚刚完成的操作——这些步骤肯定与处理前一个不同!

我们之前采用的方式是这样的,创建新组件,并直接将现有组件连接到该组件。WebSphere Integration Developer 会非常“善解人意”地以动态方式创建一个新引用和接口。您并不需要首先关闭对话框并创建接口;相反,WebSphere Integration Developer 将创建一个空接口,因此可以继续进行处理,并在稍后对接口进行内容填充。

下面就让我们进行此工作。Shipping 接口需要一个单向操作 shipOrder,该操作以一个 Order 业务对象作为输入。该操作将向 Shipping department 组件发送一条消息,以便通知配送部门发送订单。

要创建此操作,请按照以下步骤进行操作:

  1. 在 Business Integration 视图的 Interfaces 类别下,双击 Shipping 接口。这将在接口编辑器中打开 Shipping 接口。
  2. 添加名为 shipOrder 的单向操作。
  3. 添加名为 order 的输入,并将其类型设置为 Order。图 7 显示了已完成的 Shipping 接口。
    图 7. Shipping 接口
    Shipping 接口
    Shipping 接口
  4. 配送流程结束时,需要向 OrderProcessing 组件发送消息,以通知后者订单已完成。因此,将需要另一个连接,以从 ShippingProcess 连接回 ProcessOrder 组件。

    ShippingProcess 组件连接到 ProcessOrder 组件,并单击 OK 来创建引用。

由于 ProcessOrder 已经有了接口,因此这里的工作就告一个段落了。

ShippingTask 组件和接口

接下来,我们将创建 ShippingTask 组件及其接口。ShippingTask 提供了一个服务,以便在 ShippingProcess 组件希望创建必须人工完成的任务(或在我们示例中的特殊配送 droid)时进行调用。

ShippingTask 接口需要一个请求-响应操作 shipOrder,该操作以一个 Order 业务对象作为输入。该操作用于将订单数据发送给配送部门中将对订单进行配送的人员(友好 droid)。将从 ShippingTask 返回订单数据。以后我们可能会希望 shippingTask 在返回订单前对其进行修改(例如,为了指示实际配送的数量)。

要创建人工任务及其接口,请执行以下步骤:

  1. 创建另一个名为 ShippingTask 的组件。
  2. ShippingProcess 组件连接到 ShippingTask 组件,单击 New 创建新接口,并将其命名为 ShippingTask
  3. 在 New Interface 向导中单击 Finish,然后在 Add Reference 对话框中单击 OK
  4. 打开 ShippingTask 接口,并添加名为 shipOrder 的请求-响应操作。
  5. 添加名为 order 的输入,并将其类型设置为 Order
  6. 添加名为 completedOrder 的输出,也将其类型设置为 Order

图 8 显示了已完成的 Shipping 接口。

图 8. ShippingTask 接口
ShippingTask 接口
ShippingTask 接口

希望您现在已经认识到,设计应用程序的面向服务的体系结构的过程非常方便而快捷。只需要将服务(组件)拖放到画布上,定义您希望其进行的工作,并将各个框连接到一起。将一只手绑在背后也能轻松完成!

CustomerInformation 导入和 OrderProcessing 导出

现在已经完成了 OrderProcessing 模块的主要部分。剩下的就是将其连接到外部世界。在此部分,我们将演示如何添加导入和导出来达成此目的。

  • 导入将允许 CustomerCheck 组件使用外部客户信息系统的服务。
  • 而导出将允许外部客户机将订单信息发送到 ProcessOrder 组件。

CheckCustomer 组件需要调用外部信息系统,该系统中包含所有的客户数据。为了连接到外部系统,我们必须使用导入。导入指示不会调用模块中的另一个组件,而将调用该应用程序之外的对象——即我们尝试与整个面向服务的集成解决方案集成的对象。

第二篇文章中我们说过,导入包含指向实际外部实现的绑定。请执行以下步骤,以创建导入。然后,将在本文的实现部分创建绑定。

  1. 在 Assembly Editor 画布上,右键单击画布,并单击 Add Node > Import
  2. 将名称更改为 CustomerInformation
  3. 右键单击 CustomerInformation 导入,单击 Add Interface,然后从接口列表中选择 CustomerCheck(使用 CustomerCheck 组件创建的此接口)。
  4. CustomerCheck 组件连接到 CustomerInformation 导入。

继续讨论之前,有必要说明一下,我们为 CustomerCheck 和 CustomerInformation 使用了相同的接口。这是因为 CustomerCheck 将检索客户 ID,执行业务逻辑,然后使用相同的 ID 和操作类型调用外部系统,以检查客户是否有效。我们也可以为组件和导入使用不同的接口,但本文为了简单起见,选择了使用相同的接口。

正如第二篇文章中讨论的,导入必须绑定到另一个模块、Web 服务、Java™ Message Service(JMS) 目的地或 EJB 组件。通过使用集成测试客户机,您仍然能在不定义导入绑定的情况下测试该模块。因此,为了简单起见,可以忽略选择绑定。

要创建导出,您需要执行以下步骤:

  • 右键单击 ProcessOrder 组件,并单击 Export - SCA Binding

此步骤将为组件创建导出,允许从外部源调用此组件。所选择的绑定取决于计划如何访问组件。在 使用服务组件体系结构构建 SOA 解决方案——第 1 部分 中提供了使用导出的示例(这篇文章描述如何使用 JSP 调用组件)。

已完成的组装应与图 9 中所示类似。现在已完成了应用程序框架。接下来将为每个组件定义实现。

图 9. 已完成的 OrderProcessing 组装
已完成的 OrderProcessing 组装
已完成的 OrderProcessing 组装

实现 ProcessOrder 组件

尽管我们已经设计好了组件拓扑,但尚未确定将要实现多少组件。开始进行实现非常简单;直接选择一个组件,并为其选择一个实现类型即可。WebSphere Integration Developer 将创建一个框架实现,您的工作就是直接在其中填充业务逻辑。

我们决定使用业务状态机来实现 ProcessOrder 组件。业务状态机是一种特殊的业务流程类型,因为它是事件驱动的,其操作取决于流程当前的状态。在我们的示例中,我们将使用其来建模订单在达到、正在配送、已配送的整个过程中的状态。

  1. 在组装编辑器中右键单击 ProcessOrder 组件,并单击 Generate Implementation - State Machine
  2. 将随即打开一个对话框,询问应将状态机放置在哪个文件夹中。确保选择了 OrderProcessing,然后单击 OK

将随即打开 State Machine editor,其中包含一个简单的状态机。如图 10 中所示,从初始状态到第一个状态的转换上有一个错误标记,因为尚没有操作触发转换。也就是说,我们需要标识让状态机运转的操作。

图 10. 新创建的 ProcessOrder 业务状态机
新创建的 ProcessOrder 业务状态机
新创建的 ProcessOrder 业务状态机

请注意右侧的引用:这些引用是在创建状态机时基于添加到 ProcessOrder 组件的引用自动添加的。将使用这些组件调用其他服务。

首先,我们将使用更为恰当的名称重命名初始状态和结束状态。

  1. 在 State Machine editor 中,单击缺省名称 State1,并将其替换为 CustomerBeingChecked
  2. 以同样的方式将 InitialState1 更改为 WaitingForOrder
  3. FinalState1 重命名为 OrderComplete

接下来,让我们添加更多的状态来帮助跟踪何时在检查客户以及何时在忙于配送订单。

  1. 右键单击画布,并单击 Add > State,然后单击画布,以添加新状态。
  2. State2 重命名为 OrderBeingShipped
  3. 右键单击 CustomerBeingChecked 状态并选择 Add - Transition
  4. 光标下出现线条时,请单击 OrderBeingShipped 状态。这将创建从 CustomerBeingChecked 到 OrderBeingShipped 的新状态转换。
  5. 采用相同的方式添加从 OrderBeingShipped 状态到结束状态的转换。

您的状态机应该与图 11 中所示类似,具体取决于放置每个状态的位置。看待这个问题的最简单方法是,记住状态机是用于尽力真实地建模应用程序在处理订单时将要经历的状态的方法。应用程序的状态为等待订单、检查客户、配送订单或订单已完成之一。

图 11. ProcessOrder 组件状态
ProcessOrder 组件状态
ProcessOrder 组件状态

在下面的步骤中,我们将定义状态间转换的触发器。我们首先建立告知订单已配送时出现的状态转换:

  1. 右键单击 OrderBeingShippedOrderComplete 间的转换,并选择 Add Operation
  2. 再次右键单击相同的转换,并选择 Show in Properties
  3. 在随即打开的 Properties 视图中,从 Interface 列表中选择 ProcessOrder,然后在 Operation 列表中选择 orderShipped。这意味着调用 ProcessOrder 组件的 orderShipped 操作时,将触发 OrderBeingShipped 和 OrderComplete 间的转换。
  4. 要处理的下一个转换是接收到指示需要处理订单的通知时的状态转换。仍然在 Properties 视图中,选择 WaitingForOrderCustomerBeingChecked 的转换,在 Interface 列表中选择 ProcessOrder,并选择 placeOrder 操作。

从 CustomerBeingChecked 开始有两个转换。一个转换将与信誉状态良好的客户相关,此时可以配送订单。另一个转换将用于处理我们不太喜欢的客户。在这种情况下,我们希望结束订单,并祝客户愉快。

状态转换并不一定要基于接收消息的状态机组件出现。还可以基于其他条件自动出现转换。在本例中,我们将基于客户的信誉状态进行转换。

  1. 首先,需要一个变量来保存客户信息检查的结果(即客户信誉状态)。右键单击 State Machine editor 右侧的 Variables 部分,并单击 Add Variable
  2. 在随即打开的 Data Type Selection 对话框中,输入 isCustomerOK 作为变量名,并从类型列表中选择 boolean

接下来,我们将为信誉状态良好的客户(将为其配送订单)定义转换。为了帮助编写操作,WebSphere Integration Developer 包含了一个可视代码片段编辑器。我们将使用此编辑器来编写代码,以填充订单和 ID 变量,并将一些信息输出到日志中。

  1. 请确保 Properties 视图仍然打开(如果尚未打开,请单击工作台底部的 Properties 视图),并选择 CustomerBeingCheckedOrderBeingShipped 的转换。
  2. 缺省情况下,转换类型设置为 Automatic,这是我们所需要的类型。单击 Properties 视图的 Condition 选项卡,然后单击 Create
  3. 在随即打开的可视编辑器中,单击右侧的 isCustomerOK 变量,并将其拖动到编辑器画布上。
  4. 右键单击画布,并单击 Add - Return,然后再次单击画布。
  5. 在画布上右键单击 isCustomerOK 变量,选择 Add - Link,然后单击返回表达式。
  6. 将条件名称从 Condition1 更改为 Good Customer,并保存编辑器内容。

这些步骤将创建一个表达式,此表达式将根据 isCustomerOK 的值为条件返回 true 或 false。当条件计算为 true,将出现转换。请注意,将会有一个错误标记,指示“因为另一个转换将始终出现,此转换不会出现”(the transition will not occur because another transition will always occur)。我们将稍后解决此问题。

下面的步骤处理信誉状态不好的客户,并修复错误标记。

  1. 选择 CustomerBeingCheckedOrderComplete 之间的转换,然后单击右键,并选择 Add - Condition。确保打开了 Properties 视图的 Details 选项卡。
  2. 重复前面的步骤 3 到 6,不过这次要将条件名称更改为 Bad Customer。这会创建与 Good Customer 条件一样的表达式。
  3. 因为希望只要 isCustomerOK 为 false,即触发此转换(即与 Good Customer 条件相反),所以请单击 Invert Result 复选框。

现在已经拥有了所有的状态和转换。下一步是定义在每种状态下应该发生的操作。处理订单所需的信息包含在 placeOrder 操作的输入中。

您需要将订单信息存储在变量中,以便能将其发送到状态机处理订单时调用的服务。您还需要将订单包含的客户 ID 存储在另一个变量中,以便将其发送给 customerCheck 组件。

下面的步骤将创建这些变量并为其赋值,还将添加日志记录语句,以便了解在计算机运行时发生的情况。

  1. 右键单击 Variables 部分,并选择 Add Variable,以创建另一个变量。输入 myOrder 作为名称,并选择 Order 作为类型。
  2. 再创建一个名为 myCustomerID 的变量,且将其类型设置为 string

现在我们需要创建转换上的操作,并使用这些变量。

  1. 右键单击 WaitingForOrderCustomerBeingChecked 的转换,并选择 Add - Action。此操作将允许定义转换出现(调用 placeOrder 操作的结果)时发生的动作。
  2. 在 Properties 视图中将名称更改为 Print info and set variables

我们将再次使用可视代码片段编辑器定义操作:

  1. 要开始定义操作,请单击 Details 选项卡、
  2. 右键单击画布,并选择 Add - Expression,然后单击画布。
  3. 在 expression 框中输入文本 "Order has been placed. Setting Variables."(包括引号)。
  4. 右键单击画布,并选择 Add - Standard,然后选择 Utility - Print to log
  5. 单击画布,然后右键单击文本表达式,选择 Add - Link,然后单击“Print to log utility”,从而将字符串表达式连接到日志表达式。
  6. placeOrder_Input_order 变量拖动到画布上(这将包含调用 placeOrder 操作时接收到的输入)。
  7. 拖动 placeOrder_Input_order 变量,然后在变量名尾部单击,这将显示一个列表。在列表中展开 placeOrder_Input_order 并选择 customerID
  8. myOrder 变量拖到画布上,然后将 placeOrder_Input_order 连接到该变量。这会将接收到的订单数据赋值给 myOrder 变量。
  9. myCustomerID 变量拖到画布上,然后将 placeOrder_Input_order.customerID 连接到该变量。

所显示的详细信息应与图 12 中所示类似。

图 12. Print info and set variables 操作
Print info and set variables 操作
Print info and set variables 操作

下一步是在订单进入 CustomerBeingChecked 状态时调用检查客户信息的服务。为此,我们将使用一个之前自动创建的引用。请记住,这是指向其他组件的引用。我们将使用前面创建的变量。

  1. 右键单击 CustomerBeingChecked 状态,并选择 Add - Entry
  2. 将项名称更改为 Check Customer。在 Properties 视图的 Details 选项卡中单击 Invoke。当出现消息,提示将丢失所有更改时,单击 Yes
  3. Reference 列表中选择 CustomerCheckPartner。此引用是在创建从 ProcessOrder 组件到 CustomerCheck 组件的连接时创建的。.
  4. 从 Operation 列中选择 checkCustomer 操作。这是 CheckCustomer 接口中唯一的操作。
  5. 在 Variables 框中选择 myCustomerID,并在 Operation Input 框中选择 customerID
  6. 单击 Set。您刚刚指定了 checkCustomer 操作的输入来自 myCustomerID 变量。
  7. 要将服务的返回值(一个 boolean 值)赋值给 isCustomerOK,请单击 Output 参数按钮,然后分别单击 Operation 输出框中的 customerOK 和 Variables 框中的 isCustomerOK。单击 Set

状态项现在应与图 3 中所示类似。

图 13. CustomerBeingChecked 状态项中的服务调用
CustomerBeingChecked 状态项中的服务调用
CustomerBeingChecked 状态项中的服务调用

下一步是在处于 OrderBeingShipped 状态时添加对配送组件的服务调用。其步骤与为 CustomerBeingChecked 状态创建项操作的步骤相同:

  1. 按照与前面步骤相同的方式,右键单击 OrderBeingShipped 状态,选择 Add - Entry,将名称更改为 Ship Order,然后为实现选择 Invoke。当出现消息,提示将丢失所有更改时,单击 Yes
  2. 对于 Reference 和 Operation,请分别选择 ShippingPartnershipOrder
  3. 对于 shipOrder 输入,分别在 Variables 和 Operation input 列表中选择 myOrdershipOrder,然后单击 Set。此操作是单向操作,因此不需要设置输出。

您可以已经注意到,在构建状态机时始终有以下错误:Correlation set must have at least one property。当部署到服务器时,您的状态机可以具有多个实例,每个实例处于不同的状态中。当对 ProcessOrder 组件调用操作时,需要能够对正确的实例进行调用。这将通过使用相关集 来实现。相关集告知状态机对于给定的输入数据使用哪个正在运行的实例。为此,它将使用指定的字段作为唯一标识对应流程实例的键来对输入数据的内容进行检查。

在 OrderProcessing 状态机中,订单号将确定使用哪个实例。将在以后讨论业务流程的文章中对相关集进行更为详细的讨论。

  1. 在 State Machine editor 画布的空白位置单击鼠标,选择 Show in Properties,然后选择 Correlation 选项卡。
  2. 单击 New,并在随即打开的 Edit Correlation Property 对话框中输入 OrderNumber 作为名称。
  3. 单击 Browse,并选择 int 作为类型。
  4. 单击 Aliases 旁边的 New。这将打开 Property Alias Selection 对话框。
  5. 在对话框底部展开 placeOrder input,向下找到 orderNumber 并选择它,然后单击 Add
  6. 再次单击 New,并展开 orderShipped input,向下找到 orderNumber 并选择它,然后单击 OK。
  7. 单击 OK,以完成相关集。

您刚刚指示,作为其中任一操作的输入的任何 Order 业务对象的 orderNumber 特性都是 OrderNumber 相关的别名。这意味着 Order 业务对象内包含的 orderNumber 将确定哪个状态机实例将接收 placeOrder 消息。

这就完成了 ProcessOrder 组件的工作。为了简单起见,我们并未包含处理对当前状态无效的操作调用等情况的错误处理。可以直接添加更多的打印语句,以便在测试应用程序时能够了解状态机执行时发生了什么情况:

  1. 右键单击 Bad Customer 转换,选择 Add - Action,然后将名称更改为 Print Info
  2. 在属性 Details 选项卡中,右键单击画布,选择 Add - Expression,然后将一个新表达式拖动到画布上。在 expression 框中输入 "Order has been rejected."(包括引号)。
  3. 再次右键单击画布,并选择 Add - Standard,然后选择 Utility - Print to log
  4. 单击画布,将字符串表达式连接到日志表达式。
  5. 重复前述步骤,创建另一个名为 Print Info 的操作,该操作将为 orderShipped 转换输出 "Order has been shipped.",而为 Good Customer 转换输出 "Order will be shipped."
  6. 向 OrderComplete 状态添加最后一个项操作 Print Info,以输出 "Order is complete."

已完成的 ProcessOrder 状态机现在应与图 14 中所示类似。

图 14. 已完成的 OrderProcessing 业务状态机
已完成的 OrderProcessing 业务状态机
已完成的 OrderProcessing 业务状态机

实现 ShippingProcess 组件

要实现的下一个组件是 ShippingProcess。您将按照以下方式实现此组件:首先使用调用 ShippingTask 组件的业务流程,然后对 OrderProcessing 组件调用 orderShipped 操作来指示订单已配送。将在本系列以后的文章中对业务流程进行详细的讨论。

  1. 打开 OrderProcessing 的 Assembly Editor,然后右键单击 ShippingProcess 组件,并选择 Generate Implementation... - Process
  2. 对话框打开并询问将流程实现放置在何处时,请单击 OK,以接受缺省值。将随即打开业务流程编辑器,如图 15 中所示。
图 15. ShippingProcess 业务流程
ShippingProcess 业务流程
ShippingProcess 业务流程

通常,在创建业务流程时,可以设计所有活动的接口的布局,但并不考虑其细节(就像创建模块组装关系图时一样),这样的方式可能非常有用。获得了所有活动后,可以再回头来在其中填充更多的细节。现在让我们尝试一下这个方法,以创建几个活动来唤醒配送 droid,然后在配送完成时通知 ProcessOrder 组件。

  1. 右键单击画布,并选择 Add - Invoke,然后将 Invoke 活动的名称更改为 ShippingTask
  2. 重复此过程,以添加第二个名为 NotifyShipped 的 Invoke 活动。

接下来让我们回到刚刚创建的两个活动,并填充一些细节。

  1. 选择 ShippingTask 活动,并在 Properties 视图中打开 Details 选项卡。
  2. 单击 Partner 旁边的 Browse,并选择 ShippingTaskPartner
  3. 对于状态机,可用的合作伙伴取决于组装关系图中的引用;每个引用有一个对应的合作伙伴。与 ShippingTask 操作对应的只有一个操作,因此该操作将会出现在 Operation 列表。

    确保选中了 Use Data Type Variables 复选框;对于 Input 和 Output 变量,单击每个变量右侧的选择按钮,然后选择 Order 作为变量。

  4. 以相同的方式选择 NotifyShipped 活动,在属性详细信息中浏览到 ProcessOrderPartner,并选择 orderShipped 操作。同样,将变量设置为 Order

已完成的 ShippingProcess 如图 16 中所示。

图 16. 已完成的 ShippingProcess 实现
已完成的 ShippingProcess 实现
已完成的 ShippingProcess 实现

现在,调用 shipOrder 操作时,它会调用 ShippingTask 组件的 shipOrder 操作来向配送部门的人员发送消息,以通知其配送订单。当任务完成时,NotifyShipped 活动将对 ProcessOrder 组件调用 orderShipped 操作,这将触发到 OrderComplete 状态的转换。

实现 ShippingTask 组件

ShippingTask 组件是一个网页,用于显示订单信息,并允许负责配送的人员指示订单已配送。在本例中,我们将选择人工任务实现:

  1. 在 OrderProcessing 的 Assembly Editor,然后右键单击 ShippingTask 组件,然后选择 Generate Implementation... - Human Task
  2. 对话框打开并询问将实现放置在何处时,请单击 OK,以接受缺省值。同样,在随即打开的 Human Task Component Handler 对话框中接受缺省名称。

现在就已完成了 ShippingTask 组件的实现!对于此例,缺省设置足够了;由于将不会启动服务器安全功能,因此可以使用缺省授权设置。

这意味着在服务器上打开 Business Process Choreographer Explorer 的任何人都可以查看并对处于挂起状态的配送任务进行响应。Business Process Choreographer Explorer 和人工任务将在本系列以后的文章中进行详细的讨论。

实现 CustomerCheck 组件和 CustomerInformation 导入

需使用一组业务规则(在本例中包含两条规则)来实现 CustomerCheck 组件。此规则非常简单,标识符以“gold”作为前缀的客户将自动识别信誉状态良好的客户;否则将运行客户信誉检查。将在本系列以后的文章中讨论业务规则的创作以及部署后如何方便地对其进行更改。

要实现 CustomerCheck 组件,请按照以下步骤操作:

  1. 在 OrderProcessing 的 Assembly Editor 中,右键单击 CustomerCheck 组件,并单击 Generate Implementation... - Rule Group。对话框打开并询问将实现放置在何处时,请单击 OK,以接受缺省值。将显示一个新的规则组,如图 17 中所示。
    图 17. CustomerCheck 规则组
    CustomerCheck 规则组
    CustomerCheck 规则组
  2. 选择 checkCustomer,然后选择 Default Destination 旁边的 Enter Destination,并选择 New Ruleset。在 name 字段中输入 checkCustomer,然后单击 Finish。将打开 RuleSet。
  3. 右键单击 Rules 并选择 Add If-Then Rule 两次,以添加两个规则。
  4. 在 Rule1 中的 If 单元格,单击 Condition 然后键入 customerID.startsWith("gold") == false。还可以在键入过程中显示的列表中选择表达式的每个部分。
  5. 在表的 Then 行中,单击 Action 并选择 Invoke
  6. 在 Then 行中随即出现的单元格中,为 Partner 选择 CustomerCheckPartner,为 Operation 选择 checkCustomer,为 customerID input 选择 customerID,然后为 customerOK output 选择 customerOK。这意味着通过 customerID 参数接收的输入将作为 CustomerInformation 导入的 checkCustomer 操作的 customerID 参数传递。customerOK 输出参数的情况与此类似。
  7. 在 Rule2 的 If 单元格中输入 customerID.startsWith("gold") == false,并在 Then 单元格中输入 customerOK = true

已完成的规则集如图 18 中所示。

图 18. checkCustomer 操作规则集
 checkCustomer 操作规则集
checkCustomer 操作规则集

对于 CustomerInformation 导入,直接将其保留为未绑定的输入;即,不会将其设置为调用任何实现。在本系列的下一篇文章中,会将一个模块中的导入绑定到另一个模块中的导出。

现在已经完成了模块的相关工作,因此在下一部分将对其进行部署和测试。

测试 OrderProcessing 模块

现在可以进行最后一组步骤,以对 OrderProcessing 应用程序进行测试,从而确定其工作情况。在保存各个编辑器的内容时,已在后台生成了所有必要的部署代码。

  1. 切换到 Problems 视图,以确认没有错误。如果看到任何错误,且不知道如何进行修复,可以忽略错误并加载 OrderProcessingPrebuilt 模块(可以从本文最后的下载部分下载项目交换文件),并使用该模块进行测试,或将其与您构建的模块进行比较。
  2. 右键单击 OrderProcessing 模块,并选择 Test Module
  3. 在随即打开的测试客户机中,选择 ProcessOrder 组件和 placeOrder 操作,因为此操作是订单处理的初始操作。前面曾说过,对 ProcessOrder 状态机的调用以 orderNumber 为基础进行相关,因此您输入的值非常重要:当调用其他 ProcessOrder 操作时,必须使用相同的值。在此例中将不使用其他值,因此可以输入任何值。对于初始请求参数,请为 orderNumber 输入 5,为 productID 输入 abc,为 quantity 输入 1,为 customerID 输入 123,如图 19 中所示。
    图 19. 测试 OrderProcess 模块
    测试 OrderProcess 模块
    测试 OrderProcess 模块
  4. 单击 Continue,然后确保在部署对话框中选择了 WebSphere Process Server 后,单击 Finish。在服务器启动(如果尚未启动)和应用程序部署到服务器期间,将需要等待。

数分钟后,将在测试客户机的 Events 窗格中看到在组件间进行服务调用时引发的事件,如图 21 中所示。

第一个事件将在 placeOrder 操作的初始调用时显示,这将使得 ProcessOrder 状态机转换到 CustomerBeingChecked 状态。在转换期间,将在控制台输出 Order has been placed. Setting Variables. 文本行。

下一个事件出现在从 ProcessOrder 调用 CustomerCheck 组件时。由于 customerID 没有带“gold”前缀,业务规则将触发对 CustomerInformation 导出的调用;由于这是未绑定的输出,因此将进行模拟。此时将显示一个手动模拟事件,如图 21 中所示。以下的步骤将完成模拟以及随后的人工任务(调用了 ShippingProcess 组件后)。

  1. 要完成 checkCustomer 操作的模拟,请为 customerOK 输出变量输入值 true,然后单击 Continue
  2. 当 ShippingProcess 组件调用 ShippingTask 组件时,将需要完成一个人工任务。切换到 Servers 视图,右键单击 WebSphere Process Server 实例并选择打开 Launch - Business Process Choreographer Explorer,从而打开 Business Process Choreographer Explorer。
  3. 打开 Business Process Choreographer Explorer 时,会缺省打开 My Tasks 页。选择 ShippingTask 旁边的复选框,并选择 Work On。将随即显示订单信息,如图 20 中所示。
  4. 回调 ShippingTask 接口的 shipOrder 操作,以返回一个 Order 业务对象。确保为 orderNumber 输入了相同的值(在本例中为 5),以使正确的 ProcessOrder 状态机实例接收 orderShipped 消息。对于其他订单属性,可以使用任意值,因为本示例中将不使用这些属性。
  5. 要完成任务,请单击 Complete
图 20. 在 Business Process Choreographer Explorer 中完成 ShippingTask
在 Business Process Choreographer Explorer 中完成 ShippingTask
在 Business Process Choreographer Explorer 中完成 ShippingTask

ShippingTask 活动现在已完成,将执行 NotifyShipped 活动。在控制台中,将看到其他的打印语句的结果。在调用其他服务调用时,将在测试客户机中显示更多的事件。图 21 显示了日志内容和完成时的测试结果。

图 21. 测试 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=151944
ArticleTitle=IBM WebSphere 开发者技术期刊: WebSphere Integration Developer 指导教程——第 3 部分
publish-date=08032006