簡體   English   中英

Spring Activiti在完成任務之前驗證受讓人或候選人組

[英]Spring Activiti verify assignee or candidateGroups before completing task

我正在與Spring Acitviti一起管理項目的工作流程。 我是Activiti的新手,正在嘗試使其與自定義用戶群配合使用。 以下是我正在處理的示例項目

https://github.com/ConsciousObserver/AcitvitySpringTest.git

目前,我正在嘗試限制可以在流程simple-test-process執行特定任務taskA用戶。

似乎在調用taskService.complete(task.getId()) Activiti完全忽略了分配給誰的任務。 由於項目中尚未配置安全性,並且taskA分配給Hello World ,由於匿名用戶試圖執行它,它應該會失敗。

活動是否需要我們在執行任務之前手動檢查assigneecandidateUserscandidateGroups

如果不是,那么我們如何使用Activiti指示僅讓特定用戶完成任務。

simple-test-process.bpmn圖下面包括相關代碼

simple-test-process.bpmn圖

簡單測試process.bpmn

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
    xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
    typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
    targetNamespace="http://www.example.org/test">
    <process id="simple-test-process" name="simple-test-process">
        <startEvent id="startEvent" name="startEvent"></startEvent>
        <sequenceFlow id="sequenceFlow1" targetRef="initTask" sourceRef="startEvent" />
        <serviceTask id="initTask" name="initTask" activiti:expression="${myService.init(photos)}"></serviceTask>
        <sequenceFlow targetRef="taskA" sourceRef="initTask"></sequenceFlow>
        <userTask id="taskA" name="taskA" activiti:assignee="Hello World" ></userTask>
        <sequenceFlow id="sequenceFlow2" targetRef="taskB" sourceRef="taskA"></sequenceFlow>
        <userTask id="taskB" name="taskB" activiti:assignee="$INITIATOR"></userTask>
        <sequenceFlow id="sequenceFlow3" targetRef="endEvent" sourceRef="taskB" />
        <endEvent id="endEvent" name="endEvent"></endEvent>
    </process>
</definitions>

ActivitiTestApplication.java

package com.example;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class ActivitiTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(ActivitiTestApplication.class, args);
    }

    @Bean
    InitializingBean usersAndGroupsInitializer(final IdentityService identityService) {

        return () -> {
                Group group = identityService.newGroup("user");
                group.setName("users");
                group.setType("security-role");
                identityService.saveGroup(group);

                User admin = identityService.newUser("admin");
                admin.setPassword("admin");
                identityService.saveUser(admin);
            };
    }
}

@RestController
class ProcessRest {
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @GetMapping("/start")
    public List<Map<String, String>> start() {
        List<String> photos = Arrays.asList("photo1", "photo2");
        runtimeService.startProcessInstanceByKey("simple-test-process", Collections.singletonMap("photos", photos));

        long runningProcessCount = runtimeService.createProcessInstanceQuery().count();
        List<ProcessInstance> processes = runtimeService.createProcessInstanceQuery().list();

        return processes
                .stream()
                .map(p -> getMap(p.getId(), p.getProcessInstanceId(), p.getProcessDefinitionName()))
                .collect(Collectors.toList());
    }

    @GetMapping("/getTasks/{processInstanceId}")
    public List<Map<String, String>> getTasks(@PathVariable String processInstanceId) {
        List<Task> tasks = taskService
            .createTaskQuery()
            .processInstanceId(processInstanceId)
            .list();

        return tasks
                .stream()
                .map(t -> getMap(t.getId(), t.getProcessInstanceId(), t.getName()))
                .collect(Collectors.toList());
    }

    @GetMapping("/completeTask/{processInstanceId}")
    public Map<String, String> completeNextTask(@PathVariable String processInstanceId) {
        Task task = taskService.createTaskQuery()
                        .processInstanceId(processInstanceId)
                        .singleResult();

        if(task == null) {
            throw new RuntimeException("No pending task for this processInstance");
        }

        System.out.println("variables: " + task.getProcessVariables());

        taskService.complete(task.getId());

        return getMap(task.getId(), task.getProcessInstanceId(), task.getName());
    }

    public Map<String, String> getMap(String id, String instanceId, String name) {
        Map<String, String> map = new HashMap<>();
        map.put("id", id);
        map.put("processInstanceId", instanceId);
        map.put("name", name);

        return map;
    }
}
@Component
class MyService {
    public void init(List<String> photos) {
        System.out.println("################################### Running Init Task ########################");
        for(String photo: photos) {
            System.out.println("Photo name: " + photo);
        }
    }

    public String processPhoto(List<String> photos) {
        for(String photo: photos) {
            System.out.println("Photo name: " + photo);
        }
        return "processed";
    }
}

不幸的是,沒有魔術能為您做到這一點,因此您將需要驗證這些內容,例如任務的受讓人等。

我敢打賭,您將需要比硬編碼的“ Hello World”更動態的東西,因此,為了創建更動態的東西,作為一個簡單的示例,我將/start端點從GET更改為POST並檢索作為參數的受讓人。

@PostMapping("/start")
public List<Map<String, String>> start(String assignee) {

並在processVariables傳遞屬性

就像是:

Map<String, Object> variables = Collections.singletonMap("photos", photos);
variables.put("person", assignee);

將您的bpmn從activiti:assignee="Hello World"更改為activiti:assignee=${person}

並添加一個TaskListener ,它將為每個任務驗證用戶擁有什么受讓人。 您將在此處找到TaskListener的示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM