Solon v3.0.9

solon-flow

</> markdown

此插件也可用于非 solon 生态。具体开发学习,可参考:《学习 / Solon Flow 开发》

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-flow</artifactId>
</dependency>

1、描述

(v3.0.7 后支持)基础扩展插件,为 Solon Flow 开发提供基础的流引擎能力(可用于业务规则、决策处理、计算编排、流程审批等...)。提供有 “开放式” 驱动定制支持,像 jdbc 有 mysql 或 pgsql 等驱动。

可用于:

  • 决策型的场景(替代一堆的 if/else)
  • 编排型的场景
  • 审批型(有状态、可中断)的场景(比如办公审批。需要定制驱动器

主要元素:

  • 链、节点(可带任务)、连接(可带条件)
  • 链上下文、链驱动器、任务组件接口(TaskComponent)、条件组件接口(ConditionComponent)
  • 流引擎

主要定义(就像用工具画图):

  • 一个链(Chain),会有多个节点(Node)组成。
  • 一个节点(Node),会有多个连接(Link,也叫“流出连接”)连向别的节点。
  • 连接向其它节点,称为:流出连接。被其它节点连接,称为:流入连接。
  • 一个链“必须有且只有”一个 start 类型的节点,且从 start 节点开始,顺着连接(Link)流出。
  • 链的流转过程,可以有上下文参数(ChainContext),可以被中断(可支持有状态的审批模式)

通俗些,就是通过 “点”(节点) + “线”(连接)来描述一个流程图结构。

2、配置字典参考

  • Chain 配置属性
属性数据类型需求描述
idString必填链Id(要求全局唯一)
titleString 显示标题
driverString 驱动器(缺省为默认驱动器)
metaMap 元信息(用于应用扩展)
nodesNode[] 节点集合
  • Node ,配置属性(驻 start,end, execute 类型节点,支持 task 配置)
属性数据类型需求描述
idString 节点Id(要求链内唯一)
//不配置时,会自动生成
typeNodeType 节点类型
//不配置时,缺省为 execute 类型
titleString 显示标题
metaMap 元信息(用于应用扩展)
linkString or Link
String[] or Link[]
连接(支持单值、多值)
//不配置时,会自动生成
taskString 任务描述(会触发驱动的 handleTask 处理)
whenString 执行任务条件描述(会触发驱动的 handleTest 处理)

link 全写配置风格为 Link 类型结构;简写配置风格为 Link 的 nextId 值(即 String 类型)

  • Link 配置属性
属性数据类型需求描述
nextIdString必填后面的节点Id
titleString 显示标题
metaMap 元信息(用于应用扩展)
conditionString 流出条件描述(会触发驱动的 handleTest 处理)
  • 节点类型(NodeType 枚举成员)
描述任务连接条件可流入
连接数
可流出
连接数
图例参考
start开始//01
execute执行节点(缺省类型)可有/1...n1
inclusive包容网关/支持1...n1...n
exclusive排它网关/支持1...n1...n
parallel并行网关//1...n1...n
end结束//1...n0

配置示例(支持 yml 或 json):

# demo1.chain.yml(完整模式)
id: "c1"
nodes: 
  - { id: "n1", type: "start", link: "n2"}
  - { id: "n2", type: "execute", link: "n3", task: "System.out.println(\"hello world!\");"}
  - { id: "n3", type: "end"}


# demo1.chain.yml(简化模式)
id: "c1"
nodes: 
  - { type: "start"}
  - { task: "System.out.println(\"hello world!\");"}
  - { type: "end"}

3、链配置的简化模式说明

属性简化:

  • 当没有 id 属性时,会按顺序自动生成(格式示例:"n-1")
  • 当没有 link 属性时,会按顺序自动链接后一个节点
  • 当没有 type 属性时,缺省为 execute 节点类型

节点简化:

  • 当没有 type=start 节点时,按顺序第一个节点为开始节点
  • 当没有 type=end 节点时,不影响执行

4、 主要接口参考

链的流动是由“链引擎”驱动的,也称为:执行。“链引擎”在执行链时,会涉及到“链上下文”(提供执行时的上下文参数与对象引用),以及可以定制的“链驱动器”。

  • 链上下文接口(ChainContext)
返回数据类型描述
isInterrupted()bool是否已中断
interrupt() 中断流转
engine()FlowEngine当前引擎实例(驱动定制时,用于跨链调用)
model()Map参数集合
put(key, value)self参数设置
putAll(model)self参数设置
get(key)T参数获取
getOrDefault(key, def)T参数默认
resultObject执行结果(执行中可赋值)
  • 链驱动器接口(ChainDriver),可自由定制
返回数据类型描述
onNodeStart(context, node) 节点开始时
onNodeEnd(context, node) 节点结束时
handleTest(context, condition)bool处理条件检测
handleTask(context, task) 处理执行任务

5、节点任务与连接条件

节点任务与连接条件的描述,采用开放格式(即没有格式约定)。格式由 ChainDriver 处理(或约定),使用哪个 ChainDriver 就采用哪个格式约定。就像 jdbc 的 Driver, mysql 和 pgsql 的语法即不同。

5.1、默认格式(SimpleChainDriver 方案,框架内置):

示例
任务描述@t(任务组件风格) 或者 context.result=1; (java 脚本风格) 或者 #c12(链调用风格)
条件描述user_id > 12(java 脚本表达式风格。要求结果为布尔值)
  • 组件风格
@Component("t") //节点任务组件
public class TaskComponentT implements TaskComponent {
    @Override
    public void run(ChainContext context, Node node) throws Throwable {
        
    }
}
  • 脚本风格

SimpleChainDriver 的脚本能力,由 Liquor 提供。contextcontext.model() 里的变量在脚本里可直接使用。

//任务脚本(示例1)//完整的 java 代码
context.result=1;

//任务脚本(示例2)//完整的 java 代码
if(order_id > 0) { //order_id 即为模型里的变量: context.get("order_id")
    System.out.println("订单号: " + order_id);
}

//===================

//条件脚本(示例1)//产生一个布尔结果
user_id > 12 //user_id 即为模型里的变量: context.get("user_id")

5.2、定制格式参考(RubberChainDriver 方案,第三方的):

示例
任务描述F,tag/fun1;R,tag/rule1(dsl 风格)
条件描述m.user_id,>,12,A;m,F,$ssss(m),E(dsl 风格)

6、简单应用示例

参考: 《学习 / Solon Flow 开发 / Hello World》