JBPM 5人工任务

一、 人工任务属性


jBPM 支持在 流程 内使用一个指定的 用户 任务节点(如上面图所示)表示人工任务。
一个用户任务节点代表一个原子性的任务,需要通过一个人角色来执行。
虽然 jBPM 流程中的人工任务包含有指定用户节点,但人工任务可以简单的看做是任何类型的外部服务,需要调用时作为工作任务项的一种特殊类型的简单实现。
唯一要指出的是用户任务节点,我们添加了对泳道的支持,从而更容易将任务分配给用户(见下文)。
一个用户任务节点包含下列属性:

  • Id
    :节点的 ID
    在一个节点容器内他是唯一的)。
  • Name
    :该节点显示的名称。
  • Task Name
    :人工任务的名称。
  • Priority
    :一个整数,表示人工任务的优先级。
  • Comment :人工任务关联的注释。
  • ActorId
    :执行者 ID 是负责执行任务的人。
    多个 的执行者 ID 可以使用逗号作为分隔 (',')
  • Skippable
    :指定人工任务是否可以跳过(即执行者决定不执行人工任务)。
  • Contend  :任务关联数据。
  • Swimlane :泳道是人工任务节点的一部分。
    泳道可以很容易地分配多个人工任务到同一个执行者。
    请参阅下面详细的泳道使用。
  • Wait for completion
    :如果此属性为 true ,人类任务终止了(即完成或任何其他终止状态)人工任务节点才能继续,否则它会创造人工任务后立即继续任务。
  • On-entry and on-exit      action s
    :进入和退出节点后执行此 Actions
  • Parameter mapping
    :允许复制的流程变量值到人工任务参数中。
    当人工任务创造后,这些值将被复制。
  • Result mapping  :允许复制人工任务的结果参数到流程变量。
    人工 任务完成后,这些值将被复制。
    请注意, “Wait for completion” 设置为 true 时只能使用结果映射。
    一个人工任务有一个结果变量的 “Result” ,它包含返回的数据通过人工执行者。
    变量 “actorId 包含了实际任务执行执行者的 ID
  • Timers
     Timers 关联到这个节点
  • ParentId
    :允许指定的父任务 Id ,这是表示这个任务做为另外一个的子任务。


二、人工任务生命周期
      从这个流程透视来看,每当一个流程实例的执行时用户任务节点将触发,创建一个人工任务。
这个流程想该点继续只有当人工任务已经完成或中止(当然,除非你指定该过程不需要等待人工任务完成,通过设置 “Wait for completion” 属性设置为 true )。
然而,人工任务本身通常有一个单独的生命周期。
现在,我们将很快介绍这个生命周期,如下面的图所示。

每当一个任务被创建时,它进入 “Created” 状态。
它通常会自动转移换到 “Ready” 状态,此时任务会显示允许执行任务的所有执行者 (actors)
在这里,它将等待一个执行者认领任务,这表明他或她将要执行这个任务。
一旦用户认领了一个任务,状态更改为 “Reserved”
请注意,在任务创建时任务只有一个潜在的执行者将自动分配给执行者,
获取任务后,该用户可以决定在某个时候开始执行任务,在这种情况下,任务的状态更改为 “InProgress”
最后,一
旦任务已经执行,用户必须完成任务(并且可以指定相关的任务的结果数据),在这种情况下,状态更改为 “Completed”
如果任务无法完成,用户还可以指明为响应故障(可能的相关故障数据),在这种情况下,状态更改为 “Failed”

以上是正常生命周期的解释。
该服务还允许其他生命周期的方法,如:

o
委派或转发任务,在这种情况下,它被分配给另一个执行者

o
撤销任务,这样它不再指派给一个指定的执行者,所有潜在的执行者将重新出现的任务列表

o
暂停和恢复任务

o
停止进行中的任务

o
跳过一个任务(如果该任务已被列为 skippable 标记),在这种情况下,任务将不会执行


