# 1、平台SPI集成

BPM的SPI扩展能力继承的是V8平台统一的SPI扩展能力,基础应用包已经导入,第三方按照V8统一的SPI编写工程制作jar包,并在BPM的nacos配置中添加加载即可。

# 1.1、SPI集成jar包步骤

【1】创建独立的本地java项目。 【2】第三方需要引用bpm-facade接口包。 【3】实现bpm-facade中定义的关键接口

接口名称 接口说明
com.seeyon.bpm.api.ext.activity.ActivityBehaviorFactory 自定义节点加载的工厂类,主要负责自定义节点行为、json文件等关键信息加载
com.seeyon.bpm.api.ext.activity.ActivityBehavior 定义自定义节点在运行态的实际执行动作,例如获取运行时数据,修改表单数据等

【4】定义自定义节点对应的json配置文件。 【5】依据V8平台统一的SPI集成机制,在工程目录创建resources/META-INF/spring.factories文件,并将实现的com.seeyon.bpm.api.ext.activity.ActivityBehaviorFactory=xxxx实现类加入到该文件。 【5】通过maven或者其他构建工具,对该独立功能制作成jar包。

# 2、详细实例

本实例以添加一个简单节点,并将其显示在流程设计的选项中,以及最终在流程运行态获取流程实例运行时数据

# 2.1、制作集成jar包

# 2.1.1、创建独立工程

这里我们创建一个简单的maven工程,项目名称叫demo-activity

# 2.1.2、添加相关依赖

添加bpm-facade依赖,这里需要注意集成到目标bpm服务的版本,我们这里采用3.18.0-DEV-SNAPSHOT为例,在pom.xml中添加依赖,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>demo-activity</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.seeyon</groupId>
            <artifactId>bpm-facade</artifactId>
            <version>3.18.0-DEV-SNAPSHOT</version>
        </dependency>

    </dependencies>

</project>

# 2.1.3、实现相关接口

