posts - 26,  comments - 7,  trackbacks - 0
 
     摘要: 是一张Ultimus为一个简单变更定单流程开发的地图。一个客户申请变更一个产品或服务将启动本流程。在收到申请以后,工程经理能拒绝申请,需要一个EMAIL提醒发送给客户,或申请同时输入到3个其他团队(软件,电子,机械)。当所有需求团队反馈后,流程使用网络服务申请一个包括变更所有的输入和时间和成本的预算包。这些信息将反馈给工程经理做最终检查和调整。此时,工程经理又一次能够拒绝申请(如果成本或时间预估过高)。否则,信息将提交给销售部门添加任何补充信息。然后流程将自动生成一个报价并且和提醒一起发送给客户。  阅读全文
posted @ 2007-09-23 19:25 jbpm 阅读(516) | 评论 (0)编辑 收藏
     摘要: JBoss jBPM is a flexible, extensible workflow management system. JBoss jBPM has an intuitive process language to express business processes graphically in terms of tasks, wait states for asynchronous communication, timers, automated actions,... To bind these operations together, JBoss jBPM has the most powerful and extensible control flow mechanism.

  阅读全文
posted @ 2007-09-23 19:18 jbpm 阅读(737) | 评论 (0)编辑 收藏
     摘要: 在下面的例子里,我们将向您展示如何能给用户分配任务。因为在jBPM工作流

引擎和组织机构模型之间是分离的,对计算参与者的表达语言将总是被限制的。

因此,你必须指定一个任务处理的实现,包括计算任务参与者
  阅读全文
posted @ 2007-09-23 16:29 jbpm 阅读(1175) | 评论 (0)编辑 收藏
     摘要: 城市政府宽带网络软件平台连接一个城市的市政府、党的机关、人大、政法四大类几十甚至上百个机关。政府部门中有大量的工作是需要部门内、部门之间的多部门、多工作岗位、多工作人员协同工作来完成的。而且其工作呈工作流状态和事务性状态(既工作流程的完整性)。
  阅读全文
posted @ 2007-09-23 15:56 jbpm 阅读(677) | 评论 (0)编辑 收藏
     摘要: 工作流一直是实施BPM的重要环节,以往的开源与闭源的划分已经不适合如今的工作流局势,开源已经渗透到了各个领域,如今的工作流已是三分天下的大局  阅读全文
posted @ 2007-09-23 11:06 jbpm 阅读(3480) | 评论 (1)编辑 收藏
     摘要: 业务日历是关于业务时间的,并且被用于为任务和定时器计算预期的时间。 业务日历能够通过对一个期限和日期进行增加来计算日期。我们先看看业务日历的语法:

xml 代码

[business]


  阅读全文
posted @ 2007-09-19 17:40 jbpm 阅读(907) | 评论 (1)编辑 收藏
     摘要: JBPM的流程执行模型以下面几个模型为原型:
Node 节点,Action 动作,Transition 流向,Excution 执行。  阅读全文
posted @ 2007-09-19 17:08 jbpm 阅读(679) | 评论 (1)编辑 收藏

作者: JeffreyHsu


尽管jbpm非常强大,是目前最适合商业化的开源工作流引擎,可以开发出复杂的流程,但是特别遗憾的是并不支持并发子流程(multiple-subprocess)
有一次我需要做一个复杂的流程,主流程里要求同时启动多个并发执行的子流程,并且子流程的数目和启动的时间都不确定,当所有子流程都结束以后,主流程才继续执行。我们知道jbpm里有子流程的设定,有专门的节点ProcessState来处理,但是后来发现无论如何也实现不了多子流程并发执行,后来看其源码知道因为subprocess是作为ProcessState的一个属性,也就是说ProcessState只能包含一个subprocess的定义,并且最重要的是processInstance.getRootToken()和子流程相关的只有createSubProcessInstance, getSubProcessInstance, setSubProcessInstance三个方法,这意味着主流程的rootToken只能设置一个子流程,jbpm并不直接支持多子流程。
那么我们就必须用一个变通的方法来实现,“并发”很自然的让我们想到了fork,但是这里的fork不能搭配join来使用,具体原因,将在后面讨论。
下面先给出流程图:

state节点用来启动子流程(实际应用可以换成Task-Node),state进入fork后同时进入两个分支,一条去启动子流程,另一条回到自己,这样表面看来state没有动,而同时你又可以启动第2个,第3个……子流程,需要注意的是第2条子流程和第1个子流程并不处于同一级上,而比第一个子流程低一级,具体请看后面一张图就明白了,分解后的:

从图中我们可以看到后一个子流程的整棵树是前一个子流程的兄弟,但是在业务级上是并发的效果,已经实现我们前面的需求。

现在来说说为什么不能用join而直接用end,因为会产生一个问题,state3和sub process 2都到达了join以后,state2下面的fork就结束了,就会立刻越过join到达end,而sub process 1即使执行完毕到达了join却仍然在傻傻等待着他的兄弟分支也到达join(而实际上它已经自跑到end去了)一同结束,这样sub process 1就会永远停在join动弹不得,业务无法进行。

这是我的一个解决方案,但还有一个问题,虽然全部的子流程都能结束,主流程也能结束,但因为没有join,主流程的rootToken仍然停留在fork节点上。目前我尚不知如何解决,希望各位大家能提出其他更好的解决办法。
初学jbpm,水平有限,有不当之处还请高手斧正

最后附上demo代码供参考:

代码
  1.   
  2. import static org.junit.Assert.*;   
  3.   
  4. import org.jbpm.graph.def.ProcessDefinition;   
  5. import org.jbpm.graph.exe.ProcessInstance;   
  6. import org.jbpm.graph.exe.Token;   
  7. import org.jbpm.graph.node.ProcessState;   
  8. import org.junit.Before;   
  9. import org.junit.Test;   
  10.   
  11. public class MultiProcessTest {   
  12.     private ProcessDefinition superProcessDefinition;   
  13.   
  14.     private ProcessDefinition subProcessDefinition;   
  15.   
  16.     @Before   
  17.     public void setUp() throws Exception {   
  18.         superProcessDefinition = ProcessDefinition.parseXmlString(   
  19.                 "<process-definition name='super'>" +                
  20.                 "  <start-state name='start'>" +   
  21.                 "    <transition to='state' />" +   
  22.                 "  start-state>" +   
  23.                 "  <state name='state'>" +   
  24.                 "    <transition name='create sub' to='fork' />" +   
  25.                 "    <transition name='end' to='end' />" +   
  26.                 "  state>" +   
  27.                 "  <fork name='fork'>" +   
  28.                 "    <transition name='back' to='state' />" +   
  29.                 "    <transition name='go to sub' to='sub process' />" +   
  30.                 "  fork>" +   
  31.                 "  <process-state name='sub process'>" +   
  32.                 "    <sub-process name='sub' />" +   
  33.                 "    <transition to='end' />" +   
  34.                 "  process-state>" +   
  35.                 "  <end-state name='end' />" +   
  36.                 "process-definition>");   
  37.            
  38.         subProcessDefinition = ProcessDefinition.parseXmlString(   
  39.                 "<process-definition name='sub'>" +                          
  40.                 "  <start-state name='start'>"  +   
  41.                 "    <transition to='wait' />" +   
  42.                 "  start-state>" +                         
  43.                 "  <state name='wait'>" +   
  44.                 "    <transition to='end' />" +   
  45.                 "  state>" +              
  46.                 "  <end-state name='end' />" +   
  47.                 "process-definition>");   
  48.         ProcessState processState = (ProcessState) superProcessDefinition   
  49.                 .getNode("sub process");   
  50.         processState.setSubProcessDefinition(subProcessDefinition);   
  51.     }   
  52.   
  53.     @Test   
  54.     public void testMultiProcesses() {   
  55.         ProcessInstance pi = new ProcessInstance(superProcessDefinition);   
  56.   
  57.         // 启动一个主流程   
  58.         pi.signal();   
  59.         assertEquals("state", pi.getRootToken().getNode().getName());   
  60.   
  61.         // 进入分支,此处将进入子流程   
  62.         pi.signal("create sub");   
  63.         // 主流程token将停留在fork节点上   
  64.         assertEquals("fork", pi.getRootToken().getNode().getName());   
  65.   
  66.         // fork分为两支,其中一支的节点停留在ProcessState上   
  67.         Token subProcessToken1 = pi.getRootToken().getChild("go to sub");   
  68.         ProcessInstance subPi1 = subProcessToken1.getSubProcessInstance();   
  69.         assertEquals("wait", subPi1.getRootToken().getNode().getName());   
  70.   
  71.         // 另一支返回了state节点,实际上并没有返回,这个state节点不同于先前的state,它们并不在同一个path中   
  72.         Token stateToken1 = pi.getRootToken().getChild("back");   
  73.         assertEquals("state", stateToken1.getNode().getName());   
  74.            
  75.         // 再次进入fork,启动第二个子流程   
  76.         stateToken1.signal("create sub");   
  77.         ProcessInstance subPi2 = stateToken1.getChild("go to sub")   
  78.                 .getSubProcessInstance();   
  79.         // 虽然都是子流程,但它们并不相同,在逻辑上是属于并发的无关系的子流程   
  80.         assertFalse(subPi1.equals(subPi2));   
  81.         // 结束第二个子流程   
  82.         subPi2.signal();   
  83.         assertTrue(subPi2.hasEnded());   
  84.         assertFalse(pi.hasEnded());   
  85.   
  86.         // 结束第一个子流程,但主流程仍未结束   
  87.         subPi1.signal();   
  88.         assertTrue(subPi1.hasEnded());   
  89.         assertFalse(pi.hasEnded());   
  90.            
  91.         // 结束第二个子流程中的state,第一子流程的back分支结束,从而主流程也结束   
  92.         Token stateToken2 = stateToken1.getChild("back");   
  93.         assertEquals("state", stateToken2.getNode().getName());   
  94.         assertFalse(stateToken1.hasEnded());   
  95.         assertFalse(pi.hasEnded());   
  96.         stateToken2.signal("end");   
  97.            
  98.         assertTrue(stateToken1.hasEnded());   
  99.         assertTrue(subPi1.hasEnded());   
  100.         assertTrue(pi.getRootToken().getChild("back").hasEnded());   
  101.         assertTrue(pi.getRootToken().getChild("go to sub").hasEnded());   
  102.         // 主流程结束了   
  103.         assertTrue(pi.hasEnded());   
  104.         // 虽然主流程已经结束了,但是因为子流程没有join,所以其rootToken仍然停留在fork上   
  105.         assertEquals("fork", pi.getRootToken().getNode().getName());   
  106.         // 第二个子流程到达的end和主流程中的end并不是同一个节点   
  107.         assertTrue(!pi.getRootToken().getNode().equals(stateToken2.getNode()));   
  108.     }   
  109. }   
