Activiti6.0學習實踐(9)-核心api:IdentityService、FormService、HistoryService、ManagementService等

前面學習了三個重要的核心API,本章介紹剩下的幾個核心API

1、身份管理服務

流程引擎提供了身份管理服務(IdentityService)來管理用戶(User),管理用戶組(Group),以及用戶和用戶組之間的關係(Membership)。身份管理不依賴與流程定義文件。

身份管理服務調用的實現調用過程如下圖

1.1、創建用戶和組

建立一個測試leiIdentityServiceTest.java

public class IdentityServiceTest {
    private static final Logger logger = LoggerFactory.getLogger(IdentityServiceTest.class);

    @Rule
    public ActivitiRule activitiRule = new ActivitiRule();

    //identity不依賴流程定義文件
    @Test
    public void testIdentity() {

        //獲取身份管理服務
        IdentityService identityService = activitiRule.getIdentityService();
        User user1 = identityService.newUser("user1");
        user1.setEmail("[email protected]");

        User user2 = identityService.newUser("user2");
        user2.setEmail("[email protected]");

        identityService.saveUser(user1);
        identityService.saveUser(user2);

        Group group1 = identityService.newGroup("group1");
        identityService.saveGroup(group1);
        Group group2 = identityService.newGroup("group2");
        identityService.saveGroup(group2);

        identityService.createMembership("user1", "group1");
        identityService.createMembership("user2", "group1");
        identityService.createMembership("user1", "group2");

        List<User> userList = identityService.createUserQuery().memberOfGroup("group1").listPage(0, 100);
        for (User user : userList) {
            logger.info("user = {}", ToStringBuilder.reflectionToString(user, ToStringStyle.JSON_STYLE));
        }

        List<Group> groupList = identityService.createGroupQuery().groupMember("user1").listPage(0, 100);
        for (Group group : groupList) {
            logger.info(" group = {}", ToStringBuilder.reflectionToString(group, ToStringStyle.JSON_STYLE));
        }

    }

}

執行結果

第一個紅框看到可以查詢出屬於group1的兩個用戶,第二個紅框看到查詢出user1輸的用戶組

1.2、修改用戶組

修改上面的測試代碼,加入如下修改用戶的內容

1.3、執行結果

修改lastname後,我們看到version也變爲2

​​​​​​​2、表單管理服務

Activiti提供了表單管理服務,主要提供瞭如下功能:解析流程定義中單項的配置,提交表單的方式驅動用戶節點流轉,獲取自定義外部表單key。主要是對流程定義文件中的表單設置項進行解析

​​​​​​​2.1、創建流程定義文件

在這個例子中,創建一個帶有表單的流程定義文件

​​​​​​​2.2、創建FormServiceTest​​​​​​​

public class FormServiceTest {
    private static final Logger logger = LoggerFactory.getLogger(FormServiceTest.class);

    @Rule
    public ActivitiRule activitiRule = new ActivitiRule();


    @Test
    @Deployment(resources = {"my-process-form.bpmn20.xml"})
    public void testFormService() {
        FormService formService = activitiRule.getFormService();

        //獲取流程定義文件
        ProcessDefinition processDefinition = activitiRule.getRepositoryService().createProcessDefinitionQuery().singleResult();

        //獲取start節點的formkey
        String startFormKey = formService.getStartFormKey(processDefinition.getId());
        logger.info("startFormKey = {} ", startFormKey);

        //獲取start節點表單數據
        StartFormData startFormData = formService.getStartFormData(processDefinition.getId());

        //表單數據項的遍歷
        List<FormProperty> formProperties = startFormData.getFormProperties();
        for (FormProperty formProperty : formProperties) {
            logger.info("formProperty = {}", ToStringBuilder.reflectionToString(formProperty, ToStringStyle.JSON_STYLE));
        }

        //通過fromservice啓動流程引擎
        Map<String, String> properties= Maps.newHashMap();
        properties.put("message", "my test message");  //因爲在定義文件中有message屬性,所以這裏進行賦值
        formService.submitStartFormData(processDefinition.getId(), properties);

        Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
        TaskFormData taskFormData = formService.getTaskFormData(task.getId());
        List<FormProperty> taskFormDataFormProperties = taskFormData.getFormProperties();
        for (FormProperty taskFormDataFormProperty : taskFormDataFormProperties) {
            logger.info("taskFormDataFormProperty = {}", ToStringBuilder.reflectionToString(taskFormDataFormProperty,ToStringStyle.JSON_STYLE));
        }

        //給task的表單屬性賦值
        Map<String, String> properties2= Maps.newHashMap();
        properties2.put("yesORno", "no");  //因爲在定義文件中task有yesORno屬性,所以這裏進行賦值
        formService.submitTaskFormData(task.getId(), properties2);

        Task task1 = activitiRule.getTaskService().createTaskQuery().singleResult();
        logger.info("task1 = {}", task1);


    }

}

 ​​​​​​​2.3、執行結果