# 具体代码如下:
import com.seeyon.bpm.api.ext.activity.ActivityBehavior;
import com.seeyon.bpm.api.ext.activity.ActivityBehaviorFactory;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DemoSpiActivityBehaviorFactoryImpl implements ActivityBehaviorFactory {

    /**
     * 用来缓存每个自定义节点的行为实例
     */
    private Map<String, List<ActivityBehavior>> behaviors = new HashMap<String, List<ActivityBehavior>>();

    /**
     *
     * 获取某个自定义节点的所有行为列表
     *
     * @param configId  节点配置ID,这个配置ID就是描述自定义节点配置信息的json文件中定义的configId
     * @return          返回当前扩展程序定义的所有与configId相关的ActivityBehavior行为实例ID
     */
    public List<ActivityBehavior> getActivityBehaviors(String configId) {
        if("demospiactivity".equals(configId)){
            List<ActivityBehavior> list = new ArrayList<ActivityBehavior>();
            list.add(new DemoSPIActivityBehavior());
            return list;
        }
        return null;
    }

    /**
     *
     * 获取某个自定义节点参数配置的json文件信息
     *
     * @param configId 节点配置ID,这个配置ID就是描述自定义节点配置信息的json文件中定义的configId
     * @return         以字符串形式返回定义的json文件内容
     */
    public String getActivityConfiguration(String configId) {
        InputStream stream = DemoSpiActivityBehaviorFactoryImpl.class.getClassLoader().getResourceAsStream("config/DemoSpiActivity.json");
        String message = "";
        try{
            message = IOUtils.toString(stream, "UTF-8");
        }catch (IOException e) {
        }
        return message;
    }

    /**
     * 获取当前软件包定义了那些自定义节点信息
     * @return  返回一个列表,这个列表包含了所以该软件包定义的自定义节点的configId
     */
    public Set<String> supportActivities() {
        Set<String> set = new HashSet<String>();
        set.add("demospiactivity");
        return set;
    }

}
# com.seeyon.bpm.api.ext.activity.ActivityBehaviorFactory接口说明
方法名称 方法用途说明
getActivityBehaviors 根据自定义节点ID,获取某个自定义节点的所有行为列表
getActivityConfiguration 获取某个自定义节点参数配置的json文件信息
supportActivities 获取当前软件包定义了那些自定义节点信息
import com.seeyon.bpm.api.ext.activity.ActivityBehavior;
import com.seeyon.bpm.api.ext.activity.ActivityBehaviorChain;
import com.seeyon.bpm.api.ext.activity.BpmSupportOperation;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DemoSPIActivityBehavior implements ActivityBehavior {

    public String getConfigId() {
        return "demospiactivity";
    }

    /**
     *
     * @param bpmSupportOperation   BPM引擎交互接口
     * @param activityBehaviorChain         行为执行链
     * @return      true需要向下穿透,fase不需要
     */
    public boolean preMatch(BpmSupportOperation bpmSupportOperation, ActivityBehaviorChain activityBehaviorChain) {
        log.error("这里是预提交:{}", bpmSupportOperation.getCaseId());
        return true;
    }

    /**
     *
     * @param bpmSupportOperation   BPM引擎交互接口
     * @param activityBehaviorChain         行为执行链
     * @return      true表示节点有人处理,false表示接待没有人处理
     */
    public boolean onActivityReady(BpmSupportOperation bpmSupportOperation, ActivityBehaviorChain activityBehaviorChain) {
        log.error("这里节点激活了:{}", bpmSupportOperation.getCaseId());
        return false;
    }

    public boolean onActivityFinish(BpmSupportOperation bpmSupportOperation, ActivityBehaviorChain activityBehaviorChain) {
        log.error("这里节点处理完了:{}", bpmSupportOperation.getCaseId());
        return false;
    }

    public boolean onActivityCanceled(BpmSupportOperation bpmSupportOperation, ActivityBehaviorChain activityBehaviorChain) {
        log.error("这里节点撤销、回退、取回:{}", bpmSupportOperation.getCaseId());
        return false;
    }

    public boolean validateActivityAction(BpmSupportOperation bpmSupportOperation, ActivityBehaviorChain activityBehaviorChain) {
        log.error("保留方法,不实现:{}", bpmSupportOperation.getCaseId());
        return false;
    }

    public int compareTo(Object o) {
        return 0;
    }
}
# com.seeyon.bpm.api.ext.activity.ActivityBehavior接口说明
方法名称 方法用途说明
getConfigId 行为实现类对应的自定义节点ID,这里这个ID需要跟第一步中DemoActivity.json定义的ID匹配,并且需要与com.seeyon.bpm.api.ext.activity.ActivityBehavior.getConfigId返回值匹配
preMatch 流程流转前,预提交的处理方法,一般做一些人员匹配等逻辑,用以onActivityReady节点激活的时候使用
onActivityReady 当节点激活的时候,会调用该方法,用以修改节点状态、生成待办等逻辑
onActivityFinish 节点完成,准备激活下一个节点调用的方法
onActivityCanceled 节点取消是调用的方法,录入撤销、回退、取回会调用
validateActivityAction 该方法是保留方法,三方扩展不做实现

其中,接口方法中的com.seeyon.bpm.api.ext.activity.ActivityBehaviorChain类型参数,暂时不用,我们需要重点关注的是com.seeyon.bpm.api.ext.activity.BpmSupportOperation这个类型的入参,其中定义了自定义节点可以访问的数据以及可以操作的数据,说明如下:

#####数据获取接口:

接口名称 说明
getConfigId 获取当前交互接口操作的节点类型Id
getParameters 获取当前当前流程操作的流程列表
getConfigurationValue 获取自定义节点,在流程设计态时,由设计人员设置的所有节点自定义参数值
getAllConfigurationValues 获取自定义节点,在流程设计态时,由设计人员设置的所有自定义节点参数值
getCaseId 获取当前流程实例ID
getActivityId 获取当前操作的节点ID
getActivityPolicyId 获取当前节点操作权限ID
getAppName 流程类别标识:协同、表单、公文、信息报送(政务扩展)等(可根据业务模块扩展)
getTemplateId 获取模板ID
getFormRecordId 获取表单记录ID
getRootEntityName 获取流程的根实体ID
getApplicationName 获取应用名称
getSubject 获取当前流程标题
getStartUserId 获取当前用户ID
getCurrentUserId 获取流程发起者用户ID