posted @ 2007-09-11 17:48 jbpm 阅读(1020) | 评论 (0)编辑 收藏

对于BPM产品目前尚无公认的分类标准,如果沿用以前对工作流的分类,则可以分为生产型(又可以再细分为自治式和嵌入式两种)、管理型、协同型和专门型四大类。但这样一来,市场上主流的通用BPM产品大都会被划分到生产型,难以分辨出它们之间的本质差异,因此我们需要一种新的分类方法。

笔者建议根据产品内在拓扑结构的差异进行分类,将BPM产品划分为面向引擎型、面向业务型、面向消费者型、以及对等型四大类。而一些功能较强的产品能同时支持多种拓扑结构。

面向引擎型:匹马单枪

 

见自性清静,自修自作法身,自行佛行,自成佛道。

企业内的工作流系统广泛采用了这种集中控制式拓扑结构,客户端连接到负责接受请求的中央引擎服务器。当流程上有客户端完成了任务,它会将结果发送给服务器,服务器接收齐工作数据,就开始组织下一个任务项。大多数BPM产品都支持这种最原始的拓扑形式。

这种方式的长处在于其简单性,它使得管理和控制都很容易,而且它对客户端的要求不高,大多数负载和责任都从客户端转移到了引擎服务器。

这种模式的缺点在于成败悬于一线,整个系统完全依赖于一个全能服务器。该服务器必须功能非常强大,并且必须能够承受巨大的压力。反过来说,这又限制了系统的可扩展性。

