业务流程的一个重要方面是人工任务管理。虽然一些执行的工作过程中可以自动执行一些任务需要执行的人类演员。
jBPM支持特殊的人工任务节点内部流程建模与人类用户交互。这个人工任务节点允许流程设计者定义属性相关的人类演员需要执行的任务,例如像任务的类型,演员(s),或与任务相关的数据。
jBPM还包括一个所谓的人工任务服务,后端服务在运行时管理这些任务的生命周期。jBPM实现基于ws - humantask规范。但是要注意,这个实现是完全可插拔的,这意味着用户可以整合自己的人工任务的解决方案,如果必要的话。
为了人类演员参与流程,您首先需要(1)包括人工任务节点内部流程模型与人类参与者的交互,(2)集成任务管理组件(如例如jBPM提供的基于ws - humantask的实现)和(3)与人工任务交互终端用户客户端请求任务列表和声明和完成分配给他们的任务。这三个元素将在下一节中详细讨论。
jBPM支持使用人工任务内部流程使用一个特殊的用户任务节点BPMN2规范定义的(如上图所示)。一个用户任务节点代表一个原子任务,需要由人类参与者执行。
(尽管jBPM有着特殊的用户任务节点包括人工任务在一个过程中,人工任务被认为是与其他任何需要调用外部服务的,因此简单地实现为一个特定领域的服务。看到这一章领域特定的流程来了解更多关于这一点。)
一个用户任务节点包含以下核心属性:
演员:演员负责执行的人工任务。演员可以指定id的列表使用逗号(,)分隔符。
组:负责执行的组id的人工任务。组id的列表可以指定使用一个逗号(,)分隔符。
名字:节点的显示名称。
TaskName:人工任务的名称。这个名字是用来链接任务表单。它还代表任务的内部名称,可用于其他用途。
DataInputSet:所有的输入变量任务将获得工作。通常你会感兴趣的复制过程的作用域中的变量的范围的任务。(看看数据映射部分为例)
DataOutputSet:所有生成的输出变量,将执行任务。在这里您指定上下文中的所有变量的名称您感兴趣的任务复制的过程。(看看数据映射部分为例)
作业:给你指定哪个流程变量将与每个数据输入和数据输出映射。(看看数据映射部分为例)
您可以编辑这些变量在properties视图中选择用户任务节点时(见下文)。
一个用户任务节点还包含额外的属性如下:
评论:评论与人工任务相关。在这里您可以使用表达式。
内容:与该任务相关的数据。
优先级:一个整数表示人工任务的优先级。
Skippable:指定人工任务是否可以跳过,即。,演员是否可能决定不执行任务。
入口和出口的行动:行动执行脚本,在入口和出口的节点,分别。
人工任务通常存在一些数据相关的演员需要执行的任务是执行任务,通常还要求演员提供一些相关结果数据的执行任务。任务表单通常用于把资料提交给演员和请求的结果。
的数据将被用于当我们定义指定的任务需要用户任务在我们的流程。为了做到这一点,我们需要从流程上下文定义哪些数据将被复制到任务上下文。注意,数据复制,所以它可以修改任务上下文内,但不会影响流程变量,除非我们决定回副本任务流程上下文中的值。
大多数时候形式用于显示数据给最终用户。让他们产生/创建新的数据,将传播流程上下文使用未来的活动。为了决定如何信息流从流程到一个特定的任务和任务的过程中,我们需要定义的信息将自动复制由流程引擎。下面的小节展示如何做这些映射通过配置DataInputSet,DataOutputSet和用户任务的作业性能。
让我们开始定义任务DataInputSet:
GroupId和评论都是自动生成的,所以你不需要担心。在这种情况下,只有用户定义的数据输入叫做:in_name。这意味着任务是接收信息从内部流程上下文和这个变量将被称为in_name。也在此指定类型。
在数据输出代表将生成的数据的任务。在这种情况下,我们有两个字符串类型的变量称为:out_name out_mail和两个整数变量称为:out_age andout_score定义。这意味着任务上下文内我们将需要设置这些变量的值。
最后的所有连接流程上下文数据需要做作业。这里的主要想法是定义如何与数据输入和数据输出过程变量中。
之前的截图所示,过程变量之间的作业(在本例中(姓名、年龄、邮件和hr_score))和数据输入和输出在屏幕数据作业完成。注意,示例使用公约,使它容易知道这是一个内部任务变量(数据输入/输出)使用“in_”和“out_”前缀的变量名。使用本公约可以快速了解作业的屏幕。第一行将流程变量名称映射到数据输入称为in_name。第二行地图数据输出称为calledmail out_mail流程变量,等等。
这些映射在运行时将自动复制变量内容从一个上下文(流程和任务)到另一个自动为我们。
从流程的角度来看,当一个用户在执行任务节点时,创建一个人工任务。用户任务节点的过程只会离开当相关的人工任务已经完成或中止。
人工任务本身通常有一个完整的生命周期本身。超出下面描述的详细信息,请查看ws - humantask规范。下图是ws - humantask规范和描述了人工任务的生命周期。
一个新创建的任务开始在“创建”阶段。通常,它会自动成为“准备好了”,之后的任务将显示在任务列表的所有演员允许执行该任务。任务将保持“准备好”,直到其中一个演员的任务,表明他或她将会执行它。
当用户最终要求的任务,“保留”的状况将会改变。注意,一个任务,只有一个潜在(特定)演员将自动分配给演员在创建的任务。当用户接收任务开始执行,任务状态将改变从“保留”到“中的”。
最后,一旦用户有执行和完成任务,任务状态将改变“完成”。在这个步骤中,用户可以选择指定结果数据相关的任务。如果任务不可能完成,用户也可以显示通过使用错误响应,其中可能包括故障数据,在这种情况下,状态将改变“失败”。
在上面的生命周期解释是正常的生命周期,该规范还描述了许多其他生命周期方法,包括:
委派或转发任务,任务被分配给另一个演员
撤销一项任务,它不再是要求一个特定的演员,但(重新)提供给所有演员可以把它
Temporarly暂停和恢复任务
停止一个任务在进步
跳过一个任务(如果已经标记为skippable),在这种情况下,任务不会被执行
只允许用户关联到一个特定的任务修改或检索有关任务的信息。这允许用户创建一个jBPM工作流与多个任务,但仍然保证机密性和完整性的任务的状态和与任务相关的信息。
一些任务操作最终将把org.jbpm.services.task.exception。PermissionDeniedException在使用未经授权的用户信息。例如,当一个用户试图直接修改任务(例如,通过尝试索赔或完成任务),将抛出PermissionDeniedException如果用户没有正确的操作的角色。此外,用户将无法查看或检索任务,用户不参与,尤其是如果这是通过jBPM控制台或KIE工作台应用程序。
用户的管理员和组“管理员”会自动添加到每个人工任务。
permisions矩阵总结了以下行动,允许特定用户角色。左侧列出可能的操作,而用户角色在顶部列出的矩阵。
细胞三种可能的权限矩阵包含一个字符,每个显示的用户角色权限操作:
“+表示用户角色可以做指定的操作
“-”表示用户角色不可能指定的操作
“_”表示用户角色可能不会执行指定的操作,而且它也不是一个操作相匹配用户的角色(不适用)
此外,下列表中的单词或缩写标题参考以下角色:
Table 7.1. Task roles in the permissions table
Word | Role | Description |
---|---|---|
Initiator |
Task Initiator |
的用户创建任务实例 |
Stakeholder |
Task Stakeholder |
用户参与的任务:这个用户会影响任务的进展,通过执行管理操作任务实例 |
Potential |
Potential Owner |
的用户可以声称这项任务之前一直声称,或后已经发布或转发:只有任务状态“准备好”可能声称,任务的潜在所有者成为实际的所有者声称这个任务 |
Actual |
Actual Owner |
的用户接收任务,并将进展任务完成或失败 |
Administrator |
Business Adminstrator |
“超级用户”可以修改任务的状态或进步在任何时候在任务的生命周期 |
下面的矩阵描述了所有操作的授权,修改任务:
Table 7.2. Main operations permissions matrix
Operation\Role | Initiator | Stakeholder | Potential | Actual | Administrator |
---|---|---|---|---|---|
activate |
+ |
+ |
_ |
_ |
+ |
claim |
- |
+ |
+ |
_ |
+ |
complete |
- |
+ |
_ |
+ |
+ |
delegate |
+ |
+ |
+ |
+ |
+ |
fail |
- |
+ |
_ |
+ |
+ |
forward |
+ |
+ |
+ |
+ |
+ |
nominate |
+ |
+ |
+ |
+ |
+ |
release |
+ |
+ |
+ |
+ |
+ |
remove |
- |
_ |
_ |
_ |
+ |
resume |
+ |
+ |
+ |
+ |
+ |
skip |
+ |
+ |
+ |
+ |
+ |
start |
- |
+ |
+ |
+ |
+ |
stop |
- |
+ |
_ |
+ |
+ |
suspend |
+ |
+ |
+ |
+ |
+ |
Table 7.3. Retrieval operations permissions matrix
Operation\Role | Initiator | Stakeholder | Potential | Actual | Administrator |
---|---|---|---|---|---|
get |
+ |
+ |
+ |
+ |
+ |
jBPM引擎而言,人工任务类似于任何其他需要调用外部服务和被实现为一个特定领域的服务。(更多关于特定于域的服务,看到这一章了。)因为一个人工任务是这样一个领域特定服务的一个例子,这一过程本身只包含一个高层次、抽象的描述要执行的人工任务和工作项处理程序负责绑定这个(文摘)任务到一个特定的实现。
用户可以插入任何人工任务服务实现,例如由jBPM提供,或者他们可能注册自己的实现。在接下来的段落中,我们将描述jBPM提供的人工任务服务实现。
jBPM项目提供了一个默认实现基于ws - humantask人工任务服务的规范。如果你不需要集成与另一个现有的jBPM实现人工任务服务的,您可以使用该服务。jBPM实现管理任务的生命周期(创建、声称完成,等)和商店的所有任务,任务列表,和其他相关信息。它还支持功能,如国际化、日历集成不同类型的作业,代表团,升级和最后期限。实现本身的代码可以发现jbpm-human-task模块。
jBPM任务服务实现是基于ws - humantask(WS-HT)规范。这个规范定义了(详细)模型的任务,生命周期,以及许多其他功能。它非常全面和第一个版本可以在这里找到。
人工任务服务公开了一个Java API来管理任务的生命周期。这允许客户端集成(在低水平)与人工任务服务。注意,终端用户应该不会与这低级API直接交互,但使用一个更具用户友好性任务的客户(见下文)。这些客户提供一个图形用户界面请求任务列表,声明和完成任务,和管理任务。下面列出的任务客户内部使用Java API与人工任务交互服务。当然,低级API也可以,这样开发者就可以在自己的代码中使用它直接与人工任务服务交互。
任务服务(界面org.kie.api.task.TaskService)提供了以下方法(等)管理人工任务的生命周期:
void start( long taskId, String userId ); void stop( long taskId, String userId ); void release( long taskId, String userId ); void suspend( long taskId, String userId ); void resume( long taskId, String userId ); void skip( long taskId, String userId ); void delegate(long taskId, String userId, String targetUserId); void complete( long taskId, String userId, Map<String, Object> results ); 如果你看一下方法签名,你会发现几乎所有的这些方法采取以下参数:
taskId:任务的id,我们正在处理。这通常是提取用户任务列表中当前选中的任务的用户界面。
用户标识:用户的id执行行动。这通常是用户的id登录到应用程序中。
还有一个内部接口,您应该检查方法与任务服务交互,这个接口是内部,直到它得到测试。未来版本的外部(公共)接口可以包含一些方法提出了InternalTaskService接口。如果你想使用这个接口提供的方法你需要手动把InternalTaskService。一个方法,可以从这个接口有用getTaskContent():
Map<String, Object> getTaskContent( long taskId );
这种方法可以节省你做所有的锅炉钢板ContentMarshallerContext解组的序列化版本任务内容。如果你只想用稳定/公共API的你可以复制什么这个方法:
Task taskById = taskQueryService.getTaskInstanceById(taskId); Content contentById = taskContentService.getContentById(taskById.getTaskData().getDocumentContentId()); ContentMarshallerContext context = getMarshallerContext(taskById); Object unmarshalledObject = ContentMarshallerHelper.unmarshall(contentById.getContent(), context.getEnvironment(), context.getClassloader()); if (!(unmarshalledObject instanceof Map)) { throw new IllegalStateException(" The Task Content Needs to be a Map in order to use this method and it was: "+unmarshalledObject.getClass()); } Map<String, Object> content = (Map<String, Object>) unmarshalledObject; return content; 因为任务的内容可以是任何对象,前面的方法假设你存储的地图对象的工作。如果你存储地图除了你应该做相应检查。
为了获得任务服务API推荐让运行时管理器,以确保一切都是正确设置。看更多信息,运行时管理器部分。从API的角度来看,你应该做的是这样的:
... RuntimeEngine engine = runtimeManager.getRuntimeEngine(EmptyContext.get()); KieSession kieSession = engine.getKieSession(); // Start a process kieSession.startProcess("CustomersRelationship.customers", params); // Do Task Operations TaskService taskService = engine.getTaskService(); List<TaskSummary> tasksAssignedAsPotentialOwner = taskService.getTasksAssignedAsPotentialOwner("mary", "en-UK"); // Claim Task taskService.claim(taskSummary.getId(), "mary"); // Start Task taskService.start(taskSummary.getId(), "mary");
如果您使用这种方法,不需要注册流程引擎的任务服务。自动运行时经理会为你这样做。如果你不使用运行时经理,你将负责设置LocalHTWorkItemHandler在会话中为了得到任务服务通知流程引擎当任务完成时,或一个任务的流程引擎通知已创建。
jBPM 6。x任务服务在本地运行流程和规则引擎,因此可以创建多个光客户不同的流程和规则引擎的实例。所有客户端都将共享相同的数据库(后端存储的任务)。