文章
![]() |
SOA 最佳实践:BPEL 指南 |
|
第 2 部分:使用 BPEL 构建 Web 服务网络 欧洲航天局使用 BPEL 作用域、BPEL 域和 Oracle BPEL 流程管理器 API 构建易于合作伙伴使用的 Web 服务网络的案例研究。
受不断成熟的 Web 服务标准的鼓舞,越来越多的组织正在协作环境中使用 Web 服务。BPEL 正快速成为为实现企业间协作而编排这些 Web 服务的平台。BPEL 为构建在线市场或协作网络的公司提供了引人瞩目的好处,即基于标准的方法和松散耦合的流程集成。 而 Web 服务提供的激动人心的新功能却隐藏着某些风险。在许多情况下,如果在设计时未解决某些技术和管理难题,则合作伙伴关系将会破裂或集成成本飙升:
在 BPEL 指南的这一部分中,我将把欧洲航天局 (ESA) 项目(来自 Spacebel s.a. 的小组参与了该项目)作为一个案例分析,介绍与这些挑战相关的体系结构注意事项。此外,我还将介绍该项目如何利用 BPEL 作用域、BPEL 域和 Oracle BPEL 流程管理器 API 构建一个“易于合作伙伴使用的”协作网络。 ESA 网络概述 ESA 已着手制定一个战略性计划,旨在完全基于开放标准创建一个 BPEL 驱动的服务提供商协作网络。该网络称作服务支持环境 (SSE) 网络,它组合第三方的地球观测 (EO) 和地理信息系统 (GIS) 服务,提供增值的复合型服务。SSE 是一个不断壮大的网络,目前包括遍布 9 个不同国家/地区的 20 多个合作伙伴。 如图 1 所示,SSE 是一个支持 BPEL 的网络的简单实现。ESA 充当中介,它使用各种 Web 服务标准(如 SOAP、WSDL、WS-Addressing、WS-Inspection 等)为不同合作伙伴之间基于流程的协作提供支持。该网络在集中星型拓扑环境中运行:服务提供商使用 Oracle BPEL Designer 将不同类型的地球观测和 GIS 服务集中到一个信息库中,从而创建了一个不断扩大的服务目录。
图 1 SSE 体系结构 SSE 提供执行以下任务所必需的基础架构
SSE 支持同步和异步的交互模型。ESA 广泛使用 Oracle BPEL 流程管理器 API 来为提供商和最终用户提供最大程度的灵活性和易用性体验。 设计 Web 服务网络 开放标准正在不断改变集成的规则。BPEL 提供了一个以流程为中心的跨企业集成方法,因此可以使用 BPEL 流程流定义合作伙伴集成。SOA 与 BPEL 的这一组合为构建松散耦合的协作网络提供了一个前所未有的良机。 集中星型(SSE 采用的方法)是一个广泛使用的网络拓扑,组织通过它与各种合作伙伴建立连接。网络也可以采用单向对等模型。这种情况下,每个合作伙伴都为 Web 服务安全性和供应提供了一个平台。 现在,我们来看网络设计的四个方面:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:oi="http://www.esa.int/oi">
<!-- Import statements -->
<xsl:import href="./SSE.xsl"/>
<!-- Apply the template for the root element from SSE standard template -->
<xsl:template match="/">
<xsl:apply-imports/>
</xsl:template>
...
xsl:apply-imports 使用从 SSE 样式表中导入的模板规则处理根节点。注册该服务时,服务提供商提供 XML 模式、WSDL 和 XSLT 文件的 URL。SSE 强制使用文档样式的 SOAP。该方法允许使用 XML 模式对输入服务和服务输出的数据进行详细的指定并验证传入和传出的消息。
ESA 采用的方法为打算构建一个合作伙伴数量有限的 Web 服务网络的公司提供了一个便捷解决方案。随着网络规模的增长,将需要引入新的消息格式、通信规则、安全性以及传输机制。 简化合作伙伴的参与。任何网络的壮大都离不开合作伙伴的轻松参与。下列因素将对此过程产生很大的影响。
例如,为加快集成流程的速度,ESA 分发了 SSE Toolbox,这是一个在 SSE 与服务提供商的现有系统间充当接口的免费工具包。基于 Sun Java Web Services Developer Pack 的 SSE Toolbox 提供了一个支持各种后端集成机制(如 FTP、文件交换、JDBC、调用 Java API、HTTP 等)的 XML 脚本语言。它还自动生成注册服务所需的 WSDL 文件。 不同的合作伙伴将多个服务提供给中央信息库。开发和部署环境的划分使合作伙伴间的更改互不影响。SSE 通过在 Oracle BPEL 流程管理器中使用 BPEL 域有效地利用了划分功能。BPEL 域使开发人员或管理员能够将 Oracle BPEL 流程管理器的单个实例划分为多个虚拟 BPEL 沙箱。BPEL 域由一个 ID 标识,并由一个口令保护。当服务提供商在 SSE 上注册时,将调用 Oracle BPEL 流程管理器 API 自动创建一个 BPEL 域保存服务定义文件。 以下是一个 createDomain 方法示例:
/**
* Create new domain space for a service provider to hold her/his services workflow
* definitions files in
*
* @param domainName The Id to identify the domain
* @param password The password used to login to the corresponding domain
* @exception RemoteException System communication error
* @exception WorkflowException Thrown if any error happens on the server that prevent the delete
*
*/
public void createDomain(String domainName, String password)
throws RemoteException, WorkflowException{
if(ml.isDebugEnabled()) ml.debug("Enter createDomain(domain = " + domainName + " password = " + password);
/**
* check if the being created domain exist?
*/
try {
Locator locator = new Locator(domainName, password);
ml.info("Stop creating domain:" + domainName + " because it has already existed.");
throw new WorkflowException("1019");
} catch (com.oracle.bpel.client.ServerException e) {
;
}
try {
//obtain the domain admin password from the system configuration SSE.properties file
String domainAdminPassword = SystemConfigurationInfo.getProperty(WorkflowConstant.BPEL_DOMAIN_ADMIN_PASSWORD);
ServerAuth auth = ServerAuthFactory.authenticate( domainAdminPassword, "localhost" );
if(ml.isDebugEnabled()) ml.debug("obtain authentication ok");
// Create server object ... this is our service interface
//
Server server = new Server( auth );
// Domain id is "newDomain", the password is "myPassword"
if(ml.isDebugEnabled()) ml.debug("create server instance ok");
//
Map domainProperties = new HashMap();
domainProperties.put( Configuration.DATASOURCE_JNDI, SystemConfigurationInfo.getProperty
(CommonConstant.DEFAULT_BPELDOMAIN_DS_JNDI));
domainProperties.put( Configuration.TX_DATASOURCE_JNDI, SystemConfigurationInfo.getProperty
(CommonConstant.DEFAULT_BPELDOMAIN_DS_JNDI));
if(ml.isDebugEnabled()) ml.debug("create domain - ds jndi property key/value:
" + Configuration.DATASOURCE_JNDI + "/" + SystemConfigurationInfo.getProperty
(CommonConstant.DEFAULT_BPELDOMAIN_DS_JNDI));
if(ml.isDebugEnabled()) ml.debug("create domain - tx_ds jndi property key/value:
" + Configuration.TX_DATASOURCE_JNDI + "/" + SystemConfigurationInfo.getProperty
(CommonConstant.DEFAULT_BPELDOMAIN_DS_JNDI));
server.createDomain(domainName, password, domainProperties);
if(ml.isDebugEnabled()) ml.debug("Enter createDomain(domain = " + domainName + " password = " + password);
} catch( com.oracle.bpel.client.ServerException se ){
ml.error(se.getMessage());
if(ml.isDebugEnabled()) se.printStackTrace();
throw new WorkflowException("1018", se.getCause());
}
}
在下面 runBuildScript 方法的实现中,通过一个 Ant 构建脚本访问 Oracle bpelc 函数。 runBuildScript 方法调用一个 Ant 项目文件,后者随后调用 bpelc 编译和部署服务提供商的 BPEL 流程。
/**
* execute the ant script to build an Oracle BPEL process that implements the workflow.
* The script also deploys the workflow to the service domains.
* All input information is provided under the props at the input param.
* @param props Contain all necessary properties used to build/deploy the workflow BPEL process
* @throws WorkflowException
*/
private void runBuildScript(String buildFilename, Properties props) throws WorkflowException{
if(ml.isDebugEnabled())ml.debug("Enter runBuildScript(buildFileName = " + buildFilename +
", properties = ...");
try {
Project project = new Project();
project.init();
File buildFile = new File(buildFilename);
if (!buildFile.exists()) throw new WorkflowException("1015");
if(ml.isDebugEnabled()) ml.debug("ant build file:" + buildFile.getAbsolutePath());
ProjectHelper.configureProject(project, buildFile);
//prepare logger for the project build
PrintStream out = System.out;
BuildLogger logger = new DefaultLogger();
logger.setMessageOutputLevel(Project.MSG_DEBUG);
logger.setOutputPrintStream(out);
logger.setErrorPrintStream(out);
project.addBuildListener(logger);
//set project properties
Enumeration keys = props.keys();
while(keys.hasMoreElements()){
String key = keys.nextElement().toString();
project.setProperty(key, props.getProperty(key));
}
// test
//excute default target
project.executeTarget(project.getDefaultTarget());
if(ml.isDebugEnabled())ml.debug("Exit runBuildScript(buildFileName = " + buildFilename +
", properties = ...");
}
catch (Exception ex) {
ml.error(ex.getMessage());
if(ml.isDebugEnabled()) ex.printStackTrace();
throw new WorkflowException("1002",ex.getCause());
}
}
在 Web 服务网络设计中,应考虑使用 BPEL 域为所有相关各方划分流程设计和部署平台。以下是一些可能的应用:
在该流程中,合作伙伴将他们的 Web 服务发布到一个中央信息库,有关该服务的所有信息都在这里进行管理。这个中央框架提高了服务的可重用性,最大限度地降低了定位服务所需的工作量和时间。没有中央信息库将导致不一致和混乱。这反过来会降低网络的灵活性和开放性。 SSE 网络频繁使用中央 Web 服务信息库;合作伙伴使用 Web 服务检查语言 (WSIL) 发现可用服务。服务提供商可以通过选择相应的 WSDL 文件重用现有的 Web 服务(由网络中的其他提供商提供)。可以在 Oracle BPEL Designer 工具配置文件 UDDIProviderList.xml 中添加 WS-Inspection URL http://services.eoportal.org/inspection.wsil 来完成此任务,如下所示。 <provider> <description>ESA SSE Portal</description> <type>wsil</type> <inquiryURL> http://services.eoportal.org/inspection.wsil </inquiryURL> </provider>位于服务提供商处的 Oracle BPEL Designer 连接到 SSE 服务器并使用 WS-Inspection 协议发现可用服务及其 WSDL 文件。连接到 WS-Inspection 服务器后,将显示所有可用服务列表,如图 2 中所示。
图 2 可用 SSE 服务列表 对于每个服务,将提供相应的 WSDL 文件和简短的文字描述。可以通过选择 WSDL 文件为该服务添加一个合作伙伴链接。构建流程流后,可以使用 BPEL 控制台将其部署在 SSE 门户上。(在它的下个版本中,SSE 将实现 UDDI 注册表与 Oracle BPEL 的集成。注册新服务时,还将在此 UDDI 注册表中自动注册该服务。该集成将简化使用外部工具的服务发现,目前仅当这些工具支持 WS-Inspection 时才能发现服务。) 尽管您不必建立服务信息库即可构建 SOA 并获得它的众多好处,但从长远来看,信息库是不可或缺的。如果服务的作用域只是一个项目,则架构师不用信息库也能处理。但大多数企业都拥有各种服务和合作伙伴,并且这些服务和合作伙伴的大部分都在不断变化。 提供自助式监视。在多方参与业务流程的协作网络中,对业务流程执行情况的监视非常关键,因此可以将围绕业务流程的关键性能指标与服务级协议相联系。(例如,加入网络的关键要求之一可能是确认两小时内的报价请求。)监视业务流程可以更好地获知特定业务流程实例执行的时间、出现延迟的原因以及如何为未来事务修复此问题。 应向合作伙伴和最终用户提供该级别的诊断。通过创建自助式环境,合作伙伴和最终用户可以跟踪他们的单个流程,从而减轻中央监视框架检测到的问题。 可以使用 Oracle BPEL 控制台监视和调试业务流程(参见图 3)。ESA 和服务提供商利用 BPEL 控制台跟踪正在运行和已经完成的 BPEL 流程实例数量、流程实例的平均持续时间(从而细分流程中消耗的时间)以及文本格式的流程实例审计线索,从而使合作伙伴可以查看中间结果。
图 3 使用 Oracle BPEL 控制台监视业务流程 此外,订购了特定服务的最终用户可以跟踪其订单的状态。可以使用 Oracle BPEL 流程管理器 API 在 BPEL 控制台的外部显示该信息。建议服务提供商在他们的 BPEL 流程中使用有意义的作用域名称;在运行时,门户使用 IInstanceHandle.getStatus() API 提取当前 BPEL“作用域”的名称向最终用户显示该进度的信息。 作用域 按层次结构组织,一个复杂的业务流程可以分为几个作用域。它们为活动提供了行为上下文。通过在 BPEL 流程中使用有意义的作用域名称,合作伙伴可以跟踪“短期”和“长期”业务流程的状态。 例如以下 getOrderSubstatus 方法的实现。该方法使 ESS 合作伙伴可以使用在 bpel 文件中执行的作用域的名称获取 BPEL 流程实例的当前状态。
* call the Oracle BPEL API to get current status of the workflow instance, corresponding to
* the ordered supplied at the input
* @param ordered The order identified
* @param workflowId The workflow name (or Id) that is processing the order stage.
* Normally, there are two stages of an order:send(process)rfq and send(process) order
* @param domain The domain that the order workflow belongs to
* @param password The password used to login to the workflow domain
* @return the current status of the workflow instance - particularly, it is the name of the current
* active scope in the workflow BPEL file.
* @throws RemoteException
* @throws WorkflowException
*/
public String getOrderSubstatus(String ordered, String workflowId, String domain, String password)
throws RemoteException, WorkflowException
{
if(ml.isDebugEnabled()) ml.debug("Enter getOrderSubstatus(ordered = " + ordered
+ ", workflowId = " + workflowId + ", domain = " + domain + ", password = " + password);
String status = "";
try {
Locator locator = new Locator(domain, password);
IinstanceHandle instance = locator.lookupInstance(ordered + "_" + workflowId);
if( instance.isComplete() ) status = "Completed";
else status = instance.getStatus();
return status;
} catch (com.oracle.bpel.client.ServerException e) {
// TODO Auto-generated catch block
ml.error(e.getMessage());
if(ml.isDebugEnabled()) e.printStackTrace();
throw new WorkflowException("1016", e.getCause());
}
}
结论
ESA 在构建其整个协作网络时始终没忘其灵活性。接口关系的灵活定义简化了网络的采用并促进了网络的发展。BPEL 域的采用提供一个独立的工作区,从而为服务提供商提供了广泛的灵活性;服务提供商可以修改他们的业务流程且不会影响网络的稳定性。BPEL 作用域已经使 ESA 可以从细节上跟踪即时流程的状态。该网络还可代表服务供应提供商自动生成 BPEL 流程流。所有这些因素渐渐地使该网络更易于合作伙伴使用,并最大限度地降低了合作伙伴的前期投资。 但还有一些网络设计领域本文并未涉及,如分布式事务管理、安全性以及贸易合作伙伴管理。随着 B2B 网络规模的扩大,BPEL 可以在编排专用流程方面处于领先地位。例如,Oracle 集成 B2B 产品(可以与 Oracle BPEL 流程管理器交互操作)解决了公共流程编排、握手协议支持(RosettaNet、ebXML、EDI、HIPAA)、消息格式处理(MIME、SMIME、AS2、XMLDSig)和贸易合作伙伴管理(认可、服务级协议、合作伙伴协议)。
The Hoa Nguyen 当前在 Spacebel s.a.(位于布鲁塞尔)的 SDC 子公司担任高级软件工程师。他的主要兴趣是 J2EE、Web 服务以及使用 BPEL 进行工作流开发。自 2001 年以来,他一直是 Spacebel 的 SSE 项目小组的主管工程师之一,此外他还在 ESA 负责 SSE 软件发布以及 SSE 软件现场安装。 |