体系结构:SOA
   下载
 Oracle SOA 套件 10g
 Oracle JDeveloper 10g
 示例代码
 示例应用程序
 
   关键词
middleware, integration, SOA
 


通过企业服务总线构建事件驱动的体系结构


作者:Lucas Jellema,Oracle ACE 和 Oracle 融合中间件区域总监

通过一个简单的示例了解如何配置 ESB 以“发布”企业事件。

2007 年 2 月发表

在面向服务的体系结构 (SOA) 领域,一个比较重要的概念是事件驱动的体系结构 (EDA)。与事件机制类似,例如在 JavaScript 或 4GL 环境中,可以将触发器(可执行程序代码段)与按压按钮、更改域值或者提交查询等事件相挂钩,而 EDA 指定“服务”与“业务事件”的挂钩方式。

大多数业务事件(从下订单、请求报价到聘用新员工或提供某部分设备)触发企业内多个响应。如果进行更近一步的细化,过程步骤内的事件(例如调用服务失败、超过预定义阈值或者到达指定目标)可能还会引起过程自身之外的相关方的兴趣。

EDA 允许您将创建或遇到事件的过程中的所有这些事件发布到一个中央事件处理主干上,从而使所有感兴趣的相关方可以从此处找到它们。产生事件的过程或服务本身无需考虑这些外部各方,否则,会给该特定过程的执行带来压力,系统之间交织过密,造成维护困难。

在本文中,您将通过一个基于 Oracle ESB 的简单示例了解如何配置该中央主干,以消息的形式将发布的事件传递给外部各方。(如果您没有时间学习本教程,“结论”部分提供了一个链接,其指向一个包含完整 JDeveloper 应用程序的 zip 文件)。

背景

Oracle ESB 具有使其适用于其任务的关键功能。首先,它可利用多种方法检索消息(事件通知):通过 JMS、Web 服务调用、文件系统或数据库表等等。它还可提取带有与事件相关数据的消息并对其进行转换,通常是将其转变为一种更通用、更规范的企业模型。

ESB 还可以将一个粗粒度事件消息转换为多个细粒度消息。例如,它可以在新用户已经注册并下了第一个订单时,通过从基于 Web 的客户订单系统接收的消息创建一个新客户事件以及新订单事件。在将原始消息转换为一个或多个更规范、可能更具针对性的消息时,ESB 还可以丰富消息的内容(例如,通过添加当前日期和时间戳信息或添加从参考数据源查找的信息),多个事件用户可能会有此要求。

最后,根据事件(消息的内容)的特性,ESB 可将内容经过扩充的已转换消息提供给多个输出通道,例如 Web 服务、JMS、数据库过程或表、文件或者电子邮件。

(注意:BPEL 流程就是事件报告程序的一个主要示例。执行 BPEL 流程时,在几个阶段中和在一些情况下,可以发布事件,通常是以在 ESB 中调用 Web 服务的形式进行。)

有几种方法可以帮助对事件感兴趣的相关方使用来自 ESB 的消息:

  • ESB 可以将所有消息提供给 JMS 主题,并让感兴趣的相关方自己挑选获取消息以及将其转换为自定义格式的方式。
  • 可直接从 ESB、同一服务(使用来自发信方的事件并可能将其消息转换为更规范的格式)调用每一个希望知晓消息的系统。当然,这意味着 ESB 服务需要针对增加的每一个相关方进行扩展,并且可能需要包含针对各个附加方的额外转换和过滤规则。
  • ESB 提供了一个接收事件、转换和丰富消息和将该事件发布到 JMS 的服务,以及一个针对感兴趣各方的专用服务。该专用服务将直接从接收服务(耦合)接收事件消息,或从 JMS(取消耦合)读取消息、为其正在服务的相关方执行附加的定制转换,以及通过适用于消息接收方的任何方式(JMS、Web 服务调用、数据库操作)提供消息。在该示例中,添加一个新的对事件(消息)感兴趣的相关方意味着要在 ESB 中创建一个独立的、松散耦合的新服务。但是,这会引入一些特殊开销、更多的服务定义以及服务实例,并且还会在内部通过外部 JMS 主题或多或少地复制 ESB 所做的内容。