#####数据修改接口:

接口名称 说明
setParameter 设置一个流程参数,其中输入参数为(String name, Object value),name为参数名称,value为参数值

# 2.1.4、定义自定义节点json文件

这里我们在resources目录下面创建一个config文件夹,并在其中创建一个DemoSpiActivity.json的json文件 #####文件位置: #####其内容如下:

{
  "configId": "demospiactivity",
  "ruleName": "SPIDEMO节点",
  "icon": "levelapproval",
  "addNodePage": {
    "componentType": "NodeProperty"
  },
  "settings": [{
    "children": [{
      "name": "name",
      "caption": "名称",
      "componentType": "Input"
    }]
  }]
}
# 其中json定义中的相关参数说明// todo 这里的JSON文件描述,需要全量的描述 :
参数 名称 说明 备注
configId 配置ID 节点配置唯一标识 整个系统用于唯一标识一个自定义节点定义的ID,不能重复,如果重复系统启动会提示报错
ruleName 节点名称 节点在设计器中显示的名称 名称定义支持国际化,需要在bpm内部的i18n文件中实现定义,外部扩展包暂不支持自定义
icon 节点图标 节点在设计器中的显示图标 【待优化】该icon需要在bpm内部前端预先定义
addNodePage 设置页面弹窗 直接填写NodeProperty 直接填写NodeProperty
settings 节点属性列表 定义节点的部分参数信息 如:节点名称、节点code、或者一些其他的自定义属性
settings[n].children 节点第n个属性设置 节点第n个属性设置 定义每个属性的详细配置
settings[n].children[m].name 属性名称 属性的参数名称,用于取值 属性的参数名称,用于取值
settings[n].children[m].caption 属性的显示名称 属性显示在设置页面的名称 属性显示在设置页面的名称
settings[n].children[m].componentType 属性组件类型 该组件类型由BPM预先内置,不能自定义 如:文本框(Input)、节点参与者(SelectNodeHandlerNew)、单选(Select)等

# 2.1.5、定义SPI描述文件

基于V8平台统一的SPI集成机制,我们在工程resources目录下面创建META-INF目录,并创建文件spring.factories。 #####文件位置: #####内容如下:

com.seeyon.bpm.api.ext.activity.ActivityBehaviorFactory=com.seeyon.bpm.domain.model.business.behavior.demo.DemoSpiActivityBehaviorFactoryImpl

# 2.1.6、将工程打包

# 2.2、开始集成

依据V8平台SPI统一集成规则,可以将2.1中制作的jar上传到maven仓库,或者oss,亦或者直接上传到bpm容器进行本地集成,然后配置bpm的nacos文件,配置形式如下: application.yaml

seeyon:
  spi:
    enable: true # 是否启用
    spi-plugins:
      - maven:com.seeyon,xxx-spi-providers,1.0.0 # 定义SPI接口实现的jar包maven GAV坐标,格式:maven:group,artifactId,version
      - file:/var/spi/demo-order/xxx.jar # 定义SPI接口实现的jar包的存放路径,格式:file:jar包的文件路径(window路径目录之间也是用/连接)

# 2.3、设计态验证集成效果&运行态验证

配置2.2步骤后,我们可以到bpm后台设计态中,"SPIDEMO节点"会自动添加到"人工节点"列表下面,效果如下:

# 设计态配置流程图:

# 发布应用后运行态发送

后台日志: 发送后,待办查看流程图: 至此,我们完成了一个简单的自定义节点的开发工作。

编撰人:wensl、cgjun、shugang