`
sanshi
  • 浏览: 82070 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

流程静态建模机制的扩充性

阅读更多
摘要:在工作流引擎的设计过程中,如何确保引擎兼具内核的轻巧性和外延的强大性,是一直困扰我们的关键设计问题。本文在系统地研究jBPM的建模语言和体系结构的基础上,提炼出jBPM针对上述问题的解决方案:

¨       在流程静态建模层面,建模语言jPDL系统地、全面地支持自定义构件的挂接;适度分离粗略的业务流程定义和精确的技术流程定义,并确保软件二次开发人员可以在业务分析人员给出的业务流程模型的基础上进行精化,保持技术流程基于业务流程的延续性。

¨       在流程动态执行层面,从流程执行支撑、流程功能增强两个方面系统地、全面地设置可拔插(pluggable)的扩充点:

ü        流程执行支撑扩充点包括:流程定义适配,组织模型及任务分派适配,流程实例存储服务适配,外部应用系统适配。

ü        流程功能增强扩充点包括:任务策略扩充,事件监听扩充,日程调度扩充,工作日历扩充,安全控制扩充。

1 流程静态建模机制的扩充性

在jBPM的流程定义语言jPDL中,定义了多种扩充点,包括:条件路由,业务逻辑扩展,任务分派。

1.1条件路由

条件路由通过建模语言中的decision节点来实现。有两种路由方法,一种在静态建模时定义路由条件,另一种由代理类的Java代码在运行时动态决定路由。

¨       静态路由:在decision节点中说明Beanshell表达式。Beanshell是jBPM采用的一种script语言。

11

<decision name='decision'>

<transition name='important lead' to='harras them'>

  <condition expression = ‘……’ />

</ transition>

<transition name='lead' to='put it in the lead db'>

  <condition expression = ‘……’ />

</ transition>

<transition name='beggars' to='forget about it'>

  <condition expression = ‘……’ />

</ transition>

</decision>

¨        动态路由:在decision节点中说明代理(delegation)Java类,由该类在流程实例运行过程中决定路由。

12

<decision name='decision'>

  <handler class='org.jbpm.jpdl.exe.DecisionHandlerTest'/>

<transition name='important lead' to='harras them' />

<transition name='lead' to='put it in the lead db'/>

<transition name='beggars' to='forget about it'/>

</decision>

1.2业务逻辑扩展

jBPM的建模语言jPDL主要通过其event机制提供业务逻辑扩充点。jPDL有预定义的event类型,主要包括:节点进入(node-enter)、节点离开(node-leave)、流程启动(process-start)、流程结束(process-end)、任务创建(task-create)、 任务分派(task-assign)、任务启动(task-start)、定时器事件等。二次开发人员也可以自定义event类型。每个event都可以与action列表绑定。action是一个Java类,其中可以描述定制的业务逻辑。在流程实例运行过程中,当系统捕获到event时,执行相应的action列表。

jPDL提供的业务逻辑扩充点还不止于上述event机制。在node和transition中,均可以定义action,通过action可以对应二次开发人员定制的Java类,从而实现基本工作流系统的业务逻辑扩充。

1.3 任务分派

¨       在流程建模时静态地定义任务分派目标:

ü        针对任务(task)的分派:

13

<task name="evaluate web order">
    <assignment expression="user(ernie)" />
  </swimlane>

ü        针对泳道(swimlane)的分派:

14

  <swimlane name="salesman">
    <assignment expression="group(sale)" />
  </swimlane>

说明:“泳道”是指,在一个工作流模型中执行者相同的任务构成的集合。

¨       通过扩充点动态地定义任务分派目标:

15

<task name='change nappy'
  <assignment class='org.jbpm.tutorial.taskmgmt.NappyAssignmentHandler'
</task>

上例中,实际的任务分派动作由用户自定义类NappyAssignmentHandler完成。该类必须实现jBPM的标准接口AssignmentHandler

1.4 异常处理

在流程定义(process-definition)、节点(node)和迁移(transition)中,均可以定义异常处理器(exception-handler)。异常处理器的内容为一系列的actions,每个action再对应二次开发人员定义的Java类。

2 流程动态执行机制的扩充点

2.1 流程执行支撑扩充点

2.1.1组织模型及任务分派适配

因为组织模型与任务分派紧密相关,所以工作流引擎必须考虑组织模型;但是,组织模型与应用环境也是紧密关联的,所以很难给出标准的、可复用的组织模型。为此,jBPM采用以下递进策略:

¨       jBPM利用其identity compoment来提供对最简单的组织模型的支持,该组织模型仅描述用户、组以及它们之间的关系,其类图如下:

 

上图中,User代表用户或服务,Group代表一类User。Group可以有不同的类型。Membership描述了User和Group之间的多对多关系,也可以用来指示User在Group中扮演的角色。

    为了描述基于上述简单组织模型的任务分派,jBPM定义了一种任务分派表达式,用于在流程建模时静态地定义任务执行者。任务分派表达式的语法如下:

<assignment-exp> ::= <first-term> [--> next-term] 0..*

<first-term> ::= previous |

             swimlane(swimlane-name) |

             variable(variable-name) |

             user(user-name) |

             group(group-name)

<next-term> ::= group(group-type) |

             member(role-name)

例如,previous --> group(‘hierarchy’) --> member(‘boss’) 表示:前一任务执行者所在的类型为hierarchy的组中角色为boss的员工。

¨       在实际应用时,用户的组织机构几乎肯定会比jBPM identity compoment提供的组织模型复杂。所以,二次开发人员可以将实际的组织模型映射到上述简单模型。映射的方法是:填充jBPM identity compoment规定的三张数据库表格:User,Group和Membership。

¨       如果二次开发人员觉得实现上述映射有困难,那么可以完全抛开identity compoment,转而采用任务分派的代理(delegation)机制,即,提供一个任务分派代理类,在该类的Java代码中实现任务分派。jBPM要求代理类必须实现org.jbpm.taskmgmt.def.AssignmentHandler接口。见例1-5。

2.1.2流程实例存储服务适配

流程实例存储服务是指为工作流引擎在流程实例运行过程中提供信息保存和读取的服务机制。为了实现DBMS无关性,jBPM采用以下递进策略:

¨       缺省情况下,jBPM采用Hibernate实现流程实例存储服务。二次开发人员可以通过修改Hibernate的映射和配置文件,就可以根据需要适应特殊的数据库需求。

¨       jBPM3.1在存储服务机制中引进了新的扩充点:二次开发人员可以在代码中指定JDBC connection、Hibernate session和Hibernate session factory。一旦通过以下持久服务资源注入方法来设置自定义的connection、session(factory),jBPM会用它们替代上述配置文件中的资源。

ü         JbpmContext.setConnection(java.sql.Connection connection)

ü         JbpmContext.setSession(org.hibernate.Session session)

ü         JbpmContext.setSessionFactory(org.hibernate.SessionFactory sessionFactory);

2.1.3外部应用系统适配

工作流系统与外部应用的挂接通过建模语言中的action机制来实现。Action可以定义在流程(process)中、节点(node)中、迁移(transition)中、事件(event)中,以及定时器(timer)中。在action的定义中可以指定自定义的Java类,在此Java类中调用外部应用的功能。

例2-1:

<process-definition name="Hi Process">

   <start-state name="start">

      <event type="node-leave">

         <action name="Hi action" class="com.aaa.HiActionHandler"

config-type="bean">

<city>Shanghai</city>

<rounds>2</rounds>

         </action>           

      </event>

      <transition name="tr" to="next_state"></transition>

   </start-state>

    ……

</process-definition>

在上例中,流程实例运行时一旦发生从节点“start”出发的迁移,嵌于事件中的action将被执行,从而实现对类com.aaa.HiActionHandler中Java代码的调用。在该类的代码中,二次开发人员可以实现与外部应用的互操作。

jBPM的建模语言允许通过XML配置向action中的自定义类传递初始参数,例如例2-1中的参数“city”和“rounds”。在action自定义类中,也可以通过jBPM API实现对工作流变元的读写。

2.2 流程功能增强扩充点

2.2.1 任务策略扩充

jBPM在任务策略方面的扩充点包括:任务分配、任务执行与提交时任务与流程之间的信息传递。

¨       任务分配扩充点:“1.3 任务分派”已经描述了任务分派策略的扩充点,即,可以在流程建模时给出基于identity compoment简单组织模型的表达式,静态地定义任务分派目标;也可以指定任务分派代理类,由该代理类在流程实例运行过程中动态确定任务分派目标。除上述扩充点外,jBPM还支持两种任务分配模式:push模式和pull模式。二次开发人员可以根据需要选择自己的分配模式。

ü        在push模式下,工作流引擎(或者其任务分派模块)直接将任务实例与具体的actorId相关联,引擎自动将任务实例push到actor的任务列表中。如果前述分派表达式的计值结果为单个actorId,或者二次开发人员指定任务分派代理类使用Assignable.setActorId(String actorId),那么jBPM系统采用push模式完成任务分配。否则,如果前述分派表达式的计值结果为多个actorId构成的集合,或者二次开发人员指定任务分派代理类使用Assignable. setPooledActors(String[] pooledActors),那么jBPM系统采用下述的pull模式完成任务分配。

ü        在pull模式下,工作流引擎(或者其任务分派模块)将任务实例与多个actorId相关联,这些actorId构成的集合称为pooledActors。jBPM使该任务实例对pool中所有actor可见,但是引擎并不将任务实例推送到这些actor的任务列表中,而是等待pool中的某个actor将该任务实例pull进自己的任务列表中。一旦任务实例被pool中某个actor pull,引擎将该任务实例设置成对pool中其他actor不可见。

¨       任务与流程实例信息交流扩充点:在任务执行时,可能需要读、写流程变量;在任务完成并提交时,可能需要写流程变量。为此,jBPM提供了“任务变量”的概念。在某些情况下,任务变量和流程变量并非简单的一一对应关系,例如,三个流程变量代表三个月的销售额,任务变量只需要它们的平均值。为实现任务与流程实例之间的信息交流,jBPM设置了任务控制器机制。该机制也采用递进模式:首先,jBPM提供基本(默认)的任务控制器;如果不敷使用,二次开发人员可以使用自定义的任务控制器。jBPM的任务控制器机制在流程变量和任务变量之间架起了一座桥梁。

ü        使用jBPM默认的任务控制器:

<task name="clean ceiling">
  <controller>
    <variable name="a" access="read" mapped-name="x" />
    <variable name="b" access="read,write,required" mapped-name="y" />
    <variable name="c" access="read,write" />
  </controller>
</task>

上例中,任务控制器将流程变量a、b、c依次映射为任务变元x、y、c;x从a中读取初值,但在任务完成、提交时x的新值并不写回至a;y从b中读取初值,并在任务完成、提交时将y的新值写回至b;至于c,在任务执行时直接使用流程变量c,并在任务完成、提交时将c的新值带回至流程实例执行环境。

ü        使用自定义的任务控制器:

<task name="clean ceiling">
  <controller class="com.yourcom.CleanCeilingTaskControllerHandler">
    -- here goes your task controller handler configuration --
  </controller>
</task>

二次开发人员提供的自定义任务控制器必须实现以下接口:

public interface TaskControllerHandler extends Serializable 
{
    List getTaskFormParameters(TaskInstance taskInstance);
    void submitParameters(Map parameters, TaskInstance taskInstance);
}

其中,getTaskFormParameters函数负责从流程实例运行环境读取数据至任务执行环境;submitParameters则负责将任务执行环境中的数据提交至流程实例运行环境。

2.2.2 事件监听扩充

jBPM的事件由工作流模型图形元素(node、transition、superstate和process-definition等)和事件类型唯一确定。jBPM定义了一系列与工作流模型图形元素相关联的事件,例如,流程实例运行过程中,可以触发节点进入(node-enter)、节点离开(node-leave)、流程启动(process-start)、流程结束(process-end)、任务创建(task-create)、 任务分派(task-assign)、任务启动(task-start)等事件。

在静态建模时,jBPM的事件均与actions绑定。事件的触发将导致相应actions的执行。如“1.2业务逻辑扩展”所述,这是jBPM支持业务逻辑扩展的主要手段。

<process-definition>
  <event type="node-enter">
    <script>
      System.out.println("this script is entering node "+node);
    </script>
  </event>
  ...
</process-definition>

jBPM的事件传播采用自底向上的模式,关联于某个图形元素的事件首先发往该图形元素;在执行完该图形元素中针对该类事件指定的actions之后,事件继续传向该图形元素的父元素。jBPM对图形元素之间的父子关系定义如下:超状态(superstate)是包含于超状态中的图形元素(例如node,transition等)的父元素;process-definition是所有顶级图形元素(不位于任何超状态中)的父元素。

二次开发人员可以自定义事件类型,并通过GraphElement.fireEvent(String eventType, ExecutionContext executionContext)来发送事件。自定义事件遵循与jBPM标准事件相同的事件处理逻辑和事件传播逻辑。

<process-definition>
  <event type="custom-event">
    <action name="custom-action" class=" com.aaa.CustomEventHandler "/>
  </event>
  ...
</process-definition>

2.2.3 日程调度扩充

jBPM通过定时器(timer)实现日程调度。在node中加入timer元素,即可实现基于定时器的节点执行监控。

<state name='catch crooks'>
  <timer name='reminder' duedate='3 business hours' repeat='10 business minutes'
      transition='time-out-transition' >
    <action class='the-remainder-action-class-name' />
  </timer>
  ...
</state>

在上例中,一旦流程实例运行进入state 'catch crooks',定时器reminder即被创建。该定时器在3个工作小时到期,到期后马上执行action类中的Java代码,然后实施time-out-transition迁移。

    通过在事件的action中加入create-timer和cancel-timer动作,可以分别实现事件对定时器的创建和取消。

2.2.4 工作日历扩充

jBPM的工作日历提供业务时间信息,并可用于计算任务和定时器的超时时间。jBPM缺省提供的属性文件jbpm.business.calendar.properties 定义了工作日历的配置信息,例如,上、下班时间,节假日,日期/时间格式等。

二次开发人员可以通过修改该属性文件来实现对工作日历的定制。

2.2.5 安全控制扩充

安全控制机制包括用户认证和授权控制。jBPM3.0尚未实现完整的缺省安全控制机制,但是其框架为未来的安全控制机制提供了扩充点。

¨       用户认证。jBPM认为其工作流引擎一定会运行于特定容器,例如WebApp,EJB,SWING等,所以它认为引擎的运行环境必须实现用户认证功能,而jBPM引擎只需获取认证的结果(即通过认证的actorId)即可。jBPM通过接口Authenticator中的getAuthenticatedActorId()函数获取通过认证的actorId。二次开发人员可以在配置文件中指定自定义的Authenticator接口的实现类。

¨       授权控制。jBPM引擎通过接口Authorizer中的checkPermission(Permission permission, ProcessDefinition processDefinition, Token token)判别用户是否具有相关操作的权限。jBPM3.0定义了6种操作权限:创建流程实例权限(CreateProcessInstancePermission),部署流程实例权限(DeployProcessPermission),任务分派权限(TaskAssignPermission)、结束任务权限(EndTaskPermission)、查看任务参数权限(ViewTaskParametersPermission)、提交任务参数权限(SubmitTaskParametersPermission)。类似于前述的用户认证扩充点,二次开发人员可以在配置文件中指定自定义的Authorizer接口的实现类,从而实现符合特定用户需求的授权控制机制。

分享到:
评论
1 楼 123456 2006-12-26  

相关推荐

    软件工程知识点

    通过系统的外部事件、内部状态为基本元素来描绘系统的工作流程,这种建模方式比较适合于描述一些依赖于外部事件驱动的实时系统。 5.需求有效性验证 需求有效性验证是指对已经产生的需求结论所要进行的检查与评价。...

    软件工程-理论与实践(许家珆)习题答案

    ● 运行维护(扩充功能、纠错等)。 习题二答案 一、 选择题 1. 需求分析的主要目的是(B C)。 A) 系统开发的具体方案 B) 进一步确定用户的需求 C) 解决系统是“做什么的问题” D) 解决系统是“如何做的问题...

    2011年6月面向对象分析与设计试题B卷.doc附有详答案

    对于一个设计并实现好的类,如果需要功能上的扩充,一般来说应该通过添加新类实现,而不是修改原类的代码。这种原则叫______。 A. 封装原则 B. 开放/封闭原则 C. 最小惊讶原则 D. 单一功能原则 7. 一个类的______...

    PowerDesigner做的E-R实例的

    CDM是一组严格定义的模型元素的集合,这些模型元素精确地描述了系统的 静态特性、动态特性以及完整性约束条件等,其中包括了数据结构、数据操作和完整性约束三部分。 1)数据结构表达为实体和属性; 2)数据操作表达...

    《软件工程导论》张海潘_第五版_清华_课后答案

    12.2.2 提高可扩充性297 12.2.3 提高健壮性297 12.3 测试策略298 12.3.1 面向对象的单元测试298 12.3.2 面向对象的集成测试299 12.3.3 面向对象的确认测试299 12.4 设计测试用例299 12.4.1 测试类的方法300 12.4.2 ...

    软件工程判断题.doc

    1、( X )对于软件项目,投资回收期越长,越快... 面向对象建模得到的模型包含系统的3个要素,即静态结构、交互次序和数据变换。( ) 9. 软件重用是提高软件开发生产率和目标系统质量的重要途径。 ( ) 10. 判定覆盖

    面向对象技术与UML课件及源代码-by 南邮-陈杨

    15.2用Rational Rose进行UML建模 15.2.1什么是Rational Rose 15.2.2安装Rational Rose 15.2.3如何使用Rational Rose 15.2.4UML图的种类 15.3小结 第16章用例图 16.1认识用例图 16.1.1为什么需要用例图 ...

    测试笔记(从零开始)

    ★UML统一建模语言(Unified Modeling Language) 86 第十一章 配置管理 88 1.什么是配置管理 88 2.配置管理流程 88 3.SVN实战 88 配置管理工具SVN操作过程手册 90 一、 如何创建“project”项目版本库 90 二、 如何...

    数据库系统概论部分答案.doc

    ( 2 )数据的共享性高,冗余度低,易扩充数据库的数据不再面向某个应用而是面向整个系 统,因此可以被多个用户、多个应用以多种不同的语言共享使用。 ( 3 )数据独立性高数据独立性包括数据的物理独立性和数据的...

    数据库系统概论(第四版)萨师煊编--习题答案

    这些概念精确描述了系统的静态特性、动态特性和完整性约束条件。因此数据模型通常由数据结构、数据操作和完整性约束三部分组成。 8 .试述概念模型的作用。 答:概念模型实际上是现实世界到机器世界的一个中间层次。...

    advisor2002软件

    用户可以在现有模型的基础上根据需要对一些模块进行修改,然后重新组装需要的汽车模型,这样会大大节省建模时间,提高建模效率。  (2)仿真模型和源代码全部开放。ADVISOR2002的仿真模型和源代码在全球范围内完全公开,...

    powerdesign教程

    CDM是一组严格定义的模型元素的集合,这些模型元素精确地描述了系统的静态特性、动态特性以及完整性约束条件等,其中包括了数据结构、数据操作和完整性约束三部分。 1)数据结构表达为实体和属性; 2)数据操作...

    数据库系统概论第四版答案

    的静态特性、动态特性和完整性约束条件。因此数据模型通常由数据结构、数据操作和完整 性约束三部分组成。 ( l )数据结构:是所研究的对象类型的集合,是对系统静态特性的描述。 ( 2 )数据操作:是指对数据库中...

    PHP和MySQL Web开发第4版pdf以及源码

    8.2.1 考虑要建模的实际对象 8.2.2 避免保存冗余数据 8.2.3 使用原子列值 8.2.4 选择有意义的键 8.2.5 考虑需要询问数据库的问题 8.2.6 避免多个空属性的设计 8.2.7 表格类型的总结 8.3 Web数据库架构 8.4 ...

    PHP和MySQL Web开发第4版

    8.2.1 考虑要建模的实际对象 8.2.2 避免保存冗余数据 8.2.3 使用原子列值 8.2.4 选择有意义的键 8.2.5 考虑需要询问数据库的问题 8.2.6 避免多个空属性的设计 8.2.7 表格类型的总结 8.3 Web数据库架构 8.4 ...

    PHP和MySQL WEB开发(第4版)

    8.2.1 考虑要建模的实际对象 8.2.2 避免保存冗余数据 8.2.3 使用原子列值 8.2.4 选择有意义的键 8.2.5 考虑需要询问数据库的问题 8.2.6 避免多个空属性的设计 8.2.7 表格类型的总结 8.3 Web数据库架构 8.4 进一步...

    计算机控制课程设计---PID控制算法的MATLAB仿真研究.docx

    PID参数的选定对控制系统能否得到好的控制效果是至关重要的,PID参数的整定方法有很多种,可采用理论整定法(如ZN法)或者实验确定法(比如扩充临界比例度法、试凑法等),也可采用如模糊自适应参数整定、遗传算法...

Global site tag (gtag.js) - Google Analytics