在大多数情况下,第二种方法可能是最好的。注意,从 ESB 服务实例调用以通知感兴趣各方的目标服务可以并行调用也可以顺序调用(取适用的方式)

利用 Oracle ESB 开发 ESB 服务

可以在 Oracle ESB(Oracle 融合中间件中 Web 服务基础架构的 ESB 组件)中按如下方式创建该方法的简单演示。

该案例中的业务事件是聘用新员工。当新员工签订合同后,该事件将发布到 ESB。该事件消息包含姓名、年龄、性别、职务以及入职日。有多方对该事件感兴趣:

  • 新员工需要向安全部门注册,该部门将建立帐户、颁发胸牌以便员工能够进入该机构等等。
  • 财务部门需要为新员工准备多种工资单和支出报表。
  • Junior Managers Club 将邀请处于管理位置、40 岁以下的所有人参加他们的会社。为此,他们希望在聘用了符合条件的新员工时能够得到通知

使用 Oracle ESB 实现该简单的业务事件服务,如下所示:

通过人力资源部门(为此目的调用 ESB Web 服务)发布(“即发即弃”)业务事件 NewEmployee。ESB 服务使用该事件并执行三个也执行一些转换的路由规则:

  • 调用 SendNewEmployeeFileToJuniorManagerClub 目标服务并将 CSV 文件写入目标目录
  • 调用 InformFinanceDepartmentOfNewEmployee 目标服务并将新员工记录写入财务数据库
  • 调用 NotifySecurityWebService 以传递包含新员工数据的消息。这会启动 BPEL 工作流流程,该过程在为新员工创建安全胸牌时需要手动活动。

部署该服务时,为发布新员工事件而对 NewEmployee ESB Web 服务的任何调用都会触发两个或三个(针对 40 岁以下的新管理层员工)目标服务。该体系结构的关键是将事件发布方(人力资源部门)与事件使用方完全分离,这样添加新用户不会对该部门有任何影响。新员工事件中的更改基本上可以在 Router Service 中得到解决,无需影响事件使用方。

要开发针对该事件的 ESB 服务,您需要完成以下步骤:

  • 下载并安装 Oracle SOA 套件 10.1.3.1 或更高版本。
  • 下载并安装 Oracle JDeveloper 10.1.3.1 或更高版本。
  • 启动 SOA 套件。
  • 运行 JDeveloper。
  • 执行初始设置。

初始设置


您首先需要做一些准备,然后才能开始实现 EDA。具体来说,您需要使用 DDL 脚本在数据库中创建一个表,将文件复制到您文件系统上可供 JDeveloper 访问的目录,并将一个很小的简单 BPEL 项目部署到您的 SOA 套件实例。

下面是设置步骤:

  1. 示例代码下载解压缩到一个临时目录。
  2. 使用 employees_table.sql 脚本为所需的数据库模式创建表 EMPLOYEES。稍后您会用到该表,在该表上插入新记录。
  3. 将文件 NewEmployeeEvent_Template.csv 复制到可从 JDeveloper 访问的目录。您将在文件适配器向导中使用该文件,为应该由将在本教程中开发的 ESB 服务编写的文件建模。
  4. 将 SecurityProcessingNewEmployee.zip 文件解压缩到一个工作目录。该文件中包含一个小的 JDeveloper 10.1.3.1 项目和一个 BPEL 流程;SecurityProcessingNewEmployee。这是一个简单的流程,该流程调用 BPEL 工作流服务,让安全部门接受为新员工创建新胸牌的任务。
  5. 将 SecurityProcessingNewEmployee 项目加载到 JDeveloper 10.1.3.1 中。将该项目部署到 SOA 套件实例中的 BPEL PM。我们需要让该 BPEL 流程在您于 ESB 中开发 EDA 服务时可用。