​​​​​​​3、歷史管理服務

歷史管理服務主要提供了一下功能:管理流程實例結束後的歷史數據,構建歷史數據的查詢對象,根據流程實例id刪除流程歷史數據。主要是牽涉到一下歷史數據實體:

HistoricProcessInstance:歷史流程實例實體類

HistoricVariableInstance:流程或任務變量值的實體

HistoricActivityInstance:單個活動節點執行的信息

HistoricTaskiInstance:用戶任務實例的信息

HistoricDetail:歷史流程活動任務詳細信息

​​​​​​​3.1、創建測試類HistoryServiceTest

在這個測試類中,將通過HistroyService獲取各種歷史數據

public class HistoryServiceTest {
    private static final Logger logger = LoggerFactory.getLogger(HistoryServiceTest.class);

    @Rule
    public ActivitiRule activitiRule = new ActivitiRule("activiti-history.cfg.xml");


    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void testHistoryService() {
        HistoryService historyService = activitiRule.getHistoryService();
        //用builder可以對兩類變量進行測試
        ProcessInstanceBuilder processInstanceBuilder = activitiRule.getRuntimeService().createProcessInstanceBuilder();

        //普通變量
        Map<String, Object> variables = Maps.newHashMap();
        variables.put("key0", "value0");
        variables.put("key1","value1");
        variables.put("key2","value2");

        //瞬時變量
        Map<String, Object> transientVariables = Maps.newHashMap();
        transientVariables.put("tkey1","tvalue1");

        //啓動流程
        ProcessInstance processInstance = processInstanceBuilder.processDefinitionKey("my-process")
                .variables(variables)
                .transientVariables(transientVariables).start();

        //啓動後,會暫停在task上,這個時候,我們可以用runtimeService進行變量修改
        activitiRule.getRuntimeService().setVariable(processInstance.getId(),"key1", "value1-1");

        //獲取task
        Task task = activitiRule.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        //讓task通過
//        activitiRule.getTaskService().complete(task.getId(),variables);  //可以用這種方式讓task完成,本例中採用另外一種方式
        //通過表單submit的方式讓task通過,先獲取表單,然後調用submit

        Map<String, String> properties= Maps.newHashMap();
        properties.put("fkey1", "fvalue1");
        properties.put("key2", "value2-2");
        activitiRule.getFormService().submitTaskFormData(task.getId(), properties);

        //通過history查詢流程實例對象
        List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery().listPage(0,100);
        for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
            logger.info(" historicProcessInstance = {}", ToStringBuilder.reflectionToString( historicProcessInstance,ToStringStyle.JSON_STYLE));
        }

        //查詢節點
        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery().listPage(0, 100);
        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
            logger.info(" historicActivityInstance = {}", historicActivityInstance);
        }

        //查詢task
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().listPage(0, 100);
        for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
            logger.info(" historicTaskInstance = {}", ToStringBuilder.reflectionToString(historicTaskInstance, ToStringStyle.JSON_STYLE));
        }

        //查詢variable
        List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery().listPage(0, 100);
        for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
            logger.info(" historicVariableInstance = {}", historicVariableInstance);
        }

        //查詢details
        List<HistoricDetail> historicDetails = historyService.createHistoricDetailQuery().listPage(0, 100);
        for (HistoricDetail historicDetail : historicDetails) {
            logger.info(" historicDetail = {}", ToStringBuilder.reflectionToString(historicDetail, ToStringStyle.JSON_STYLE) );
        }
        //查詢his log,通過include控制查詢的內容
        ProcessInstanceHistoryLog processInstanceHistoryLog = historyService.createProcessInstanceHistoryLogQuery(processInstance.getId())
                .includeActivities()
                .includeComments()
                .includeVariables()
                .includeFormProperties()
                .includeTasks()
                .includeVariableUpdates().singleResult();

        List<HistoricData> historicDataList = processInstanceHistoryLog.getHistoricData();
        for (HistoricData historicData : historicDataList) {
            logger.info(" historicData = {}", ToStringBuilder.reflectionToString(historicData, ToStringStyle.JSON_STYLE));
        }

        //刪除流程歷史記錄
        historyService.deleteHistoricProcessInstance(processInstance.getId());

        //驗證刪除後的歷史記錄無法爲空  期望爲null
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().singleResult();
        logger.info(" After delete, historicProcessInstance = {} ", historicProcessInstance);
    }

 ​​​​​​​3.2、執行結果