采取这种结构的BPM系统一般非常重视用于自动型活动的企业应用集成(EAI/A2A)和用于人工型活动的人机交互界面。有集成服务器背景的厂商往往侧重于应用集成和直通处理(系统到系统的交易),Fuego、SeeBeyond、Vitria和WebMethods属于此类。有着工作流背景的厂商则往往对需要大量人工干预的应用提供更完善的功能,FileNet、Identitech、Plexus和Staffware就属于此类,这类厂商对客户界面和流程设计工具进行了优化,可以支持各种流程的人工干预。新玩家HandySoft和Intalio则介于两者之间。

归根到底,应用集成能力的高低是区别诸解决方案的一个主要因素。如果你所考虑的应用需要相当高的集成水平,尤其是与多个系统的集成,集成服务器厂商提供的产品显然具有优势,但选择来自集成服务器厂商的BPM解决方案可能意味着需要采用它们的平台作为集成标准。 

面向业务型:天龙八部

尔时世尊,天龙八部,四众围绕,王及大众,五体投地,为佛作礼。

许多业务流程管理系统是通过可靠消息通信实现的。消息队列技术允许系统异步和分布运行,支持跨异构网络甚至是暂时离线的系统间通信。一个客户端为了与属于另一引擎服务器的客户端进行协作,可以将消息发送到自己所属引擎的队列中,引擎会完成剩下的实际消息转发和传递工作,并把最终的返回消息也放在发起者的接收队列中,供该客户端随时提取。

这是一种多引擎的拓扑结构,可以解决许多单纯的客户/服务器拓扑存在的问题,但它仍然采用集中控制的方法,因为一个引擎通常服务于一大堆客户端,任务只是在相互连接的引擎之间分割和协作。

这一解决方案的优点在于可扩展性好,当负荷太重时可以通过添加引擎来缓解。这一方案的容错性也更强,当某台引擎出现故障时,其他引擎可以接管其原来的工作。另外,它可以支持更有效的通信,因为引擎可以与客户端离得更近。

这一方式的缺点在于引擎必须设计得很精巧,它必须既能处理客户端请求,又能与其他引擎协调。它还有一点与面向引擎的拓扑类似,即仍然将负荷和责任从客户端改扛在了引擎服务器肩上,只不过不光是一个引擎罢了。另外,同时维护多个引擎也需要更多的管理开销。

支持这种拓扑结构的BPM产品一般都擅长于跨企业的应用集成和协调(B2Bi)。许多BPM应用,如支持多账户应用处理的金融服务,往往基于应用服务器环境。例如IBM的MQSeries Workflow的产品;BEA的Process Integration。Fujitsu、Intalio、Quovadx、Savvion、Versata等厂商的产品不仅能够与IBM或BEA的应用服务器兼容,还各自提供常见BPM组件的定制开发环境。对侧重于开发流程之间的应用到应用通信并以微软产品为中心的环境而言,微软的BizTalk则非常适合。 

面向消费者型:心心相印

昔时圣人互出,乃曰传灯,尔后贤者差肩,乃曰继祖,是以心心相传,法法相印。

近些年,发布/订阅(Pub/Sub)拓扑结构成为构建、实现和集成复杂流程的抢手货,被认为是满足动态需求的一种简单而有效的手段。很多强大、灵活的BPM系统就建立在这种模式之上,例如,TIBCO便一直是使用Pub/Sub方式构建松散耦合的分布式应用的先驱。在动态演化的系统中应用Pub/Sub模式实现业务流程已被证明相当有效。

Pub/Sub拓扑结构的一大长处是无需复杂的集中式服务器和路由机制,因为消息直接由来源发往目的地。该模式支持高度分散的业务流程间的协作。

它的弱点在于可伸缩性非常有限。每个发布者只能包含有限数目的订阅者,否则会处理不过来。此外,在没有集中控制的情况下发现发布者和订阅者也很困难,因为当你找不到对方的时候,无处去询问和诉说。最后,它还存在生命期的依赖性。