部署 BPEL 流程,方法是右键单击 SecurityProcessingNewEmployee 并选择 Deploy 选项,然后选择选项 BPEL Process Deployer

通过弹出的窗口,您可以选择一个到 BPEL PM 实例的 Connection

选择正确的连接,按 OK 启动部署。

 

创建 JDeveloper 应用程序


在 JDeveloper 中,创建一个名为 EventDrivenArchitecture 的新应用程序。如果 JDeveloper 要为您创建一个默认项目,按 Cancel

 

转至 New Gallery,这次选择 Projects、ESB Project 项:

将项目命名为 NewEmployeeEventService。

当 ESB 图打开后,单击左上角的小图标以创建一个系统:

在 ESB 服务器中注册项目后,就可以在 ESB 控制台中使用您创建的系统或服务组了。服务是系统的一部分,或者是系统内的组的一部分。系统和组都提供了一种组织服务的方法 — 不同于 BPEL 流程中的作用域。系统的一个重要方面是,可以从路由服务并行调用不同系统中的目标服务,同时按顺序调用同一系统中的目标服务。

将新系统命名为 NewEmployeeEventSystem。

在开始使用 ESB 中的事件处理服务之前,需要根据 New Employee 事件指定从人力资源部门接收的确切消息类型。为此,创建一个 XML 模式文档 (XSD),以描述为该事件接收的 XML 消息的结构。

转至 New Gallery,选择节点 General、XML 并单击可用项列表中的 XML Schema。然后,为新的 XML 模式文档输入名称 — 在本例中为 NewEmployeeEventMessage.xsd。

注意,该模式有一个相对简单的消息结构,其复杂类型比较简单(带有五个简单类型元素),描述了与该业务事件相关的核心信息。

现在,返回 ESB 选项卡,开始创建服务。

Routing Service 组件从 Component Palette 拖放至 ESB Service。为 Routing Service 输入名称,使用 Browse 按钮和 Type Chooser 选择 NewEmployeeEventMessage 模式定义中的 NewEmployeeEvent 模式元素。

以下是 Type Chooser 的屏幕截图,可用于选择描述该 Routing Service 输入的 XSD 元素。

在创建即发即弃(无回调异步)的服务时,无须指定回复消息或失败。

可允许外部进程通过 Web 服务接口直接调用这个 NewEmployeeEventRS 路由服务。如果使用其他通道发布该事件 — 例如,通过在数据库表中输入新员工或利用 JMS 将新的 Employee 文件置于 FTP 服务器上 — 您可以将入站适配器服务添加到 ESB 服务,该服务会转发获得的 NewEmployeeEventRS 消息。此时,假设人力资源部门将使用 Web 服务接口。

现在,来看一下出站适配器。请记住,该事件涉及三方:安全部门、财务部门以及 Junior Managers Club。

  • 安全部门具有一个要调用的 Web 服务终端 — 实际上,该终端只是将在部门内运行的 BPEL 流程的前端,其中包括负责创建物理证件的人工流程。
  • 财务部门希望您直接在数据库表中插入一条新记录,以后可从此处读取该记录。
  • Junior Managers Club 明确表示,希望通过写入文件系统特定位置的 CSV 文件接收新 Junior Manager 的消息。它提供了一个示例文件,用于说明该文件的格式。

为此,我们需要向 ESB 服务添加出站服务。

在 ESB 制图器中,将 File Adapter 拖放至图中。这会弹出一个窗口,您可以通过该窗口定义 File Adapter 服务的细节,以便将 CSV 文件写入文件系统。

输入服务名称。然后,单击 WSDL File 域旁边的 Define Adapter Service 图标。

接下来,将进入 File Adapter Configuration Wizard。在第一个页面上,指定服务名称。(基本上,是确认之前在 Create File Adapter Service 弹出窗口中指定的内容。)

单击 Next 后,将转到 Operation 页面。在这里,您可以指定希望服务编写文件。

Step 3 将询问是否为服务将要编写的文件指定输出目录和命名惯例。目前,指定硬编码目录要简单些 — 但是,这显然不是创建可移植服务的最佳方法。可使用几个动态元素指定文件名(但一次只能指定一个),例如消息或序列的日期或时间。

