主题
面向服务的架构
比较:WLI 文件控件和 Oracle 文件适配器作者:Daniel Amadei 和 Heidi Buelow 面向 WLI 用户的 SOA 套件概要系列的这一部分将介绍与 WebLogic Integration 的文件控件功能相对应的 Oracle BPEL 流程管理器功能。2009 年 5 月发表
[ 第 1 页] [ 第 2 页] [ 第 3 页] [ 第 4 页] 在 Oracle BPEL 流程管理器中实现用例要使用 Oracle BPEL 流程管理器实现本文中的用例,您必须安装 Oracle SOA 套件和 Oracle JDeveloper。您可以针对 SOA 套件使用 OC4J 或 WebLogic Server。 请务必保留 SOA 套件的 oc4jadmin 或 weblogic 用户的口令。 入门您需要为用例提供的示例文件,其中包括模式和输入数据。将示例文件解压缩到计算机上的某个位置,例如 C:\CompareWLI_BPEL\samplefiles。我们将在本文通篇引用此目录。您将创建输入和输出目录来包含用于测试的文件,例如: C:\AdapterFiles\In 和 C:\AdapterFiles\Out。 确保 SOA 套件正在运行并启动 JDeveloper。从 View 菜单中打开 Connections Navigator,创建到 SOA 套件的 Application Server 连接。右键单击 Application Server 并选择 New Application Server Connection。选择会稍有不同,具体取决于您的服务器。
接下来,使用您刚创建的应用服务器连接创建集成服务器连接。右键单击 Integration Server 并选择 New Integration Server Connection。输入 IntServerConnection 作为名称并选择 Next。 选择您先前创建的应用服务器,并输入您的服务器上用于 http 协议的端口号。此端口号的默认值为 8888,而对于 WebLogic 为 9700(在您的安装中可能有所不同)。选择 Next。 选择 Test Configuration,您应该看到应用服务器、BPEL 流程管理器服务器以及 ESB 服务器的成功消息。选择 OK。 现在,我们将创建应用程序。此顶级应用程序将包含三个项目,每个用例一个项目。每个用例由一个 BPEL 流程实现,并且每个项目可以包含一个 BPEL 流程。在 Oracle BPEL 流程管理器运行时,每个 BPEL 项目都独立运行,但在 JDeveloper 中,您可以将这些项目全部包括在一个应用程序中。 这三个用例尽可能贴切地反映本文中的 WLI 用例。在 WLI 中,文件控件类似于 BPEL 文件适配器。如果可能,使用与文件适配器实施相同的命名,有助于关联相似性。当您完成所有三个用例后,JDeveloper 中的应用程序应该类似于下图。 现在,让我们开始。选择 Application Navigator(如果它不可见,您可以从 View 菜单中选择它)。右键单击 Application 并选择 New Application。 输入 FCTLApp 作为应用程序名并选择 OK。 将打开默认的项目对话框。由于我们要创建 BPEL 项目而不是默认项目,因此,在此对话框上选择 Cancel。将创建应用程序。 使用 BPEL 从文件中读取纯字符串现在,我们将创建第一个 BPEL 项目。此项目用于我们的第一个用例,此用例从文件中读取字符串。首先,我们设置一个读取目录中文件的 Web 服务。我们使用 BPEL 文件适配器创建此服务。接下来,我们调用此服务,此服务读取文件并将字符串传递到 BPEL 流程。如果文件不在目录中,则此服务将引发错误。 右键单击新应用程序并选择 New Project。 在 General/Projects 下,选择 BPEL Process Project 作为项目类型。 输入 GetFileContentAsString 作为流程名。选择 Synchronous BPEL Process 作为模板类型。选择 Finish。 通过接收和回复活动创建 BPEL 流程。BPEL 流程是 Web 服务,因此还将创建 WSDL 文件。我们针对 Web 服务选择默认的输入和输出消息类型,即字符串。还将创建 inputvariable 和 outputvariable 这两个变量,它们对应于 Web 服务的输入和输出数据。 现在,我们只需设置文件适配器 Web 服务,然后调用它。 在 Component Palette 上,从下拉列表中选择 Services 查看与服务相关的项。如果您没有看到 Component Palette,请从 View 菜单中打开它。将 File Adapter 拖到 BPEL 设计器屏幕右侧的 Services 窗格,启动文件适配器向导。选择 Next 进入第 1 步。 输入 StringReaderFileControl 作为服务名并选择 Next。 选择 Synchronous Read File 作为操作类型并选择 Next。 输入您将读取文件的目录。这应该是运行 SOA 套件的服务器可访问的目录。它应该相应地采用 Windows 或 Linux 路径语法。保留其余的值为默认值并选择 Next。 对于 File name,输入 stringContent.txt 并选择 Next。 最后一步是设置被读取数据的格式。选择 Define Schema For Native Format 按钮启动原生格式构建器向导。 在第 1 步中,选择 Create new native format 和 Delimited 单选按钮,然后选择 Next。 使用 Browse 按钮打开示例文件目录中提供的示例 stringContent.txt 文件。您将在窗口中看到文本。选择 Next。 选择 File contains only one record 并选择 Next。 根据需要输入命名空间并输入 mystring 作为元素名,然后选择 Next。 再选择三次 Next 接受格式规范的默认值,然后选择 Finish。 返回适配器向导,您将看到新创建的用于定义字符串数据的 xsd。选择 Next,然后选择 Finish。 现在适配器服务已配置,您将看到 Create Partner Link 对话框。在 BPEL 中,partner link 仅为对服务的引用。选择 OK。 BPEL 流程将如下所示: 选择 Save All。接下来,您将创建 BPEL Invoke 活动以调用服务并获得字符串。服务将数据返回到您定义的 BPEL 变量中。 将 Component Palette 更改到 Process Activities。 将 Invoke 活动拖到 receiveInput 活动正下方。当此活动处于正确位置时,它将以黄色高亮显示。 通过将左箭头拖到 StringReaderFileControl partner link,将 invoke 活动关联到此 partner link。 将打开 Invoke Properties 对话框。将自动填充 partner link 和操作。输入 Invoke_String 作为名称。在 BPEL 中, Invoke 活动需要输入和输出变量,即使我们实际上没有向服务传入任何输入。对于输入变量,选择右边的 Auto-Create Variable 按钮。这将创建一个可将数据发送到服务的变量。它将自动创建消息类型。针对此变量自动生成的名称是描述性的,您可以保留此名称不变。在 Create Variable 对话框中,选择 OK。对于输出变量,重复 Auto-Create Variable,但将变量名更改为 fileContent。在 Invoke 对话框中,选择 OK。 现在,流程将从文件中读取字符串并在 fileContent 变量中返回字符串。现在,我们将字符串复制到 outputvariable 中,这样流程将返回字符串。 将 Assign 活动拖到 BPEL 流程中的 Invoke 活动下。双击打开 Assign 对话框。选择 Create -> Copy Operation。 在 From 侧,展开您为 Invoke 输出变量创建的 fileContent 变量,并选择最终元素。在 Target 侧,展开 outputvariable 变量并选择最终元素。此 Assign 操作将数据从一个元素复制到另一个元素。稍后,在部署期间,BPEL 将警告您这些类型可能不兼容。由于您知道它们兼容(都是字符串),因此可以忽略警告。 选中 BPEL 流程窗口顶部的绿色复选框以验证流程。您将看到黄色警告标志消失, Invoke_String 上的警告标记除外。此标志发出输入变量未初始化的警告,但由于服务没有使用此变量,因此可以忽略该警告。 选择 Save All。现在流程已完成。当流程启动时,它将在指定输入目录中查找文件并进行读取,将文件中的数据作为纯字符串返回。让我们来试一下。 右键单击项目名并选择 Deploy -> IntServerConnection -> Deploy to default domain。查看 Apache Ant 日志窗口,直到您看到绿色 Build Successful 消息。现在项目已部署。 将输入文件的副本放在输入目录内。现在可以运行流程了。 要运行流程,我们可以使用 BPEL 管理控制台。打开浏览器并输入 URL http://localhost:8888/BPELConsole,将 localhost 替换为在其中部署了您的服务的服务器的名称(如果此服务器不是您的本地计算机),将端口号替换为 9700(如果您针对 BPEL Console 使用默认 WebLogic 端口)。使用用户名 oc4jadmin 或 weblogic 以及您的配置口令登录。 BPEL Console 打开到 Dashboard,这将显示所有已部署的 BPEL 流程。选择 GetFileContentAsString 流程打开启动页面。 选择 Post XML Message。同步流程将启动,读取文件,将数据复制到 outputvariable 中,并将值返回到浏览器窗口。您可以在浏览器中看到从文件中读取的字符串。 检查输入目录。此文件已不见。服务找到此文件并对其进行处理。让我们返回 BPEL Console 查看审计跟踪,并查看流程实例的详细信息。 选择 Instances 选项卡。您将在此看到所有正在运行以及完成的实例。此处列出了 GetFileContentAsString 流程实例。选择此实例以查看审计跟踪。审计跟踪在 Flow 选项卡上以图形模式打开。请注意,它类似于流程的设计视图。您还可以使用 Audit 选项卡查看文本审计跟踪。 选择 Invoke_String 活动查看服务数据。您将在文件适配器服务调用的输出中看到字符串。 尝试再次运行流程,此时目录中没有文件。在这种情况下,适配器服务引发错误,但未在任何位置捕获到错误,因此流程失败。您可以在 BPEL 审计跟踪中查看结果。 我们可以更改流程以便捕获错误并返回有意义的错误消息。我们设置 Invoke 的范围,以便可以捕获错误并在定义的范围之后继续。首先,将 Scope 活动拖到 Invoke 活动正上方。 通过选择加号 ( +) 展开 Scope 活动,然后将 Invoke 和 Assign 活动拖到 Scope 内。 现在,我们将添加错误捕获器。在 Scope 框中,选择 Add CatchAll Branch 图标。展开分支并将 Assign 活动拖到其中。双击打开 Assign。选择 Create -> Copy Operation。在 From 侧,选择 Expression 作为类型并输入“ Error reading file”。在 Target 侧,展开 outputvariable 变量并选择最终元素。 选择 Save all。流程完成,应该如下所示: 现在,流程将返回文件中的字符串或错误消息(如果读取文件时出现错误)。部署新版本的流程。系统将要求您提供版本号,因为已经部署了此流程的 1.0 版本。输入 1.1 作为新版本以使两个版本均可查看。现在运行新的版本。此时,如果目录中没有输入文件,您将立即在浏览器中看到错误消息。 ReadStringFromFile 流程显示如何创建服务以将字符串引入流程中,还显示如何处理错误。您可以扩展 BPEL 流程以便针对此字符串执行操作,例如将其传递到其他服务或者通过人工任务或电子邮件通知将其发送到用户。 现在,我们将试试下一个用例。返回 JDeveloper,关闭所有打开的文件。 使用 BPEL 接收 XML、转换为其他模式并写入文件在此用例中,我们调用一个包含一些输入数据的 BPEL 流程,将其转换为所需的输出模式,并将其写入文件。首先,我们需要一个项目。右键单击应用程序并选择 New Project。在 General/Projects 下,选择 BPEL Process Project 作为项目类型。输入 TranslateStockProcess 作为流程名。选择 Synchronous BPEL Process 作为模板类型,然后选择 Next。 请求和回复模式默认为简单字符串,因此我们将其更改为输入股票和输出合作伙伴股票模式。选择 Input Schema Element 框右边的按钮,浏览到示例文件目录。选择 stocks.xsd 作为要导入的 xsd。 然后,打开 xsd 并选择 stocks 元素。 对于 Output Schema Element,您首先看到 Type Chooser 窗口,因为已经导入模式。选择右上方的 Import Schema 按钮。 浏览并选择 STOCKS_PARTNER.xsd。 然后,选择 STOCKS 元素。 选择 Finish。将创建项目。 由于此流程使用同步模板,因此,已经创建 Receive 和 Reply 活动以及客户端服务引用。我们需要添加文件适配器服务以写入数据。 将文件适配器拖到 BPEL 设计屏幕右侧的 Services 窗格。选择 Next 进入第 1 步。 输入 writePartnerSchema 作为服务名并选择 Next。 选择 Write File 作为操作类型并选择 Next。 输入将向其中写入文件的目录。此目录应该可由运行 SOA 套件的服务器访问。它应该相应地采用 Windows 或 Linux 路径语法。对于 File Naming Convention,输入 partnerStocks%SEQ%.xml_。写入文件时,特殊字符串 %SEQ% 将替换为序列中的下一个数字。这样,您可以多次运行流程而不会覆盖输出文件。保留其余的值为默认值并选择 Next。 最后一步是设置被写入数据的格式。此时,我们以 xml 格式写入数据,因此浏览以选择已经导入的模式。 选择 STOCKS_PARTNER.xsd 和 STOCKS 元素。选择 Next,然后选择 Finish。 现在适配器服务已配置,您将看到 Create Partner Link 对话框。选择 OK。 选择在哪侧放置服务引用都可以,但按照惯例,我们通常使用右侧放置流程调用的引用,使用左侧放置流程接收的引用。您可以通过右键单击 partnerlink 图标并选择 Display->Move to opposite swim lane,轻松切换左右侧。 现在,我们将调用新服务。 将 Invoke 活动拖到 BPEL 流程的 Receive 和 Reply 活动之间。 输入 Invoke_WriteStock 作为名称,选择 Input Variable 框右边的 Automatically Create Input Variable 按钮。将输入变量名更改为 stocks。选择 OK。选择 OK 设置调用属性。 最后一步是将输入数据复制到服务的输入变量中。我们可以使用 BPEL Transform 活动执行此操作。将 Transform 活动拖到 Invoke 活动正上方。将源设置为 inputvariable。创建项目时,将自动创建此变量。将此变量定义为创建 BPEL 流程时为输入设置的元素类型。将目标设置为 stocks 变量。将文件名设置为 TransformStock 并选择 Create 按钮。 将源 stock 关联到目标 STOCKS,并在 auto-select 对话框中选择 OK。转换工具按名称关联它可以匹配的字段(如果需要,可以添加字典以匹配常用字段名)。关联所有其余字段。然后,由于我们可以具有多行源数据,因此添加 xslt for-each 结构。将此结构从 Component Palette XLST Constructs 选项板拖到目标 STOCKS 元素。然后,将源 stocks 元素关联到 for-each 结构。 最后一步也是将输出变量设置为合作伙伴股票值。这不是严格必需的,因为我们将结果写入文件,但是当我们在 BPEL 控制台中测试流程时,这样易于查看结果。 将 Assign 活动拖到 Invoke 活动下方。双击打开它。在 General 选项卡上,将名称设置为 Assign_Output。在 Copy Operation 选项卡上,从 Create 菜单中选择 Copy Operation。 您将看到 Invoke 和 Assign 活动上的两个警告标志。JDeveloper 警告您所使用的变量尚未初始化。实际上,转换已初始化 Invoke_Write_Input,但 JDeveloper 未识别。可以忽略警告。右键单击项目名并选择 Deploy -> IntServerConnection -> Deploy to default domain。查看 Apache Ant 日志窗口,直到您看到绿色 Build Successful 消息。现在项目已部署。 打开浏览器并输入 URL http://localhost:8888/BPELConsole,将 localhost 替换为在其中部署了您的服务的服务器的名称(如果此服务器不是您的本地计算机),将端口替换为 9700(如果您使用默认 WebLogic 端口)。使用用户名 oc4jadmin 或 weblogic 以及您的配置口令登录。 在信息板上,您将看到新流程 TranslateStockProcess。选择流程以转到此流程的启动页面。您将看到输入模式为 HTML 格式。输入一些数据。您可以选择绿色加号以输入另一行数据。选择 Post XML Message。 流程将启动,并包含输入数据。由于此流程是同步流程,因此立即将回复发回浏览器窗口。您还可以选择 Visual Flow 图标查看图形化审计跟踪。 将文件写入输出目录。找到文件并查看内容。根据 STOCKS_PARTNER 模式,输出为 xml 格式。 在此用例中,您了解了如何在 BPEL 流程中将数据写入文件。您将数据转换为文件适配器服务所期望的格式。您还了解了如何通过启动流程和手动输入输入数据来使用 BPEL 控制台测试服务。您可以扩展 BPEL 流程以便以其他方式操作数据,或者甚至从其他服务调用 BPEL 流程并因此传入数据。 让我们转向最后一个用例。返回 JDeveloper,关闭所有打开的文件。 |