像抵押贷款、索赔甚至支付处理等BPM应用还需要与流程管理功能紧密相关的图像处理及内容管理功能,为此,Plexus能把大容量文档图像处理和高度可伸缩的流程管理紧密结合在一起;而Identitech等厂商捆绑了基于XML的电子表格和本地记录管理功能;FileNet的新款Panangon平台特别提供了企业内容管理(ECM)功能,能同时支持文档图像处理、Web内容管理及可靠的集成特性和选项。尽管Handysoft并不提供本地网站门户,也不提供内容管理功能,但却提供了与Documentum、Hummingbird、Plumtree和微软的SharePoint相集成的功能。 

对等型:打成一片

长短好恶,打成一片,一一拈来,更无异见。

P2P(Peer-to-Peer)计算是Internet发展的最新产物,在Internet之上已经有了数不胜数的资源和对等端,它们有潜力克服传统客户/服务器系统的大多数限制,如可伸缩性、内容可用性、计算能力等,当然,这也需要比单纯将消息转发给所有对等端更有效的群组通信机制,因为这些对等端可能是在网格计算背景下分布在全球的用户和厂商。

P2P模式是完全分散的,每个结点都被认为是一个对等端,它会连接到一个或者几个其他的端口。如果不使用过滤机制的话,那么每个对等端都会把会话转发给相邻的所有对等端,形成会话“洪水”。所以在实际应用中,应该使用分割、投影、过滤等策略,只将与该对等端相关的流程部署在它上面,该对等端只接受从其流程上游发来的消息,再将经过处理的结果仅发送给它的下游对等端。

P2P拓扑的好处在于无需集中式服务器,允许任意数量的网络结点,因为工作负荷可以在各个对等端之间平衡与共享。

它的坏处在于有时候延迟现象严重,因为流程有时需要在多个对等端之间协同。另外,部分低效的对等端必然影响整体的性能。

由中科院软件所和中科国际共同开发的A2E-DI就支持完全分散的数据提取、转换、传输和加载的全过程操作。HandySoft开发的BizFlow则提供了一系列由可伸缩业务流程引擎驱动的基于Web的协作工具,其可伸缩性决定了它亦能应用于对等环境。 

在P2P结构的基础之上还可能出现P2P Cluster(P2P集群)拓扑结构。它可以通过分而治之的策略解决单纯P2P模式中消息通信存在的某些问题。网络被划分为一系列集群,每个集群都了解其管辖的对等端。在每个集群中,牺牲一台服务器用于充当协调者的角色,它知道哪个对等端订阅了远程的某个发布者,也知道远程的某个订阅者订阅了集群内部的哪个对等端,这样就不必把时间花在那些无关的集群内部了。其优缺点与P2P拓扑大体相似。

posted @ 2007-09-11 17:44 jbpm 阅读(770) | 评论 (0)编辑 收藏
     摘要:
理论介绍(一些定义)
  业务流程是一个组织及其合作伙伴的人员及系统所完成的工作的一种正式表达, 它旨在给内部或外部客户提供产品或服务。业务流程最简单的表达形式就是一组活动,它们表示流程的不同步骤,通过一些转换连接在一起。活动可能需要人为干预,也可能是全自动的。对于需要人为交互的活动,可以在流程中定义一个角色,标识允许谁在这里与流程交互。流程起到定义的作用,而流程中的实例就是完成整个流程的实际项目,从一个活动转换到另一个活动。实例总是开始于流程的Begin活动,而结束于流程的End活动。实例的路径完全取决于实例的数据以及外部环境。

   转换是活动之间的直接连接, 许多的转换进出一个活动.。一旦某个实例完成了一项活动件,外发转换将被评估, 其中之一被选中,以使实例转向下一活动。条件转换包含一个布尔表达式,该表达式将被计算,要使实例继续沿流程前进,结果必须为true。有些转换是基于时间的,这就意味着如果到了预期时间,实例还在那里,这些转换将会触发到目标活动的自动路由。流程也可以有状态:可为流程定义属性,接受每个实例的一个值,这能帮助您保持实例状态,以  阅读全文
posted @ 2007-09-11 17:40 jbpm 阅读(529) | 评论 (0)编辑 收藏
仅列出标题
共3页: 上一页 1 2 3 下一页