在 Step 4 中,指定文件的输出格式:信息的结构如何?因为要编写 CSV 文件,所以单击 Define Schema for native format 按钮。

这将显示 Native Format Builder,您可在其中创建 XSD,以便 File Adapter 用于从其中的 XML 数据创建 CSV 文件。使用示例 CSV 文件,Junior Manager Club 发送指令时游刃有余。

接受默认值,并单击 Next

在下一个页面中,浏览到示例文件,或键入其名称和位置。然后按 Next

接受第 3 页上的默认值,并单击 Next

分别为包含多条记录的元素和表示一条记录的元素输入名称。例如,使用 NewJuniorManagers 和 NewJuniorManager。注:这些将在创建该文件服务的映射时出现,在编写的文件中不会显示。

接受第 5 页上的默认值,并单击 Next

在第 6 页上,选中复选框“Use the first record as the field names”。同样,这将使 XSD 的可读性更强 — 它不会影响由该服务编写的文件。

在下一个页面上,汇总了由向导创建以供 File Adapter 使用的 XSD 文件的信息。您可以检查这些信息。然后单击 Next 接受。

这将显示 Native Format Builder 向导的最后一页。单击 Finish

返回 File Adapter Configuration Wizard,单击 Next

然后单击 Finish。您将返回 Create File Adapter Service 弹出窗口。再次单击 Finish

NewEmployeeEventService 的 ESB 图已经通过 SendNewEmployeeFileToJuniorManagersClub 服务得到了扩展。

双击 NewEmployeesRS 图标指定路由规则,以将 NewEmployeeEvent 消息传递至该目标服务。

单击绿色加号创建一个新的路由规则。Browse Target Service 对话框将打开。您可以在其中选择路由规则将向其传递消息的服务。

在 SendNewEmployeeFileToJuniorManagersClub 上选择 write 操作,单击 OK

添加分为两部分的过滤器表达式 — 一部分表明新雇员的年龄应低于 40 岁,另一部分要求角色应为管理类。以下是必须输入的完整表达式:

/inp1:newEmployeeEvent/inp1:age < 40 and contains('MANAGER,PRESIDENT,
VICE PRESIDENT,TECHNOLOGY MANAGER,CFO,CHIEF,SUPERVISOR',/inp1:newEmployeeEvent/inp1:role)

现在,需要指定如何转换从人力资源部门接收的消息,以将其传递至目标服务。

单击映射图标。选择对话框中的 Create New Mapper File 选项。

单击 OK。进入 Mapper 工具。您需要在其中连接两个 XSD 文档,因此定义 XSLT 以将源 XSD 转换为目标。

首先,将 newEmployeeEvent 元素拖放至 NewJuniorManager 的顶部,以创建一个简单、明显的映射。

取消选中复选框 Match Elements Considering their Ancestor Names

现在,您已经拥有了一个最初的映射:

role 元素尚未映射到 Position 域,而 FirstDay 域对于日期格式的要求比较特殊。

role 拖放至 position。然后,将连接顶部的 Component Palette 中的 format-dateTime Date Function firstDayAtWorkDate 拖放至 firstDay

现在,双击功能项,以确切指定如何执行转换:

接下来,该解决财务部门的特定消息传递需求了。

财务部门。财务部门希望您直接将新记录插入数据库表。该表位于公司数据库之一的 FINANCE 部门中:
SQL> desc employees
 Name                          Null?            Type
 ----------------------------  ---------------  ----------------------
 NAME                          NOT NULL         VARCHAR2(50)
 GENDER                                         VARCHAR2(1)
 JOB_TITLE                                      VARCHAR2(50)
 START_DATE                                     DATE

您需要为该目标创建一个新的适配器服务。使用 Database Adapter 为 NewEmployeeEventRS 设置一个目标服务。在 Component Palette 的 Adapter Services 部分中,将 Database Adapter 拖至 ESB 文档。以下窗口将弹出。

输入 Adapter Service 的名称,单击 WSDL File 域后面的第一个图标,以配置数据库适配器。

创建一个 New Database Connection,以连接到公司数据库的 FINANCE 模式。(注:以“初始设置”期间创建 EMPLOYEES 表的方式创建数据库模式连接。):

指定连接名称:

然后,输入 FINANCE 模式的用户名和口令:

单击 Next 按钮输入 Connection 的详细信息:

在这一步中,您需要指定 JDBC URL 细节,例如主机名、端口以及数据库 SID。完成后,单击 Next 测试连接。

如果成功,则单击 Finish。否则,更正错误的信息。

这将返回 Database Adapter Configuration Wizard。单击 Next

选择希望该服务执行的操作:只需插入新记录。

单击 Next;您将转到 Select Table 页面。单击 Import Tables 选择 FINANCE 数据库中的 EMPLOYEES 表。

单击 Import Tables。按 Query 按钮。这将显示一个包含 FINANCE 模式下所有表的列表。选择 EMPLOYEES 表并单击 OK

当 Select Table 向导页面再次出现时,单击 Finish

您将返回 Create Database Adapter Service;单击 OK

现在将返回 ESB 图:

将该目标服务连接到 NewEmployeeEventRS。双击路由服务的图标。

单击绿色加号以添加路由规则:

选择 InformFinanceDepartmentOfNewEmployeeEvent 服务下的 Event 操作,并单击 OK

单击 Mapping 图标,定义从传入的 NewEmployeeEvent 到目标服务的映射。

选择 Create New Mapper File 并单击 OK

将 newEmployeeEvent 事件元素拖至 top:Employees 元素。

取消选中 Match Elements considering their ancestors 复选框。

自动映射将执行转换的第一步:

您需要手动将 role 映射到 jobTitle,并将 firstDayAtWorkDate 映射到 startDate。只需将 Source 元素拖放至 Target 元素即可。

最终的映射将如下所示:

单击 Save All 图标。就快完成了:三方中已有两方与 NewEmployeeEvent 链接在一起。

安全部门。安全部门已经发布了一个 Web 服务,您需要通过新员工事件进行调用。在该 Web 服务之后潜伏着一个能够启动人工流程的 BPEL 流程(此时,这是它唯一可做的事情)。

在 ESB 服务中,您需要创建另一个 Adapter Service 以便调用这个 BPEL 流程,然后将其与 Router Service 相连。

从 ESB 服务的 Component Palette 中,将 SOAP Service 元素拖放至 ESB 图。

Create Soap Invocation Service 对话框将弹出。输入该服务的名称,例如 NotifySecurityWebService。然后,单击 Service Explorer 图标。

选择 SecurityProcessingNewEmployee 服务(该服务已经部署在 BPEL PM 实例上)。

单击 OK

再次单击 OK

双击 Router Service。您需要添加一个新的路由规则,以将 Soap Invocation Service 连接到 Router Service。

单击绿色加号以添加新的路由规则。

在 NotifySecurityWebService 目标服务下选择 initiate 操作。

单击 OK

单击 Mapping 图标。

选择 Create New Mapper File 并单击 OK

将 RouterService newEmployeeEvent 映射到 SecurityProcessingNewEmployeeEventRequest 消息。

保存所有工作。

ESB 服务将如下所示:

在 ESB 中注册路由服务

现在,可以在 ESB 中注册您的服务。如果您还没有与运行中的 ESB 建立连接,应首先按照“创建与 ESB 的连接”部分末尾处描述的步骤进行操作。

右键单击项目并选择 Register with ESB ,然后选择 LocalESB_soasuite_10_1_3_1 连接。

如果注册成功,将显示如下报告:

如果现在转至 ESB 控制台,可以看到已经部署的服务。

NewEmployeeEventRS 服务可作为常规 Web 服务进行调用。如果转至该服务的 Definition 选项卡,可以看到它的 WSDL 位置:

触发 EDA 的 NewEmployeeEvent 路由服务

您还可以进入应用服务器的企业管理器,以查看 OC4J 实例上可用的 Web 服务,以及对这些服务进行测试。

单击 Test Service 按钮。

通过单击 Test Web Service 转至以下页面:

在五个输入域中输入值,然后按 Invoke 按钮。企业管理器控制台中的结果少得可怜,这是因为 ESB 服务是异步服务,并且不返回任何响应:

在 ESB 控制台中,您可以看到一个新的服务实例(这是刚才调用 Web 服务而触发的):

您还可以看到,当 ESB 服务收到 New Employee 事件的消息后会调用全部三个目标服务。

这意味着:

  • 安全部门有一个新的工作流处于等待状态。
  • Junior Managers Club 新增了一个 CSV 文件。
  • 财务部门在 EMPLOYEES 表中新增了一条记录。

如果转至 Worklist Application,并以 JSTEIN 身份登录 — 当前指定的安全官员,负责为新员工创建安全证件:

您将发现以下任务处于等待状态:

如果在 Junior Managers Club 指定的目录中查看文件系统,您将看到:

如果打开这个文件,您将看到:

对于财务部门而言,如果连接到公司数据库中的 FINANCE 模式的 SQL*Plus,并选择 EMPLOYEES 表中的所有员工,您将看到:
SQL> show user
USER is "FINANCE"
SQL> select *
  2  from    employees
  3       /

NAME                                                      G
--------------------------------------------------------- -
JOB_TITLE                                                 START_DAT
--------------------------------------------------------- ----------
Lex Jellema                                               M
MANAGER                                                   16-AUG-20

创建与 ESB 的连接

在连接到 ESB 以便在其中注册新服务之前,您需要与应用服务器建立连接。

在 SOA 套件 10.1.3.1 中,创建应用服务器连接的步骤如下:

转至 New Gallery 并选择 Application Server Connection 选项。

选择 Oracle Application Server 10g 10.1.3 的连接类型,还要提供一个连接名称。单击 Next

输入用于连接到应用服务器的用户名和用户口令。对于本地开发环境,该用户就是管理员 oc4jadmin。单击 Next

在下一个屏幕中,可以指定要连接到的应用服务器实例。要确认您使用的值正确,检查 <soasuite_10_1_3_1_HOME>\opmn\conf 目录中的 opmn.xml 文件。在该文件中,查找 port 元素的 request 属性的值。

输入正确值,并单击 Next

单击 Test Connection 并等待 Success! 状态出现。

单击 Finish。再次转至 New Gallery。此次选择 Integration Server Connection。单击 OK

键入连接名称,并单击 Next

选择正确的应用服务器连接 — 刚才创建的那个,还需指定正确的端口号。(文件 SOA_SUITE_HOME\install\esbsetupinfo.txt 可以提供有关该端口的正确信息。)

理想情况下,在单击 Test Connection 按钮后,将获得如下输出:


结论

利用 EDA,可以通过智能事件通信基础架构转发业务事件,进而触发可为事件带来附加结果的松散耦合的业务服务。

在本教程中,您可以看到业务事件“新聘用的员工”如何由 Oracle ESB 进行转发,进而调用三个相分离的无关业务服务,每一个都拥有自己的传递机制和消息格式。ESB 可为您执行所有的路由、过滤以及转换操作。单击此处下载包含完整 JDeveloper 应用程序的 zip 文件。

如您所见,使用 Oracle JDeveloper 和 Oracle ESB 实现这个基本 EDA 是一个非常简单、直接的过程,无需编程,并且依靠向导就可以完成大部分工作。EDA 的部署和管理十分轻松且快速。


Lucas Jellema AMIS(位于荷兰 Nieuwegein)的技术经理,同时还是 Oracle ACE 和 Oracle 融合中间件区域总监。Lucas 发表了多篇网络日志,撰写了多本书籍,并且经常在国际会议和研讨会上发表演讲,他还热衷于开发可重用软件,如 JHeadstart Designer Generator、CDM RuleFrame 以及 Oracle Designer Repository Object Browser。

将您的意见发送给我们