三、示例实现
        人工任务节点在JBPM5中是一个异步WorItem,JBPM5中已经带有一个WorkItemHandler的人工任务的实现类是WSHumanTaskHandler,这个handler能同一个Task Service通信(由jBPM5提供),并在其中创建一个新的任务。然后,它将等待别人(使用人工客户端API)来完成/取消该任务。
       在jbpm5中你可以实现WorkItemHandler接口, 不使用默认实现,根据你需要进行。
如:
class MyNonAutomaticHumanSimulatorWorkItemHandler implements WorkItemHandler {
    private WorkItemManager workItemManager;
    private long workItemId;

    public void executeWorkItem(WorkItem workItem, WorkItemManager workItemManager) {
        this.workItemId = workItem.getId();
        this.workItemManager = workItemManager;
        System.out.println("Map of Parameters = " + workItem.getParameters());
    }

    public void abortWorkItem(WorkItem workItem, WorkItemManager workItemManager) {

    }

    public void completeWorkItem(Map<String, Object> parameters) {
        this.workItemManager.completeWorkItem(this.workItemId, parameters);

    }
那在注册的时候你就可以注册自已的实现:
MyHumanChangingValuesSimulatorWorkItemHandler humanActivitiesSimHandler = new MyHumanChangingValuesSimulatorWorkItemHandler();
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", humanActivitiesSimHandler);


       在实现在我们需要实现一个服务端和一个客户端,jBPM5的安装包中提供一个示例,它服务端采用ant启动, 数据库 使用h2。下面将依据这个示例做一个类似的例示,数据据使用MYSQL5,学习它们之间的交互。
o

服务端实现
1、继承UserInfo,方便添加用户与组相关信息;

2、添加一个最小的服务监听实现;

public void startServer() {
        if(isRunning())
            throw new IllegalStateException("Server is already started");
        this.running = true;
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("org.drools.task");
        TaskService taskService = new TaskService(entityManagerFactory, SystemEventListenerFactory.getSystemEventListener());
        TaskServiceSession taskSession = taskService.createSession() ;
        UserInfoDomain userInfo = new UserInfoDomain();
        taskService.setUserinfo( userInfo);
        
        for (String userName : getDefaultUsers()) {
            taskSession.addUser(new User(userName));
        }
        
        taskServer = new MinaTaskServer(taskService);
        Thread thread = new Thread(taskServer);
        thread.start();
    }

3、配置数据库连接
人工任务有相关的数据实体,包含在jbpm-human-task.5.0.0.jar中,在示例代码中我将提供。

o
客户端实现
通过jbpm提供连接方法实现。如下:
   /**
     * 创建客户端连接
     * 
     */
   public HumanTaskClient() {
        client = new TaskClient(new MinaTaskClientConnector("client 1",
                new MinaTaskClientHandler(SystemEventListenerFactory.getSystemEventListener())));
        client.connect("127.0.0.1", 9123);
    }
   /**
     * 加载流程模板和注册人工任务
     * @throws RuntimeException
     */
   public void start() throws RuntimeException {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

                kbuilder.add(new ClassPathResource("rules/humanTask.bpmn"), ResourceType.BPMN2);
                System.out.println("Compiling resources");
        if (kbuilder.hasErrors()) {
            if (kbuilder.getErrors().size() > 0) {
                for (KnowledgeBuilderError  error : kbuilder.getErrors()) {
                                    System.out.println("Error building kbase: "+error.getMessage());
                }
            }
                        throw new RuntimeException("Error building kbase!");
        }

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

        ksession = kbase.newStatefulKnowledgeSession();
        logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
        ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new WSHumanTaskHandler());

    }

    /**
     * 启动流程
     * @throws RuntimeException
     */
    public void startProcess() throws RuntimeException {
        try {
            ksession.startProcess( "com.zt.jbpm.humantask.client", null );
        }
        catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

四、运行

1、启动 服务器 监听:
直接在eclipse里面运行StartHumanTaskServer类的 main方法

运行客户端:直接在eclipse里面运行Application类的main方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值