​​​​​​​4、管理服務

ManagementService是管理服務,可以進行job任務管理,數據庫相關通用操作,自定義sql查詢,可以執行流程引擎名利(Command)。

​​​​​​​4.1、流程定義

在流程定義中,我們配置一個job

另外,我們還需要在cfg文件中,添加一個異步動作的配置

​​​​​​​4.2、查找JOB

4.2.1、建立測試函數testJobQuery

建立一個測試類ManagementServiceTest,在這個類裏面,建立如下測試函數

@Test
@Deployment(resources = {"my-process-job.bpmn20.xml"})
public void testJobQuery() {

    ManagementService managementService = activitiRule.getManagementService();
    List<Job> jobs = managementService.createTimerJobQuery().listPage(0, 100);
    for (Job job : jobs) {
        logger.info("timeJob = {}", job);
    }

    JobQuery jobQuery = managementService.createJobQuery();
    SuspendedJobQuery suspendedJobQuery = managementService.createSuspendedJobQuery();
    List<Job> jobs1 = suspendedJobQuery.listPage(0,100);
    for (Job job : jobs1) {
        logger.info("suspend job = {}", job);
    }

    DeadLetterJobQuery deadLetterJobQuery = managementService.createDeadLetterJobQuery();
    List<Job> jobs2 = deadLetterJobQuery.listPage(0, 100);
    for (Job job : jobs2) {
        logger.info("dead job = {}", job);
    }


}

4.2.2、執行日誌

​​​​​​​4.3、數據庫表查詢

4.3.1、測試代碼

@Test
@Deployment(resources = {"my-process-job.bpmn20.xml"})
public void testTablePageQuery() {

    ManagementService managementService = activitiRule.getManagementService();
    TablePage tablePage = managementService.createTablePageQuery()
            .tableName(managementService.getTableName(ProcessDefinitionEntity.class))
            .listPage(0, 100);

    List<Map<String, Object>> rows = tablePage.getRows();
    for (Map<String, Object> row : rows) {
        logger.info("row = {}", row);

    }

}

4.3.2 執行結果

​​​​​​​4.4、數據庫sql操作

4.4.1、定義mapper接口

數據庫sql操作,需要先定義個mapper接口

package com.study.activiti.mapper;

import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Map;

public interface MyCustomMapper
{
    @Select("SELECT * from ACT_RU_TASK")
    public List<Map<String, Object>> findAll();
}

4.4.2、cfg文件配置mapper對象

將這個接口在cfg文件配置進去

4.4.3、測試代碼

@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testTablePageQuery() {
    //啓動流程
    activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
    //查詢task表中內容  表ACT_RU_TASK, 在mapper中定義的sql
    ManagementService managementService = activitiRule.getManagementService();
    List<Map<String, Object>> mapList = managementService.executeCustomSql(new AbstractCustomSqlExecution<MyCustomMapper,
            List<Map<String, Object>>>(MyCustomMapper.class) {
        @Override
        public List<Map<String, Object>> execute(MyCustomMapper o) {
            return o.findAll();
        }
    });

    for (Map<String, Object> map : mapList) {
        logger.info(" map = {}", map);
    }

}

4.4.4、執行日誌:

​​​​​​​4.5、執行命令

4.5.1、測試代碼


@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testCommand() {
    //啓動流程
    activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
    //獲取management
    ManagementService managementService = activitiRule.getManagementService();

    //執行execute
    ProcessDefinitionEntity processDefinitionEntity = managementService.executeCommand(new Command<ProcessDefinitionEntity>() {
        @Override
        public ProcessDefinitionEntity execute(CommandContext commandContext) {
            ProcessDefinitionEntity processDefinitionEntity = commandContext.getProcessDefinitionEntityManager()
                    .findLatestProcessDefinitionByKey("my-process");
            return processDefinitionEntity;
        }
    });

    logger.info("processDefinitionEntity = {}", processDefinitionEntity);
}

4.5.2、執行日誌:

​​​​​​​5、動態流程定義服務

DynamicBpmnService是6.0以後纔有的動態流程定義服務,但是不建議使用,因爲這個是對業務進行強制修改,容易引發混亂,建議少用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章