JBPM使用方法、过程记录

一、How to call Web Service Using JBPM 5, designer

 

https://204.12.228.236/browse.php?u=ObFK10b3HDFCQUNPNMI9E9mVwaCq3FwkaoL99tqkn%2Bip0N%2B93A%3D%3D&b=15

 
 
 
 
 
 

wtorek, 31 lipca 2012

Service Task with web service implementation

 
Invocation of web services as part of business process is common and most likely because of that default implementation of Service Task in BPMN2 specification is web service. Recently (5.4) jBPM5 has gotten support for such activity.

jBPM5 web service support is based on Apache CXF dynamic client. It provides dedicated Service Task handler (that implements WorkItemHandler interface).

org.jbpm.process.workitem.bpmn2.ServiceTaskHandler

Worth noting is that this handler is capable of invoking both web service end points and simple Java based services as with previous ServiceTask handler (org.jbpm.bpmn2.handler.SendTaskHandler) based on the implementation attribute of service task node

web service implementation
 <bpmn2:serviceTask id="ServiceTask_1" name="Service Task" implementation="##WebService" operationRef="_2_ServiceOperation"> </bpmn2:serviceTask>
 
java implementation
<bpmn2:serviceTask id="_2" name="Hello" operationRef="_2_ServiceOperation" implementation="Other" >
</bpmn2:serviceTask>

ServiceTaskHandler can invoke web service operations in three modes:
  • synchronous (sends request and waits for response before continuing)
  • asynchronous (sends request and uses callback to get response)
  • one way (sends request and does not wait for any response)
This configuration is done on service node level as parameter (data input) so it allows to have different configuration for service nodes and to be handled by the same service task handler.

Let's try to go through this implementation with example. We are going to build a process that will get weather forecast for given zip codes in US. So process will look like this:

This process will:
  • ask for couple of zip codes on the first human task (task is assigned to john)
  • next transform result of the user task to a collection that will be used as input for multi instance service task
  • then based on the input collection process will create several instances of service task to query the weather forecast service
  • once all service task instances are completed it will log result to the console
  • and create another human task to show the weather forecast for selected zip codes (task is assigned to john)
When process instance is started it will prompt the user to select in what mode service task instances should be executed: async or sync. With this particular example changing the mode from async to sync will not make big difference as the service we use is rather fast but with services that takes some time to respond difference will be noticeable.

But how does it know it is web service and even more important what web service it is? This is configured as part of process definition using few dedicated constructs:

1. first of all we need to tell the engine where is our WSDL so it can be read and operations from it can be invoked - this is done with BPMN2 import:
 <import importType="/wsdl/" location="/WeatherWS/Weather.asmx?WSDL" namespace="/WeatherWS/"/>

2. next message, interface and operations must be defined:
<itemDefinition id="_2-2-4_InMessageType" />
<message id="_2-2-4_InMessage" itemRef="_2-2-4_InMessageType" />
 
<interface id="_2-2-4_ServiceInterface" name="" implementationRef="Weather">
 
  <operation id="_2-2-4_ServiceOperation"   
       implementationRef="GetCityWeatherByZIP" name="hello">
      <inMessageRef>_2-2-4_InMessage</inMessageRef>
  </operation>
</interface>

Important: make sure that implementationRef for both interface and operations point to valid service and operation in WSDL.

3. Next use defined operation in your service task and set implementation as web service (or don't specify that attribute at all so default will be taken):
<serviceTask id="_2" name="Service Task" operationRef="_2-2-4_ServiceOperation" implementation="##WebService" >
........
</serviceTask>

NOTE: Unfortunately tooling does not support this yet so the bpmn2 file needs to be edited by hand. Soon tooling will provide this as well.

Yet another important thing here is that if you plan to use request or response object of the service in your process as variables make sure that all of them implement java.io.Serializable interface so they can be properly persisted. One way to do this (used in the example) is to provide additional configuration to tell JAXB to add Serializable while generating classes from WSDL and generate classes as part of the build:

Complete source code can be found here. It comes with test cases that uses this example as well as local service that can be used to illustrate difference between sync and async modes.

This example can be executed on jbpm-console when build from master, as it already has this service task handler configured. Here is a short guide on how to do it:
1. clone jbpm master and build it with mvn clean install -DskipTests -Dfull (alternatively download latest build from build server)
2. clone jbpm-examples and build jbpm-ws-example project with mvn clean install
3. copy result of build in point 2 (jbpm-ws-sample-1.0-SNAPSHOT.jar) into jbpm-installer/dependencies
4. copy WeatherWSServiceProcess.bpmn2 into jbpm-installer/sample/evaluation/src/main/resource
5. copy all archives from jbpm-distribution into jbpm-installer/lib
6. use jbpm-installer to install jbpm into jboss AS7 - ant install.demo.noeclipse
7. start demo server - ant start.demo.noeclipse

then go to jbpm-console and run the process with name WeatherWSServiceProcess.

Have fun!
 
二、、http://duncandoyle.blogspot.com/2012/10/jbpm5-calling-webservices-from-your.html
 
 
 

Wednesday, October 3, 2012

jBPM5: Calling WebServices from your business processes

 
In one of my previous blog posts on Business Process Management (BPM) I outlined the important role that BPM plays in a Service Oriented Architecture (SOA), and how a well defined SOA is a prerequisite for successful Cloud implementations.

The jBPM5 engine, part of the JBoss BRMS platform, is a highly flexible and versatile BPM engine based on open standards like BPMN2 and WS-HumanTask. This article will show how the jBPM5 platform can integrate with WebServices by utlizing the JAX-WS API.

The jBPM5 platform provides a simple, but very powerful, extension mechanism to add domain specific service nodes and their implementations to a business process. This allows us to plug our own, custom, logic into the business process runtime system. The extension mechanism is based on the jBPM5 WorkItemHandler API. The WorkItemHandler interface declares 2 methods which need to be implemented by the domain specific WorkItemHandler implementation:
  • public void executeWorkItem(WorkItem workItem, WorkItemManager workItemManager): Is called by the process engine when a service node is executed.
  • public void abortWorkItem(WorkItem workItem, WorkItemManager workItemManager): Can be implemented to signal the workitem to be aborted.
In this example we will utilize this WorkItemHandler API to implement our own custom service nodes which use the JAX-WS API to call external WebServices. This article will not cover how to define and use custom nodes in your business process editor (i.e. the JBoss BRMS BPMN2 Web editor, the JBoss Tools Eclipse BPMN2 editor, etc.). For inforrmation on how to define and use custom process nodes in your BPMN2 process, please consult: 
 
 
The source codes of the examples in this blogpost are available in my Github repository. The code also contains the WorktemDefinitions file which contains the definitions of the 'PaymentService' and 'JAX-WS-Dispatcher-Service' workitems. These definitions can, for example, be used in the JBoss BRMS system to add the custom service nodes to the BPMN2 web-editor palet.

The Process
The process used in this example is a simple process which calls a PaymentService to check whether a payment-type (e.g. VISA, MasterCard, etc.) is valid and which, if the payment-type is valid, calls an OrderService to place a specific order. The process contains additional ScriptTask nodes which provide debug output which is written to System.out.



 


The BPMN2 process definition of this specific process can be found here.

In this example, the process runs in a simple Java client application (the 'Simple_jBPM_Process' project), which creates the jBPM5 KnowledgeBase, containing the BPMN2 process definition, creates the StatefulKnowledgeSession, registers our custom JAX-WS WorkItemHandlers and starts the process instance. See the 'org.jboss.ddoyle.howtojboss.jbpm5webservices.Main' class for the example code.


WebServices
This example contains a WAR project (the 'SimpleWebServicesWeb' project) that can be directly deployed on a JBoss BRMS 5.3 platform (or EAP 5.1.x with the JBossWS-CXF WebService stack) and which contains both the implementation of the 'PaymentService' and the 'OrderService'. The WSDL files of these services can either be obtained from the project's 'src/main/resources' folder or, at runtime, via the JBossWS console at http://localhost:8080/jbossws/services.


JAX-WS
JAX-WS provides two client APIs which can be used to execute WebService calls, the Dispatch API and the Proxy API.

The Proxy API provides a Java proxy object representing the WebService endpoint to be called. The JAXB2 library is utilized to marshall and unmarshall Java objects to and from XML. This client mode can be used when one wants to operate on Java objects.

The Dispatch API is a dynamic API in which the client code which uses this API is responsible for the creation of the XML payload or even the entire SOAP message that will be sent to the WebService endpoint. This API can be used when one wants to operate on the XML message level.

In this example we will use both client modes. We will call the 'PaymentService' using a JAX-WS Proxy client and the 'OrderService' via a JAX-WS Dispatch client.

JAX-WS Proxy Client: PaymentServiceJaxWsProxyWorkItemHandler
JBoss BRMS (and any other JBoss platform for that matter) provides a utility that is able to generate the JAX-WS annotated Java code from a given WSDL file. This utility, called 'wsconsume', is located in the 'jboss-as/bin' directory of your JBoss BRMS  (or EAP) platform. The utility can be used as follows: ./wsconsume.sh -kn {WSDL-file}. This will generate the JAX-WS annotated client and server code which can be used to both implement the webservice provider and a webservice consumer. Both the 'Simple_jBPM_Process' (consumer) and the 'SimpleWebServicesWeb' (provider) contain the JAX-WS code generated from the 'PaymentService' and 'OrderService' WSDL files.

The 'PaymentServiceJaxWsProxyWorkItemHandler' uses the generated JAX-WS Proxy client to call the PaymentService. As can be seen from the code, the WorkItemHandler is, because it directly uses the generated PaymentService proxy classes, tightly coupled to the PaymentService. I.e. This WorkItemHandler implementation is specifically created to call a PaymentService WebService. In general, a WorkItemHandler which uses a JAX-WS Proxy client can only be used to call that specific service. This implies that one has to define and create a WorkItemHandler per service, and thus a domain specific process node per service. 

The jBPM5 WorkItemHandler API provides the ability to pass parameters from the jBPM5 process instance to the WorkItemHandler via a parameter Map. In the jBPM5 BPMN2 process definition, a mapping needs to be defined on the 'PaymentService' node which maps the process instance data onto the parameters required by the WorkItemHandler. 

In the case of the 'PaymentServiceJaxWsProxyWorkItemHandler', 2 parameters can (must) be passed to the WorkItemHandler: 
  • input: a String object containing the input value for the PaymentService.
  • endpointAddress: the URL of the location of the PaymentService. 
The service response data is returned to the process instance via the 'paymentServiceResponse' parameter in the returned parameter Map. This response can then be mapped back onto a process instance variable.
 
The 'endpointAddress' parameter allows us to configure the actual location of the PaymentService endpoint. This makes it possible to use the same WorkItemHandler to point to different endpoint locations of the PaymentService, which is specifically useful when one has to deploy the process in multiple environments (i.e. Development, Test, Production).


JAX-WS Dispatch Client: JaxWsDispatcherWorkItemHandler
The 'JaxWsDispatcherWorkItemHandler' uses the JAX-WS Dispatch API to, in this process definition, call the OrderService. The JAX-WS Dispatch API allows us to work on XML structures directly. The responsibility of providing the correct XML SOAP-message payload (or the entire SOAP-message itself, depending on whether the Dispatch client is used in PAYLOAD or MESSAGE mode) lies now with the code that uses the Dispatch API.

In this example we've tried to make this WorkItemHandler as generic as possible, so it can be used to call any webservice and can be reused in various projects. This is done by parameterizing the name and location of the service to be called, as well as by providing a simple 'injection' mechanism to inject the RequestMapper and ResponseMapper objects responsible for marshalling and unmarshalling the XML payload from and to jBPM5 WorkItemHandler parameters (which are passed via the WorkItemHandler parameter Map).

The WorkItemHandler requires the following parameters to be passed by the process instance:
  • serviceNamespace: the namespace of the service to be called. I.e. The namespace defined in the services' WSDL file.
  • serviceName: The name of the service as defined in the services' WSDL file.
  • portTypeNamespace: The namespace of the PortType.
  • portTypeName: The name of the PortType.
  • soapAction: The soapAction value of the service operation to be called.
  • endpointAddress: The URL of the service endpoint.
  • requestMapper: The name of the request-mapper which will be used to lookup a RequestMapper instance via the 'RequestMapperFactory'.
  • responseMapper: The name of the response-mapper which will be used to lookup a ResponseMapper instance via the 'ResponseMapperFactory'.
  • input: The input data for the WebService call.
The service response data is returned to the process instance via the 'response' parameter in the returned parameter Map.

These parameters make this WorkItemHandler very generic. One can call different services, inject specific RequestMappers and ResponseMappers, etc.  The picture below shows how the mapping of jBPM5 process instance data to WorkItemHandler parameters is configured in the JBoss BRMS BPMN2 web editor:



If required, the WorkItemHandler can be extended to support additional WS-* features like WS-Security, WS-Addressing, etc.


Running the example.
To run the example, first the project containing the OrderService and PaymentService implementations needs to be build using Maven. To do this, execute the command 'mvn clean install' in the 'SimpleWebServicesWeb' directory. This will build the WAR file and add it to your local Maven repository. Deploy this WAR file on a JBoss BRMS 5.3 platform (or any JBoss platform with a JBossWS-CXF WebServices stack) of which the HTTP connector is bound to 'localhost:8080'. The WSDL files of the WebServices can now be accessed at:

Next, build the 'Simple_jBPM_Process' client project by again executing 'mvn clean install' in the 'Simple_jBPM_Process' directory. This will produce a JAR file which contains all the jBPM5 and Drools dependencies required to run the process instance.

To run the client, simply execute the command 'java -jar Simple_jBPM_Process-0.0.1-SNAPSHOT.jar JBoss_T-Shirt VISA' from a terminal. If everything exectutes correctly, this will produce the following output:

Loading StatefulKnowledgeSession.
Starting Process Instance.
Payment type: VISA
PaymentService response: VALID
Payment approved!
Oct 4, 2012 12:39:43 AM org.jboss.ddoyle.howtojboss.jbpm5webservices.workitemhandlers.JaxWsDispatcherWorkItemHandler executeWorkItem
INFO: Calling Service: http://impl.orderservice.howtojboss.ddoyle.jboss.org/:SimpleOrderServiceService
Oct 4, 2012 12:39:43 AM org.jboss.ddoyle.howtojboss.jbpm5webservices.workitemhandlers.JaxWsDispatcherWorkItemHandler executeWorkItem
INFO: Received response from Service: http://impl.orderservice.howtojboss.ddoyle.jboss.org/:SimpleOrderServiceService
Order 'JBoss_T-Shirt' submitted successfully
Finished Process Instance with id: 1
 
If another payment-type then VISA is entered, the process will show the following output.

Loading StatefulKnowledgeSession.
Starting Process Instance.
Payment type: MasterCard
PaymentService response: INVALID
Payment not approved. Order cancelled.
Finished Process Instance with id: 1

Conclusion
jBPM5 is a highly versatile and flexible Business Process Management platform which can be easily extended, customized and integrated with a vast array of external systems. In this example we combined the JAX-WS API and the jBPM5 WorkItemHandler API to integrate WebServices with our business processes. The WorkItemHandler API is a simple, yet powerful, construct that can be used to integrate business processes with almost any (external) system, as long as that system provides a Java client API (or as long as a Java client can be written for it). This implies that we can use the same mechanism to, from our  business process, call RESTful services, send JMS messages to message queues (e.g. JBoss HornetQ), etc. As such, the jBPM5 platform can be easily integrated in almost any IT landscape.
1.JPDL的流程定义元素 1)第一层:GraphElement 这个容易理解,因为在画流程定义时,每个拖拉的对象都是一个graph的元素。GraphElement有四个属性: (1)processDefine 表示当前元素属于哪个流程定义 (2)events 表示可以接收哪些event (3)name 名字 (4)exceptionHandlers 异常处理类集合(List) 2)第二层:node、processDefinition、Transition、Task 它们都继承自GraphElement (1)processDefinition表示流程定义(implements NodeCollection),它有下面的属性:name、version、nodes、startState。nodes表示流程中所有的node,startState用于启动流程时找到首节点。 (2)Transition表示转移,它有三个属性:from(Node),to(Node),supportedEventTypes表示支持的event类型 (3)node表示节点,它有四个属性:leaving transitions、arriving transitions、action、superState。 (4)Task 定义任务 3)第三层:各种不同的node 它们都继承自node。 Decision、EndState、Fork、Join、Merge、Milestone、 InterleaveEnd、InterleaveStart、ProcessState、State。 2.jBPM的token jbpm中最重要的概念,应该是令牌(Token)和信令(Signal)。在整个流程实例运行过程中,我们可以迅速的利用token得到其当前的current state。在解决“并行”等(比如Fork)问题时,jBpm让Token对象维护了父子关系,这种关系在涉及到Fork的时候会产生。 jBpm让Token这个对象身兼了多种使命: (1)快速定位current state (2)用于fork,join算法 (3)用于告知任务执行者的任务索引。 如下代码: //pd是process definition,pi是process instance ProcessInstance pi = new ProcessInstance( pd ); //得到根令牌 Token token = pi.getRootToken(); //发信令 token.signal(); Token的signal方法也可以传入transition参数,这个方法把信令发送给Token,这样,令牌将被激活,并沿指定的transition离开当前的状态(如果没有指定transition,将沿缺省的transition 离开当前状态)。 jbpm是怎么实现的呢?其实很简单: 1)Token记录了当前的状态(current state),只有当前的状态(或称节点)拥有该令牌 2)向TOKEN发signal后,当前状态收到该signal 3)当前状态把令牌传给signal中指定的transition 4)transition收到令牌后,不强占,马上把令牌传给下个状态. 5)根据令牌的位置,流程的状态已经发生改变. 3.process definition 一个process definition代表了一个正式的业务流程,它以一个流程图为基础。这个流程图由许多node和transition组成。每个node在这个流程图里都有着各自特殊的类型,这些不同的类型决定了node在运行时的不同行为。一个process definition只有一个start state 。 4.token 一个token代表了一条执行路径,它包含了这条执行路径的当前的执行状态(current state)。 5.process instance 一个process instance(流程实例)即一个process definition(流程定义)的流程执行实例。一个process definition可以对应多个process instance。当一个process instance被创建的时候,一个主执行路径token同时被创建,这个token叫做root token,它指向流程定义的start state(processDefinition.getStartState()==token.getNode())。 6.signal 一个signal 发送给token通知token 继续流程的执行。如果signal 没有指定transition,token将沿缺省的transition离开当前状态,如果signal 指定transition,token将沿指定的transition离开当前的状态。看源代码可以看到发给process instance的signal 其实都是发送给了root token。 7.Actions jbpm提供了灵活的action ,当流程执行,token 进入node和transition时,会触发相应的一些event(事件)。在这些event上附上我们自己写的action,就会带动action 的执行。action里是我们自己的相关java操作代码,非常方便。注意的是event(事件)是内置的,无法扩展。另外,action也可以直接挂在node上,而不依赖于event(事件)的触发,这个很重要。 8.node 一个流程图由许多node和transition组成。每个node都有一种类型,这个类型决定了当流程执行到这个node时的不同行为。jbpm有一组node type可以供你选择,当然你可以定制自己node 。 node的作用 node有两个主要的作用: 1)执行java代码,比如说创建task instance(任务实例)、发出通知、更新数据库等等。很典型的就是在node 上挂上我们的action 2) 控制流程的执行: A、等待状态:流程进入到这个node时将处于等待状态,直到一个signal 的发出 B、流程将沿着一个leaving transition越过这个node,这种情况特殊一点,需要有个action挂在这个node上(注意这个action不是event触发的!),action中将会调用到API里 executionContext.leaveNode(String transitionName),transitionName即这里的leaving transition名字。 C、创建新的执行路径: 很典型的就是fork node。流程在这里会分叉,产生新的执行路径。这样就创建了新的token,每个新的token代表一个新的执行路径。注意的是,这些新的token和产生前的token是父子关系! D、结束执行路径:一个node可以结束一条执行路径,这同样意味着相应的token的结束和流程的结束。 9.流程图中的node type 1)task-node 一个task-node可以包含一个或多个task,这些task分配给特定的user。当流程执行到task-node时,task instance将会被创建,一个task对应一个task instance。task instances 创建后,task-node就处于等待状态。当所有的task instances被特定的user执行完毕后,将会发出一个新的signal 到token,即流程继续执行。 2)state state是一个纯粹的wait state(等待状态)。它和task-node的区别就是它不会创建task instances。很典型的用法是,当进入这个节点时(通过绑定一个action到node-enter event),发送一条消息到外部的系统,然后流程就处于等待状态。外部系统完成一些操作后返回一条消息,这个消息触发一个signal 到token,然后流程继续执行。(不常用) 3)decision 当需要在流程中根据不同条件来判断执行不同路径时,就可以用decision节点。两种方法:最简单的是在transitions里增加condition elements(条件),condition是beanshell script写的,它返回一个boolean。当运行的时候,decision节点将会在它的 leaving transitions里循环,同时比较 leaving transitions里的condition,最先返回'true'的condition,那个leaving transitions将会被执行;作为选择,你可以实现DecisionHandler接口,它有一个decide()方法,该方法返回一个String(leaving transition的名字)。 4)fork fork节点把一条执行路径分离成多条同时进行(并发)的执行路径,每条离开fork节点的路径产生一个子token。 5)join 默认情况下,join节点会认为所有到达该节点的token都有着相同的父token。join 节点会结束每一个到达该节点的token,当所有的子token都到达该节点后,父token会激活。当仍然有子token处于活动状态时,join 节点是wait state(等待状态)。 6)node node节点就是让你挂自己的action用的(注意:不是event触发!),当流程到达该节点时,action会被执行。你的action要实现ActionHandler接口。同样,在你的action里要控制流程。 10. Actions的说明 存在两种action,一种是 event触发的action,一种是挂在node 节点的action。要注意它们的区别,event触发的action无法控制流程,也就是说它无法决定流程经过这个节点后下一步将到哪一个leaving transition;而挂在node 节点的action就不同,它可以控制流程。不管是哪一种action都要实现ActionHandler接口。 11. Task(任务) jbpm一个相当重要的功能就是对任务进行管理。Task(任务)是流程定义里的一部分,它决定了task instance的创建和分配。Task(任务)可以在task-node节点下定义,也可以挂在process-definition节点下。最普遍的方式是在task-node节点下定义一个或多个任务。默认情况下,流程在task-node节点会处于等待状态,直到所有的任务被执行完毕。任务的名称在整个流程中必须是唯一的。一个TaskNode对应多个Task。 对于这样的流程定义: xml 代码 1. <task-node name='a'> 2. <task name='laundry' /> 3. <task name='dishes' /> 4. <task name='change nappy' /> 5. <transition to='b' /> 6. </task-node> 只有当节点中的三个任务都完成后,流程才进入后面的节点 对于这样的流程定义: xml 代码 1. <task-node name='a' signal='first'>> 2. <task name='laundry' /> 3. <task name='dishes' /> 4. <task name='change nappy' /> 5. <transition to='b' /> 6. </task-node> 当第一个任务完成后,token就指向后面的节点 对于这样的流程定义: xml 代码 1. <task-node name='a' signal='never'>> 2. <task name='laundry' /> 3. <task name='dishes' /> 4. <task name='change nappy' /> 5. <transition to='b' /> 6. </task-node> 三个任务都完成后,token仍然不会指向后面的节点;需要自己手动调用processInstance.signal()才会驱动流程到下面的节点。 对于这样的流程定义: xml 代码 1. <task-node name='a' signal='unsynchronized'>> 2. <task name='laundry' /> 3. <task name='dishes' /> 4. <task name='change nappy' /> 5. <transition to='b' /> 6. </task-node> token不会在本节点停留,而是直接到后面的节点 12. jbpm的任务管理实现 一个Task instance(任务实例)可以被分配给一个actorId (java.lang.String)。所有的Task instance都被保存在数据库中的表jbpm_taskinstance里。当你想得到特定用户的任务清单时,你就可以通过一个与用户关联的actorId来查询这张表。 一个流程定义有一个TaskMgmtDefinition;一个TaskMgmtDefinition对应多个swimlane,同时对应多个task;一个swimlane有多个task,可以从TaskMgmtDefinition中通过task的名称直接获取相应的task; swimlane对象有四个属性,分别是name(名字)、assignmentDelegation(分配代理类)、taskMgmtDefinition、tasks(Set 对应多个task),可以增加task task对象主要的属性:taskMgmtDefinition、swimlane、assignmentDelegation、taskNode,需要注意的是swimlane和assignmentDelegation中间只是可以一个属性有值,因为它们都和任务的分配有关系。 一个流程实例有一个TaskMgmtInstance;一个TaskMgmtInstance对应多个swimlaneInstance,同时对应多个taskInstance;一个swimlaneInstance有多个taskInstance,可以从TaskMgmtInstance中直接获取相应的taskInstance; swimlaneInstance对象主要有五个属性,分别是name、actorId、pooledActors(Set)、swimlane、taskMgmtInstance。 taskInstance对象的主要属性:name、actorId、task、swimlaneInstance、taskMgmtInstance、pooledActors。 当对任务进行分配时,一般需要实现AssignmentHandler这个接口,这个接口的方法只有一个: void assign( Assignable assignable, ExecutionContext executionContext) throws Exception; 一个典型的实现(把名字是'change nappy'的任务交给NappyAssignmentHandler这个类来分配) xml 代码 1. <task name='change nappy'> 2. <assignment class='org.jbpm.tutorial.taskmgmt.NappyAssignmentHandler' /> 3. task> NappyAssignmentHandler类: java 代码 1. public void assign(Assignable assignable, ExecutionContext executionContext) { 2. assignable.setActorId("papa"); 3. } 同样,Assignable只是一个接口,它有两个方法:setActorId()和setPooledActors(),Assignable的具体实现类也是两个:swimlaneInstancehe和taskInstance。这样就不不难理解整个任务分配流程了: 1、流程进入TaskNode节点,执行TaskNode类的execute()方法,该方法首先获得TaskMgmtInstance实例,然后通过它来创建TaskInstance。taskMgmtInstance.createTaskInstance(task, executionContext); 2、在上面的createTaskInstance(task, executionContext)里,该方法调用了taskInstance.assign(executionContext)对taskInstance进行分配。 3、在assign(executionContext)方法里,首先会判断task属性里是否存在swimlane,如果有的话,这个taskInstance就会分配给swimlane指定的ActorId或 PooledActors;如果不存在,再去找task属性里 assignmentDelegation(分配代理类)通过代理类(即我们自己写的实现AssignmentHandler这个接口的类)指定ActorId或 PooledActors。 13. jbpm的用户角色管理 jbpm在用户角色管理上共设计了四个类:Entity、Membership、Group、User。 Entity类是其他三个类的父类,它包含了两个属性:name(String)、permissions(Set); User类继承Entity类,包含三个属性:password(String)、email(String)、memberships(Set); Group类继承Entity类,包含四个属性: type(String)、parent(Group)、children(Set)、memberships(Set); Membership类继承Entity类,包含三个属性:role(String)、user(User)、group(Group) 很明显,一个user对应一个用户,一个group对应一个用户组,它们之间通过membership关联,并且一个user可以属于多个不同类型(type)的group,user和 group之间是多对多的关系。Membership类的role属性个人感觉用途不大,反倒是name属性代表了user在group里的role(角色)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值