许多组织正从面向对象的业务流程管理范例转移到面向服务的方法;实际上,服务正在成为应用程序开发的基本元素。同时,业务流程执行语言
(BPEL) 已经成为编排这些服务和管理业务流程的无缺陷执行的事实标准。这些趋势所产生的结果是,为更灵活、更经济高效地管理业务流程提供了一些良机。
大多数业务流程(贷款审批就是一个典型示例)包含多个决策点。在这些决策点处,将对某个条件进行评估。业务流程根据这些标准或业务规则更改它们的行为。实际上,这些业务规则对业务流程起到了推动作用。这些规则通常嵌入到业务流程本身或自定义
Java 代码的内部,这将导致在将来的某个时候出现若干问题:
- 业务规则比业务本身更改得更频繁,而更改和管理嵌入的业务规则是一个复杂问题,并超出了大多数分析员的能力范围。因此,随着业务规则的更改,程序员通常要消耗大量时间来执行该任务。
- 大多数组织都缺少中央规则信息库。因此,策略中任何涉及到组织范围的更改都无法运用到所有业务流程中。
- 业务流程无法重用规则。因此,IT 人员最终要为每个流程设计规则,这通常导致不一致性或冗余。
避免这些问题的最佳方法是使用规则引擎将业务流程与业务规则分离。在该方法中,规则公开为服务,而
BPEL 流程在到达决策点时通过查询该引擎来利用这些服务。该方法更为灵活 - 可以通过图形方式操作规则,而不是在编程语言中或在流程内部对规则进行编码。业务用户可以使用工具自行编写规则,并且无需
IT 人员的协助即可进行部署后的规则更改。由于大多数更新和功能增强是由业务用户执行的,因此可以显著减少维护成本。
规则引擎和 BPEL 是两种互补技术。Oracle BPEL 流程管理器提供了高级工具来显示、设计和管理 BPEL 流程,而第三方规则引擎使复杂的业务逻辑可以用类似英语的语法表示,并由非程序员领域专家对其进行编辑。
在“BPEL 指南”的第一部分中,我将根据我所在团队的自身经验来提供分离流程和规则的最佳实践。并通过代码示例提供一种开发方法,更改将
BPEL 与规则引擎集成的管理策略。最后,我将介绍该体系结构如何在不同的层中正确划分逻辑。
分离规则与流程
将规则引擎集成到流程管理框架中要求事先进行一定量的投资。在尝试进行此集成之前,将规则与流程分开是很重要的。因此,系统体系结构方面的一个主要决策是如何实现业务策略、业务流程和支持业务逻辑。实际上,架构师必须交流或设计最佳实践,以便设计人员在设计系统功能时知道应在何处应用每个相关技术
- BPEL、业务规则、Java/Web 服务。
如图 1 所示,业务逻辑被分布到三个不同的 IT 基础架构层中:业务流程、Web 服务和规则。我们将对它们进行依次介绍。
图 1 体系结构:分离规则与流程
业务流程层。该层负责管理业务流程的总体执行。这些使用 BPEL
实现的业务流程可以是长期运行的业务流程、事务业务流程以及持久业务流程。流程逻辑支持分布到 Web 服务/EJB 调用中的高级事务(“sagas”)以及嵌套的子流程事务。BPEL
引擎支持对工作流进行审计和检测,因此比较适合于
- 将不易变化的工作流步骤与易变的业务规则分开
- 实现行业流程
- 实现需要补偿的流程
- 支持流程的大型实例化
- 设计需要审计的流程
- 协调异构技术,如连接器、Web 服务和支持 Web 服务调用框架 (WSIF) 的逻辑
Web 服务层。Web 服务层将现有的应用程序层功能公开为服务。这样,多个业务流程便可以重用这些服务,从而实现面向服务体系结构
(SOA) 的承诺。
Web 服务实现功能逻辑和域逻辑。功能方法通常是无状态和中等粒度的。例如,Web 服务可能包含系统数据的实用程序方法、实体操作和查询方法。可以使用多种技术实现
Web 服务并隐藏实现平台之间的差别。因此,该层比较适合于:
- 为特定实体/域领域实现中等粒度的方法
- 集成原有的代码/第三方工具
- 封装应用程序层中的逻辑、自定义代码和实现
规则层。规则引擎通常是复杂逻辑(涉及实体之间的一些相互依赖性以及与顺序相关的逻辑计算)的发源地。从业务流程中以单独实体的形式提取业务规则可更好地对系统进行分离,从而提高可维护性。
规则引擎可以对规则集进行并行和按顺序的评估。此外,规则能够对输入数据和中间数据的值进行评估并确定是否应引发规则。与传统的
Java 过程代码相比,该模块设计提供了一个更简单、可维护性更高的解决方案。
此外,正如我在前面指出的,规则具备声明特性,并使业务分析员能够进行高级 GUI 编辑。现代规则引擎的执行速度非常快,并提供了内置的审计记录。规则层的典型特性包括
- 包含耦合和复杂的逻辑
- 支持使用并行执行进行高效的业务逻辑评估
- 包含基于多个业务规则评估构建的复杂返回结构
- 允许将域逻辑转换为简单规则
- 实现高度易变的业务策略
由于规则在 Web 服务层中公开为服务,因此可以在所有企业间应用程序中重用,从而简化了新应用程序和集成的开发。
开发和维护
为演示开发过程,我将使用称作 Eligibility Process 的业务流程示例。该流程用于评估家庭是否有资格加入特定的医疗保健项目。根据家庭的属性(收入、子女总数),它将该家庭指定给
Healthcare Program 1 或 Healthcare Program 2。在分析阶段,根据易变性和复杂性将逻辑分为不同类别的存储桶。正如在前一部分中所介绍的,规则通常对复杂的返回结构(需要多个业务验证以及频繁更改或影响组织大部分的策略)进行建模。而部门或组织流程则在业务流程层中建模。
典型的开发流程包含三个步骤:
- 在规则集中创建规则
- 将规则集公开为 Web 服务
- 从 BPEL 中调用规则集 Web 服务
开发阶段需要专门的角色(如规则开发人员、流程开发人员、业务分析员和 Web 服务开发人员)才能完成这些任务(请参阅图
2)。
图 2 开发和维护角色
1. 在规则集中创建规则。 在开发的最初阶段,规则开发人员在集成的图形开发环境(如 ILOG
的 JRules 业务规则管理系统)中创建初始规则。(有关 Oracle Fusion 中间件中业务规则功能的信息,请参阅边条。)
创建规则前,应设置规则信息库和对象模型。通过规则信息库可以在业务规则的生命周期内维护和管理业务规则。业务规则操作的问题域通过
ILOG JRules 以业务对象模型 (BOM) 的格式表示。BOM 通过表示模型的可执行版本的 Java 类或 XML
模式表示。XML 模式可以帮助确保数据的灵活性。详细地实现对象模型通常是开发人员的任务。 开发人员创建对象模型和规则信息库后,您需要决定哪些规则可以由分析员维护,以及哪些规则要用低级语言
(IRL) 开发。创建开发人员级规则后,开发人员与分析员协作标识剩余规则并在规则模板(可以由多个非技术方重用)中捕获它们。该方法简化并加快了规则的生成,同时减少了可能出现的人为错误。
为启动基于模板的规则创建流程,分析员需连接到规则信息库。当分析员从信息库中打开规则程序包时,他们将能够访问该程序包的
BOM。ILOG 支持通过它的业务应用程序语言 (BAL) 定义高级规则。分析员可以在此时编辑现有规则,也可以创建新规则。可以在维护期间通过模板(用于限制可以对规则进行的修改)修改规则。
规则编辑器有一个默认模板,使开发人员可以使用 IF–THEN 结构创建条件和操作。如图
3 所示,业务分析员创建了一个检查家庭子女总数的规则。如果该变量等于 2,则家庭有资格参加 Healthcare Program
1。规则在数据类型 eligibilityResult 中返回值 true。
|
Oracle
Fusion 中间件规则引擎 该示例演示了如何将 ILOG
的规则引擎与 Oracle BPEL 流程管理器集成在一起,但请注意,Oracle Fusion 中间件的未来版本将把一个新的本机业务规则引擎与
Oracle BPEL 流程管理器集成在一起。
使用 Oracle BPEL Designer 中的 Decision
Service 向导,用户可以将业务规则集成到 BPEL 项目中。该向导将能够浏览 Oracle Business
Rules(Oracle 业务规则)以及第三方规则引擎的信息库。此外,用户能够将 BPEL 变量映射为规则信息库中的事实、插入新的事实并执行规则。然后,BPEL
引擎将针对规则引擎事实自动执行从基于 XML 的变量到基于 Java 的数据类型的任何格式转换。
部署后,业务用户将能够访问与业务流程相关的规则并进行更改,而不必重新部署流程。该方法将显著简化
BPEL 流程与规则引擎的集成,并增强体系结构的灵活性。 |
|
图 3 创建一个检查家庭子女总数的规则
开发一个新规则后,可以使用 ILOG Rule Builder 工具内部的示例数据对其进行测试。Rule
Builder 中的该调试器支持断点,使用户可以检查有效的内存数据并显示规则执行顺序。完成规则编辑和测试后,分析员将规则程序包导入到规则集中并部署回信息库。
以下代码示例显示了 Eligibility ruleset 的实现。
// Eligibility ruleset
receives an account and calculates eligibility results for
multiple programs
ruleset eligibility {
in Account account;
out List eligibilityResultsList = new ArrayList();
}
// calculate program 1 then program 2 eligibility
flowtask Program1_TaskFlow {
body = {
Program1_Setup;
Program1_Eligibility;
Program2_Setup;
Program2_Eligibility;
}
};
// Determine which rules are setup rules
for program 1
ruletask Program1_Setup{
body = select(?rule) {
if("Program1_Setup".getTask(?rule) )
return true;
else
return false;
}
}
// Determine which rules are eligibility
rules for program 1
ruletask Program1_Eligibility{
body = select(?rule) {
if("Program1_Eligibility".getTask(?rule) )
return true;
else
return false;
}
}
// Create an eligibility result (JAXB object)
for program 1
rule Progam1.CreateEligibilityResult {
property task = " Program1_Setup";
when {
?account:Account();
?person:Person();
}
then {
bind ?result = new EligibilityResult ();
?result.setPersonId(?person.getPersonId());
?result.setProgramType(ProgramEnum.PROGRAM1);
?result.setEligible(Boolean.FALSE);
modify ?person { getEligibilityResults().add(?result); };
}
};
// simple rule make person eligible if over 6 years old and
returns
// result back in finalResults map
rule Program1.AgeQualification {
property task = " Program1_Eligibility";
when {
?person:Person(?age:getAge().intValue(););
evaluate(?age >= 6);
}
modify ?result {setEligible(Boolean.TRUE); };
finalResults.add(?result);
}
}; |
2. 将规则集公开为 Web 服务。 JRules 等规则引擎提供了相应的工具来生成包装程序
Web 服务或会话 Bean,以包装新开发的规则集。Web 服务开发人员将创建一个包装程序,以将规则集公开为 Web 服务。
XML 是一个用于集成规则、EJB、BPEL 流程和 Web 服务的关键标准。BPEL 使用本机
XML 访问数据,而 Web 服务使用它来序列化数据(并将在 Doc/Literal 调用中原封不动地使用它)。XML 可以在规则中直接使用。通过编组,可以将
XML 直接转换为 JAXB 对象树。可以使用本机 Java 对象执行规则。
Web 服务应在它们相应的 WSDL 定义中导入 XML 模式。从 XML 模式中生成的 DTO 对象(如 JAXB)还可以帮助确保数据顺利转换,而不会出现转换错误。
Eligibility Web 服务提供从 XML 到 JAXB 的转换,然后调用 Eligibility
Rules Delegate Session Bean。要隐藏调用 JRules 自定义库的复杂性,可以创建一个会话 fa?ade。该方法使实现规则引擎“不可知”;可以将系统轻松地移植到一个新的规则引擎提供程序。Eligibility
Delegate Session Bean 对 Eligibility fa?ade Session Bean 进行 RMI 调用。该会话
bean 使用 ruleSession.executeRules("RuleApp/eligibility")
调用 RuleApp 程序包中的 Eligibility ruleset。
import ilog.rules.bres.session.IlrRuleExecutionResult;
import ilog.rules.bres.session.IlrStatelessRuleSession;
import ilog.rules.bres.session.ejb.IlrManagedRuleSessionProvider;
import ilog.rules.bres.session.util.IlrRuleSessionHelper;
.
.
.
public List assessEligibility(AccountRoot account) {
List eligibilityList = null;
// get stateless rulesession instance
IlrStatelessRuleSession ruleSession = null;
try {
ruleSession = IlrManagedRuleSessionProvider.getProvider()
.createStatelessRuleSession();
} catch (ilog.rules.bres.session.IlrRuleSessionCreationException
ce) {
String msg = "Failed to retrieve RuleSession Provider";
throw new InfrastructureException(msg, ce);
}
// pass borrower and credit as "in"
parameters of the stateless session.
IlrRuleSessionHelper helper = new IlrRuleSessionHelper(false);
helper.addParameter("account", account);
try {
// execute rules and handle results
IlrRuleExecutionResult res = ruleSession.executeRules("/RuleApp/
eligibility", null,
helper.getJavaClassResolver(this), helper.getParameters());
eligibilityList = (List)res.parametersOut.getHandle("finalResults").getValue();
} catch(Throwable t) {
String msg = "Failed to execute rule!";
throw new InfrastructureException(msg, t);
}
return eligibilityList;
} |
3. 从 BPEL 调用规则集 Web 服务。 开发所有自定义系统组件后,开发人员应将系统与
BPEL 引擎集成。原有系统和新的自定义组件由 BPEL 流程编排。可以在此时解决兼容性、数据类型转换和 Web 服务协议方面的问题。流程开发人员和/或系统集成商将在
Oracle BPEL Process Designer 内部实现编排流。
例如,BPEL 将使用以下代码调用基础 Eligibility Web 服务。
<assign name="setAccount">
<copy>
<from variable="BPELInput" part="payload"
query="/tns:EligibilityProcessRequest/tns:Account">
</from>
<to part="parameters"
query="/nsxml0:assessEligibility/nsxml0:Account"
variable="webservice_account"/>
</copy>
</assign>
<invoke name="CallEligibilityWebservice"
partnerLink="EligibilityWebservice"
portType="nsxml0:EligibilityService" operation="
assessEligibility "
inputVariable="webservice_account" outputVariable="webservice_eligibilityResults"/> |
维护阶段。 对于维护阶段(项目中的最长阶段)而言,将业务规则移出 Java 代码并移入规则引擎中将增强维护的可管理性。正如我在前面所介绍的,业务管理者可以在运行时使用图形界面修改规则,业务规则和
BPEL 流程可以相互独立地进行更改。
使用 Oracle BPEL 流程管理器执行 JRule
显然,规则、Web 服务和 BPEL 流程的设计和开发涉及多种不同的技术。在本部分中,我将介绍这些技术如何在运行时协同工作以执行
Eligibility Process。尽管该示例专门基于 Oracle BPEL 流程管理器和 ILOG JRule,但它可应用于许多其他环境。
规则引擎调用将出现在三个层中(请参阅图 4):BPEL 调用规则 Web 服务、规则 Web
服务调用规则引擎、规则引擎应用程序代码接收输入并返回结果。
图 4 规则引擎调用演示
在示例业务流程的上下文中,应用程序使用 XML 有效载荷调用 Eligibility process。该有效载荷包含有关帐户的信息(如家庭属性)。Eligibility
process 反过来调用 Eligibility Web service。Eligibility Web service 提供从
XML 到 JAXB 的转换,然后调用 Eligibility Rules Delegate Session Bean。后者使用
RMI 与会话 session fa?ade 交互。Session fa?ade 激活规则引擎,后者随后计算 eligibility
结果并将这些结果返回给该流程。Eligibility Process 将评估返回的结果并将 Program 1 或 Program
2 指定给该帐户。在该示例中,我们提供了一个远程服务器来运行 eligibility 规则,也可以在本地托管该规则。(注意,最佳实践是不要将非流程服务与
BPEL 流程管理器放在同一位置,这样可以实现更好的可伸缩性。)
该示例有效演示了如何将业务逻辑划分为规则、BPEL 和 Web 服务:
- Eligibility BPEL Process 显式定义了必须根据接收的 Eligibility
Results 数据执行的步骤。Eligibility BPEL Process 将基于 Eligibility Results
调用不同的分支。Program 1 和 2 分别执行不同的步骤,可以使用 BPEL Designer 轻松地修改这些步骤。
- Eligibility Web 服务为 BPEL 流程管理器执行中等粒度的任务,BPEL
流程管理器封装有关如何发送对应关系以及将任务排队的机制。Web 服务作用于诸如数据库键(如 Account OID)这样的常见数据模型(可用于提取详细数据以执行所需任务)中的摘要数据。
- Eligibility 规则既不修改原始数据,也不访问外部数据源。由于您拥有准确的规则数据输入/输出记录,因此规则引擎审计线索比较简单。
图 5 演示了通过 Web 服务将规则集成到 J2EE 平台的细节。规则被部署到独立的 ear
(EligiblityRules.ear) 中并在规则引擎管理控制台中注册。余下的支持逻辑部署在另一个 ear (EligibilityRuleService.ear)
中,后者包含 EligibilityRules 将需要的 Account JAXB 对象的类以及用于调用规则的会话 fa?ade。会话
fa?ade 隐藏了调用 JRules 自定义库的细节,同时还可以使系统移植到一个新的规则引擎提供程序。
图 5 通过 Web 服务将规则集成到 J2EE 平台中
结论
在这篇 BPEL“指南”中,我介绍了用于在三个不同层(业务流程层、Web 服务层和规则层)中分布业务逻辑的策略。可以使用这些辅助技术最大限度地降低数据和逻辑之间的相关性。但是,为了获得充分的好处,设计师必须执行严格的分析以分解系统组件,并使用相应的技术来设计它们。开发过程涉及多种技术和各种角色。在参与开发过程之前,必须标识相应的资源。最终的体系结构是一个灵活的平台,业务用户可在该平台上处理多数业务更改,而无需
IT 人员的参与。 |