1. Introduction

1.1. 翻译(说明)

由[分享牛Flowable中国社区] 翻译,任何意见建议,欢迎联系QQ:3152981878。 如果想一起成为开源代码贡献人员,欢迎大家加入qq交流群为社区贡献添砖加瓦。qq贡献群:1023773998

1.2. 协议

Flowable在Apache V2 协议下发布。

1.4. 源码

Flowable的发布包里包含了大部分源码,以JAR文件方式提供。Flowable的源码也可以通过以下链接获得: https://github.com/flowable/flowable-engine

1.5. 必要的软件

1.5.1. JDK 8+

运行Flowable需要JDK 8或以上版本。可以访问 Oracle Java SE downloads页面 点击“Download JDK”按钮获取。该页面上也有安装指导。安装完成后,可以执行 java -version 。能看到JDK的版本信息就说明安装成功了。

1.5.2. IDE

可以自行选择用于Flowable开发的IDE。如果想要使用Flowable Designer,则需要Eclipse Mars或Neon。 到 Eclipse下载页面选择Eclipse版本并下载。解压下载的文件, 然后执行eclipse文件夹下的eclipse文件。手册后续有专门一章介绍如何安装我们的Eclipse Designer插件

1.6. 反馈问题

我们希望开发者在报告或提问之前,先看看提问的智慧

看完提问的智慧,你可以在用户论坛提问、评论以及提交改进建议,也可以在我们的Github问题跟踪系统创建bug报告。

1.7. 实验性功能

标记有[实验性]的章节介绍的功能还不够稳定。

.impl.包下的类都是内部实现类,不保证稳定。但是,在用户手册中作为配置参数介绍的类则是被官方支持的,可以保证稳定。

1.8. 内部实现类

在JAR文件中,所有.impl.包下的类(比如org.flowable.engine.impl.db)都是实现类,只应在内部使用。实现类中的所有类或接口都不保证稳定。

1.9. 版本策略

使用三个整数的形式标记版本:MAJOR.MINOR.MICRO。其中 MAJOR版本代表核心引擎的演进。MINOR版本代表新功能与新API。MICRO版本代表bug修复与改进。

总的来说,Flowable希望在MINORMICRO版本中,对所有非内部实现类保持“源代码兼容性”,即应用可以正确构建,且不改变语义。Flowable也希望在MINORMICRO版本中,保持“二进制兼容性”,即用新版本的Flowable直接替换老版本的Jar文件,仍然可以正常工作。

如果在MINOR版本中修改了API,将保留原有版本,并使用@Deprecated注解。这种废弃的API将在两个MINOR版本之后移除。

2. 配置

2.1. 创建 DMN 引擎

Flowable DMN 引擎的构造方式和 Flowable 工作流引擎非常相似。因此,部分文档非常类似流程引擎的相应内容。

Flowable DMN 引擎是通过名为 flowable.dmn.cfg.xml 的XML文件进行配置的。请注意,如果你使用 Spring 风格构建 DMN 引擎,则不适用。

获取一个 DmnEngine 的最简单的方式是使用 org.flowable.dmn.engine.DmnEngines 类:

1
DmnEngine dmnEngine = DMNEngines.getDefaultDmnEngine()

上述代码将会从classpath寻找 flowable.dmn.cfg.xml 文件,并根据文件中的配置构造引擎。下面的代码片段展示了实例配置。后续章节将详细介绍配置属性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration">

    <property name="jdbcUrl" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
    <property name="jdbcDriver" value="org.h2.Driver" />
    <property name="jdbcUsername" value="sa" />
    <property name="jdbcPassword" value="" />

    <property name="databaseSchemaUpdate" value="true" />

    <property name="strictMode" value="false"/>

  </bean>

</beans>

可以注意到这个 XML 配置实际上是个 Spring 配置。 这并不代表 Flowable DMN 只能在 Spring 环境中使用! 我们只是在内部借助 Spring 的解析和依赖注入能力来构建引擎。

也可以通过编程的方式使用配置文件创建 DMNEngineConfiguration 对象。也可以使用不同的 bean ID(比如第三行)。

1
2
3
4
5
6
DmnEngineConfiguration.
  createDmnEngineConfigurationFromResourceDefault();
  createDmnEngineConfigurationFromResource(String resource);
  createDmnEngineConfigurationFromResource(String resource, String beanName);
  createDmnEngineConfigurationFromInputStream(InputStream inputStream);
  createDmnEngineConfigurationFromInputStream(InputStream inputStream, String beanName);

不使用配置文件也是可行的,这将基于默认值创建配置(更多信息请参阅 已支持的其他配置类 )。

1
2
DmnEngineConfiguration.createStandaloneDmnEngineConfiguration();
DmnEngineConfiguration.createStandaloneInMemDmnEngineConfiguration();

所有的 DmnEngineConfiguration.createXXX() 方法返回一个可做进一步调整的 DmnEngineConfiguration 。调用 buildDmnEngine() 方法之后将创建一个 DmnEngine

1
2
3
4
DmnEngine dmnEngine = DmnEngineConfiguration.createStandaloneInMemDmnEngineConfiguration()
  .setDatabaseSchemaUpdate(DmnEngineConfiguration.DB_SCHEMA_UPDATE_FALSE)
  .setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000")
  .buildDmnEngine();

2.2. DmnEngineConfiguration bean

flowable.dmn.cfg.xml 必须包含一个 ID 为 'dmnEngineConfiguration' 的 bean。

1
 <bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration">

这个 bean 将被用于构造 DmnEngine。有多个可选的类可以用来定义 dmnEngineConfiguration。这些类代表了不同的环境,并根据环境设置相应的默认值。最佳方式是选择最符合你的环境的类,尽可能地减少配置引擎所需要的属性。目前有下面这些类可供使用:

  • org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration: 引擎以单机方式运行。Flowable 将自行处理事务。默认情况下,仅在引擎启动时检查数据库(如果 Flowable DMN 相关表不存在,或者版本不正确,将抛出异常)。

  • org.flowable.dmn.engine.impl.cfg.StandaloneInMemDmnEngineConfiguration: 这是一个方便进行单元测试的类。Flowable DMN 将自行处理事务。默认使用 H2 内存数据库。数据库将随着引擎的启动和关闭进行创建和销毁。使用此类时一般无需进行额外配置。

  • org.flowable.dmn.spring.SpringDmnEngineConfiguration: 在 Spring 环境中使用 DMN 引擎时使用此类。详见 与 Spring 集成章节

2.3. 植入到流程引擎

除了以独立方式运行,DMN 引擎还可以植入到流程引擎中。这使得流程引擎能够识别它和其他引擎。例如,除了 BPMN 模型,还可以将 DMN 模型部署到流程引擎部署服务 API。

要让流程引擎能够识别出 DMN 引擎,需要在流程引擎配置中将 org.flowable.dmn.engine.configurator.DmnEngineConfigurator 添加到流程引擎配置 bean 的 configurators list 中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration">
    <property name="jdbcUrl" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
    <property name="jdbcDriver" value="org.h2.Driver" />
    <property name="jdbcUsername" value="sa" />
    <property name="jdbcPassword" value="" />
    ...
</bean>

<bean id="dmnEngineConfigurator" class="org.flowable.dmn.engine.configurator.DmnEngineConfigurator">
    <property name="dmnEngineConfiguration" ref="dmnEngineConfiguration" />
</bean>

<bean id="processEngineConfiguration" class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    <property name="configurators">
      <list>
        <ref bean="dmnEngineConfigurator" />
      </list>
    </property>
    ...
</bean>

2.4. 数据库配置

Flowable DMN 引擎有两种方式进行数据库配置。第一种方式是定义数据库的 JDBC 属性:

  • jdbcUrl: 数据库的 JDBC Url。

  • jdbcDriver: 特定类型数据库的驱动。

  • jdbcUsername: 连接数据库所使用的用户名。

  • jdbcPassword: 连接数据库所使用的密码。

基于所提供的 JDBC 属性构造的数据源将使用默认的 MyBatis 连接池设置。下面这些可选属性可以用来对连接池进行调整(引自 Mybatis 文档):

  • jdbcMaxActiveConnections: 连接池在任意时间可以持有的最大活动连接数。

  • jdbcMaxIdleConnections: 连接池在任意时间可以持有的最大空闲连接数。

  • jdbcMaxCheckoutTime: 在被强制返回之前,连接池中的连接可被“借用”的时长(以毫秒为单位)。默认值是20000(20秒)。

  • jdbcMaxWaitTime: 这是一个低级别设置,使池有机会打印日志状态,并在获取连接耗时太久时进行重新尝试(以避免池配置错误时永远静默地失败)。默认值是20000(20秒)。

示例数据库配置:

1
2
3
4
<property name="jdbcUrl" value="jdbc:h2:mem:flowable_dmn;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />

我们的跑分显示 MyBatis 的连接池在处理大量并发请求时不是最高效的。因此,建议使用 javax.sql.DataSource 的实现(比如 HikariCP、Tomcat JDBC 连接池、等等),并将其注入到引擎配置中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/flowable_dmn" />
  <property name="username" value="flowable" />
  <property name="password" value="flowable" />
  <property name="defaultAutoCommit" value="false" />
</bean>

<bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration">

    <property name="dataSource" ref="dataSource" />
    ...

要注意的是 Flowable DMN 并不自带定义这种数据源所需要的类库,所以你要确保这些类库在你的classpath中。

无论你使用 JDBC 或数据源方式,都可以设置以下属性:

  • databaseType:一般情况下能从数据库连接中自动识别出来,没必要手工指定。应该仅当自动识别失败时指定。可选的值有:{h2、mysql、oracle、postgres、mssql、db2}。这项设置将决定使用哪些 create/drop 脚本。参见 “支持的数据库”章节 了解已支持哪些类型的数据库。

  • databaseSchemaUpdate:用来设置引擎启动和关闭时数据库表的操作策略。

    • false (默认):在创建引擎时检查数据库表的版本,如果不匹配则抛出异常。

    • true:在构建引擎时进行检查,并在必要时更新数据库表。如果表不存在,则创建。

    • create-drop:引擎创建时创建表,引擎关闭时删除表。

2.5. JNDI 数据源配置

默认情况下,Flowable DMN 的数据库配置包含在每个 web 应用的 WEB-INF/classes 下的 db.properties 文件中。但是这样并不理想,因为它使得用户要么修改 Flowable 代码中的 db.properties 并重新编译 WAR 文件,要么在每一次项目部署时解压 WAR 并修改 db.properties。

通过 JNDI (Java Naming and Directory Interface)获取数据库连接,这个连接将完全由 Servlet 容器管理,且配置可以在 war 包外部进行管理。而且相比 db.properties 文件,这种方式还能对连接参数进行更多的控制。

2.5.1. 配置

JNDI 数据源的配置将视你所使用的 servlet 容器而有所不同。下面的说明适用于 Tomcat,至于其他的容器,请参阅各容器的文档。

如果使用 Tomcat,JNDI 资源配置在 $CATALINA_BASE/conf/[enginename]/[hostname]/[warname].xml 中(Flowable UI 的配置通常在 $CATALINA_BASE/conf/Catalina/localhost/flowable-app.xml)。默认的 context 是在应用初次部署时从 Flowable WAR 文件中复制过来的,所以如果已经存在的话你需要进行替换。比如,要使用 MySql 而不是 H2,可如下修改 JNDI 资源:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
    <Context antiJARLocking="true" path="/flowable-app">
        <Resource auth="Container"
            name="jdbc/flowableDB"
            type="javax.sql.DataSource"
            description="JDBC DataSource"
            url="jdbc:mysql://localhost:3306/flowable"
            driverClassName="com.mysql.jdbc.Driver"
            username="sa"
            password=""
            defaultAutoCommit="false"
            initialSize="5"
            maxWait="5000"
            maxActive="120"
            maxIdle="5"/>
        </Context>

2.5.2. JNDI 属性

要配置 JNDI 数据源,使用下面这些 Flowable UI 的 properties 文件中的属性:

  • spring.datasource.jndi-name=:数据源的 JNDI 名称。

  • datasource.jndi.resourceRef:设置查询是否发生在 J2EE 容器中,换句话说,JNDI 名称中不包含前缀“java:comp/env/”时是否要把它加上。默认“true”。

2.6. 支持的数据库

下面列出了 Flowable 所使用的数据库的类型(区分大小写!)。

Flowable DMN 数据库类型 JDBC URL 示例 备注

h2

jdbc:h2:tcp://localhost/flowable_dmn

默认数据库

mysql

jdbc:mysql://localhost:3306/flowable_dmn?autoReconnect=true

已使用 mysql-connector-java 数据库驱动进行测试

oracle

jdbc:oracle:thin:@localhost:1521:xe

postgres

jdbc:postgresql://localhost:5432/flowable_dmn

db2

jdbc:db2://localhost:50000/flowable_dmn

mssql

jdbc:sqlserver://localhost:1433;databaseName=flowable_dmn (jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver) OR jdbc:jtds:sqlserver://localhost:1433/flowable_dmn (jdbc.driver=net.sourceforge.jtds.jdbc.Driver)

已使用 Microsoft JDBC Driver 4.0(sqljdbc4.jar)和 JTDS 驱动进行测试

2.7. 创建数据库表

Flowable DMN 使用 Liquibase 跟踪、管理和应用数据库表的变更。

创建数据库表的最简单的方式是:

  • 将 flowable-dmn-engine 相关JAR包添加到 classpath

  • 添加合适的数据库驱动

  • 添加 Flowable 配置文件(flowable.dmn.cfg.xml)到 classpath,指向你的数据库(参阅 “数据库配置”章节

  • 执行 DbSchemaCreate 类的 main 方法

2.8. 数据库表名称说明

Flowable DMN 的表名全部以 ACT_DMN_ 开头。

  • ACT_DMN_DATABASECHANGELOG:此表用于 Liquibase 对已运行的变更进行追踪。

  • ACT_DMN_DATABASECHANGELOGLOCK:此表用于 Liquibase 确保同时只有一个 Liquibase 实例在运行。

  • ACT_DMN_DECISION_TABLE:此表包含了已部署的决策表的元数据。

  • ACT_DMN_DEPLOYMENT:此表包含了每次部署行为的元数据。

  • ACT_DMN_DEPLOYMENT_RESOURCE:此表包含了 DMN 定义的资源和元数据。

2.9. 数据库升级

请确保在升级前已对数据库进行备份。

每当引擎被创建时默认都会进行版本检查。版本检查通常在你的应用程序或者 Flowable web 应用启动时发生。如果 Flowable 库发现库版本和数据库表版本不同,则抛出异常。

要进行升级,你首先需要在 flowable.dmn.cfg.xml 配置文件中加入如下配置属性:

1
2
3
4
5
6
7
8
9
<beans >

  <bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration">
    <!-- ... -->
    <property name="databaseSchemaUpdate" value="true" />
    <!-- ... -->
  </bean>

</beans>

另外,在classpath中引入适合你数据库的驱动。 升级应用程序中的 Flowable DMN 类库,或者启动一个新版本的 Flowable DMN 并将其指向旧版本的数据库。当 databaseSchemaUpdate 设置为 true 时,Flowable DMN 将会在首次发现类库版本和数据库表版本不同时升级到新版本。

2.10. 部署缓存配置

为了避免每次需要决策表时都去访问数据库,同时也因为决策表不会改变,所有的决策都是被缓存的(在它们经过解析之后)。缓存默认是没有限制的。可添加如下属性对决策缓存进行限制:

1
<property name="decisionCacheLimit" value="10" />

这项设置将使用给定了硬性限制的 LRU 缓存替代默认的 hashmap 缓存。当然,最合适的取值取决于决策总数以及运行时实际使用到的决策数。

你还可以注入你自己的缓存实现。必须是一个实现了 org.flowable.dmn.engine.impl.persistence.deploy.DeploymentCache 接口的 bean:

1
2
3
<property name="decisionCache">
  <bean class="org.flowable.MyCache" />
</property>

2.11. 严格模式

严格模式是默认 启用 的。就是说命中策略(hit policies)将按照 DMN 1.1 标准执行。也可以禁用严格模式。

1
2
3
4
5
6
7
8
9
<beans>

  <bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration">
    <!-- ... -->
      <property name="strictMode" value="false"/>
    <!-- ... -->
  </bean>

</beans>

这样做的影响是违反了命中策略约束时,结果不会作废。可能的违规将被作为验证信息记录到审核日志中。

2.12. 自定义 Flowable 函数委托(Function Delegates)

Flowable DMN 内置了一些 JUEL 函数委托。通过设置 dmnEngineConfiguration bean 的 customFlowableFunctionDelegates 属性,你可以使用自己的实现。这些(函数委托)可以在表达式(expressions)中执行你自己的逻辑。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<beans>

  <bean id="dmnEngineConfiguration" class="org.flowable.dmn.engine.impl.cfg.StandaloneDmnEngineConfiguration">
    <!-- ... -->
    <property name="customFlowableFunctionDelegates">
      <list>
          <bean ref="myOwnFunctionDelegateOne" />
          <bean ref="myOwnFunctionDelegateTwo" />
      </list>
    </property>
    <!-- ... -->
  </bean>

  <bean id="myOwnFunctionDelegateOne" class="org.acme.MyOwnFunctionDelegateOne" />
  <bean id="myOwnFunctionDelegateTwo" class="org.acme.MyOwnFunctionDelegateTwo" />

</beans>

请注意,自定义函数委托必须继承自 org.flowable.engine.common.impl.el.AbstractFlowableFunctionDelegate。

2.13. 日志

所有日志(flowable、spring、mybatis、…​)都通过 slf4j 门面进行记录,所以你可以自行选择日志框架。

flowable 引擎依赖项中默认没有包含具体的日志实现框架;你应该将你选择的日志框架添加到你的项目中。 如果没有引入日志实现框架的 jar 包,slf4j 不会记录任何日志,只会给出一个不会记录任何内容的警告。

举个例子,使用 maven 时,像这样添加依赖(以使用 log4j 为例),请注意这里省略了版本:

1
2
3
4
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
</dependency>

flowable-ui 和 flowable-rest webapps 使用 log4j。运行所有的 flowable-* mudules 测试时同样使用 log4j。

所用容器的 classpath 中带有 commons-logging 时的重要注意事项: 为了能通过 slf4j 能调用到 spring-logging,使用了一个桥(a bridge is used)(详见 http://www.slf4j.org/legacy.html#jclOverSLF4J)。如果你的容器提供了 commons-logging 实现,请按此页面的说明进行操作,以确保稳定:http://www.slf4j.org/codes.html#release

Maven 示例(忽略了版本):

1
2
3
4
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
</dependency>

3. Flowable DMN API

3.1. DMN引擎API和服务

DMN引擎API是与Flowable DMN交互的最常见方式。中心起点是DmnEngine,可以通过configuration section部分中描述的多种方式创建。从DmnEngine中,您可以获得各种其他服务。

DmnEngine和服务对象是线程安全的。因此,您可以为整个服务器保留对其中一个的引用。

1
2
3
4
DmnEngine dmnEngine = DmnEngines.getDefaultDmnEngine();
DmnRuleService dmnRuleService = dmnEngine.getDmnRuleService();
DmnRepositoryService dmnRepositoryService = dmnEngine.getDmnRepositoryService();
DmnManagementService dmnManagementService = dmnEngine.getDmnManagementService();

DmnEngines.getDefaultDmnEngine() 将在第一次调用时初始化并构建DMN引擎,之后始终返回相同的DMN引擎。 可以使用适当的DMNEngines.init()创建和DMNEngines.destroy()关闭所有DMN引擎。

DmnEngines类将扫描所有 flowable.dmn.cfg.xmlflowable-dmn-context.xml 文件。对所有 flowable.dmn.cfg.xml 文件, DMN引擎将以典型的Flowable方式构建:DmnEngineConfiguration.createDmnEngineConfigurationFromInputStream(inputStream).buildDmnEngine(). 对所有 flowable-dmn-context.xml 文件,DMN引擎将以Spring方式构建: 首先创建Spring应用程序上下文,然后从该应用程序上下文中获取DMN引擎。

所有服务都是无状态的。这意味着您可以在群集中的多个节点上轻松运行Flowable DMN,每个都进入同一个数据库,而不必担心哪台机器实际执行了以前的调用。对任何服务的任何调用都是幂等的,无论它在何处执行。

DmnRepositoryService可能是使用Flowable DMN引擎时所需的第一个服务。此服务提供用于管理、操作部署和DMN定义的操作。 DMN定义是DMN模型的根本概念(DMN的主要概念在<dmn-introduction, DMN introduction section>中有解释). 它包含决策的定义(及其决策表)。 部署是Flowable DMN引擎中的打包的单位。部署可以包含多个DMN XML文件。 发布部署意味着将其部署到引擎表,在存储到数据库中之前检查和解析所有DMN定义。从那时起,系统就知道部署,现在可以执行部署中包含的任何决策。

此外,此服务允许您:

  • 查询引擎已知的部署,DMN定义和决策表。

  • 检索可用于使用Java而不是XML进行内省的DMN定义或决策表的POJO版本。

DmnRuleService 提供了执行决策的方法。通过提供参数和输入数据,可以开始评估决策。

使用Flowable DMN编写自定义应用程序时,通常不需要 DmnManagementService 。 它允许您检索有关引擎版本,数据库表和表元数据的信息。

有关服务操作和DMN引擎API的更多详细信息,查看链接:http://www.flowable.org/docs/javadocs/index.html[the javadocs].

3.2. 异常策略

Flowable中的基本异常是 org.flowable.engine.FlowableException,一个 unchecked 异常。 API可以随时抛出此异常,但在特定方法中发生的“预期”异常将记录在链接:http://www.flowable.org/docs/javadocs/index.html[ the javadocs]. 例如, 来自 DmnRuleService 的提取物:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/**
  * Execute a decision identified by it's key.
  *
  * @param  decisionKey      the decision key, cannot be null
  * @param  inputVariables   map with input variables
  * @return                  the {@link RuleEngineExecutionResult} for this execution
  * @throws FlowableObjectNotFoundException
  *            when the decision with given key does not exist.
  * @throws FlowableException
  *           when an error occurs while executing the decision.
  */
RuleEngineExecutionResult executeDecisionByKey(String decisionKey, Map<String, Object> inputVariables);

在上面的示例中,当传递的密钥没有任何决策时,将抛出异常。此外,由于javadoc 明确声明decisionKey不能为null,当传递null时,将抛出 FlowableIllegalArgumentException

即使我们想要避免一个大的异常层次结构,在特定情况下会抛出以下子类。在流程执行或API调用期间发生的所有其他错误都不符合以下可能的异常,这些错误将作为常规 FlowableExceptions 抛出。

  • FlowableOptimisticLockingException: 在由同一数据条目的并发访问引起的数据存储中发生乐观锁定时抛出。

  • FlowableClassLoadingException: 未找到请求加载的类或加载时发生错误时抛出。

  • FlowableObjectNotFoundException: 当请求或操作的对象不存在时抛出。

  • FlowableIllegalArgumentException: 指示在Flowable DMN API调用中提供了非法参数的异常,在引擎的配置中配置了非法值,或者提供了非法值。

3.3. 查询 API

有两种方法可以从引擎查询数据:查询API和本机查询。 Query API允许使用流畅的API对完全类型安全的查询进行编程。您可以为查询添加各种条件(所有这些条件作为逻辑AND一起应用)并且恰好是一个排序。以下代码显示了一个示例:

1
2
3
4
List<DmnDeployment> dmnDeployments = dmnRepositoryService.createDeploymentQuery()
    .deploymentNameLike("deployment%")
    .orderByDeployTime()
    .list();

有时您需要更强大的查询,例如,使用OR运算符的查询或使用Query API无法表达的限制。对于这些情况,我们引入了本机查询,允许您编写自己的SQL查询。返回类型由您使用的Query对象定义,数据映射到正确的对象,例如Deployment,ProcessInstance,Execution等。由于查询将在数据库中触发,因此必须使用在数据库中定义的表名和列名;这需要一些有关内部数据结构的知识,建议您谨慎使用本机查询。可以通过API检索表名,以使依赖性尽可能小。

1
2
3
4
5
6
7
8

long count = dmnRepositoryService.createNativeDeploymentQuery()
    .sql("SELECT count(*) FROM " + dmnManagementService.getTableName(DmnDeploymentEntity.class) + " D1, "
        + dmnManagementService.getTableName(DecisionTableEntity.class) + " D2 "
        + "WHERE D1.ID_ = D2.DEPLOYMENT_ID_ "
        + "AND D1.ID_ = #{deploymentId}")
    .parameter("deploymentId", deployment.getId())
    .count();

3.4. 单元测试

由于Flowable DMN是一个可嵌入的Java引擎,因此编写DMN定义的单元测试就像编写常规单元测试一样简单。

Flowable支持JUnit版本4和5样式的单元测试。

在JUnit 5样式中,需要使用 org.flowable.dmn.engine.test.FlowableDmnTest 注解 或手动注册 org.flowable.dmn.engine.test.FlowableDmnExtension 。 FlowableDmnTest 注解只是一个元注解,并且注册了 FlowableDmnExtension (即 @ExtendWith(FlowableDmnExtension.class)). 这将使DmnEngine和服务可用作测试和生命周期方法的参数 (@BeforeAll, @BeforeEach, @AfterEach, @AfterAll). 在每次测试之前,默认情况下将使用类路径上的 flowable.dmn.cfg.xml 资源初始化dmnEngine。 为了指定不同的配置文件需要使用org.flowable.dmn.engine.test.DmnConfigurationResource 注解(参见第二个例子)。 当配置资源相同时,Dmn引擎将在多个单元测试中静态缓存。

通过使用 FlowableDmnExtension ,您可以在测试方法上使用 org.flowable.dmn.engine.test.DmnDeployment 注解或 org.flowable.dmn.engine.test.DmnDeploymentAnnotation 注解。 如果同时使用 @DmnDeployment 和 @DmnDeploymentAnnotatio 那么 @DmnDeployment 优先,@DmnDeploymentAnnotation 将被忽略。 在测试方法上使用 @DmnDeployment 注解时,在每次测试之前,将部署 DmnDeployment#resources 中定义的dmn文件。 如果没有定义资源,则为 testClassName.testMethod.dmn 形式的资源文件,将在与测试类相同的包中进行部署。 在测试结束时,部署将被删除,包括所有相关的dmn定义,执行等。 有关更多信息,请参阅 DmnDeployment 类。

考虑到所有这些,JUnit 5测试看起来如下:

使用默认资源进行JUnit 5测试
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@FlowableDmnTest
class MyDecisionTableTest {

  @Test
  @DmnDeploymentAnnotation
  void simpleDmnTest(DmnEngine dmnEngine) {
    DmnRuleService dmnRuleService = dmnEngine.getDmnRuleService();

    Map<String, Object> executionResult = ruleService.createExecuteDecisionBuilder()
            .decisionKey("extensionUsage")
            .variable("inputVariable1", 2)
            .variable("inputVariable2", "test2")
            .executeWithSingleResult();

    Assertions.assertThat(executionResult).containsEntry("output1", "test1");
  }
}
使用JUnit 5,您还可以将部署的ID(带有org.flowable.dmn.engine.test.DmnDeploymentId_)注入到测试和生命周期方法中。
使用自定义资源进行JUnit 5测试
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@FlowableDmnTest
@DmnConfigurationResource("flowable.custom.dmn.cfg.xml")
class MyDecisionTableTest {

  @Test
  @DmnDeploymentAnnotation
  void simpleDmnTest(DmnEngine dmnEngine) {
    DmnRuleService dmnRuleService = dmnEngine.getDmnRuleService();

    Map<String, Object> executionResult = ruleService.createExecuteDecisionBuilder()
            .decisionKey("extensionUsage")
            .variable("inputVariable1", 2)
            .variable("inputVariable2", "test2")
            .executeWithSingleResult();

    Assertions.assertThat(executionResult).containsEntry("output1", "test1");
  }
}

在编写JUnit 4单元测试时,可以使用 org.flowable.dmn.engine.test.FlowableDmnRule 规则。通过此规则,DMN引擎和服务可通过getter获得。包含此 Rule 将启用注解 org.flowable.dmn.engine.test.DmnDeploymentAnnotation (请参阅上文,了解其使用和配置) 它将在类路径中查找默认配置文件。 当使用相同的配置资源时,DMN引擎可以在多个单元测试中静态缓存。 也可以为规则提供自定义引擎配置。

以下代码片段显示了使用JUnit 4测试样式和 FlowableDmnRule 的用法的示例(并传递可选的自定义配置):

JUnit 4 test
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public class MyDecisionTableTest {

  @Rule
  public FlowableDmnRule flowableDmnRule = new FlowableDmnRule("custom1.flowable.dmn.cfg.xml");

  @Test
  @DmnDeploymentAnnotation
  public void ruleUsageExample() {
    DmnEngine dmnEngine = flowableDmnRule.getDmnEngine();
    DmnRuleService dmnRuleService = dmnEngine.getDmnRuleService();

    Map<String, Object> executionResult = ruleService.createExecuteDecisionBuilder()
            .decisionKey("extensionUsage")
            .variable("inputVariable1", 2)
            .variable("inputVariable2", "test2")
            .executeWithSingleResult();

    Assertions.assertThat(executionResult).containsEntry("output1", "test1");
  }
}

3.5. Web应用程序中的DMN引擎

DmnEngine是一个线程安全的类,可以在多个线程之间轻松共享。 在Web应用程序中,这意味着可以在容器启动时创建DMN引擎,并在容器停机时关闭引擎。

以下代码片段显示了如何编写一个简单的 ServletContextListener 来初始化和销毁​​普通Servlet环境中的流程引擎:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class DmnEnginesServletContextListener implements ServletContextListener {

  public void contextInitialized(ServletContextEvent servletContextEvent) {
    DmnEngines.init();
  }

  public void contextDestroyed(ServletContextEvent servletContextEvent) {
    DmnEngines.destroy();
  }

}

contextInitialized 方法将调用 DmnEngines.init()。 这将寻找类路径上的 flowable.dmn.cfg.xml 资源文件,并对于给定的配置创建一个 DmnEngine (例如,带有配置文件的多个JAR).如果类路径上有多个此类资源文件,请确保它们都具有不同的名称。 当需要DMN引擎时,可以使用以下方式获取它:

1
DmnEngines.getDefaultDmnEngine()

或者:

1
DmnEngines.getDmnEngine("myName");

当然,也可以使用任何创建DMN引擎的变体,如configuration section中描述的那样。

context-listener的 contextDestroyed方法会调用 DmnEngines.destroy()。 它会妥善关闭所有初始化的DMN引擎。

4. Spring集成

虽然我们可以在没有Spring的情况下使用 Flowable DMN,但我们还是有必要提供了一些非常好的集成特性,本章我们将对此进行说明。

4.1. DmnEngineFactoryBean

我们可以将DMN引擎配置为普通的Spring Bean。配置的入口是org.flowable.dmn.spring.DmnEngineFactoryBean类。这个bean采用DMN引擎配置并同时创建DMN引擎。 这意味着Spring属性的创建和配置与configuration章节中记录的是一致的。Spring集成所用的配置与引擎Bean如下所示:

1
2
3
4
5
6
7
<bean id="dmnEngineConfiguration" class="org.flowable.dmn.spring.SpringDmnEngineConfiguration">
    ...
</bean>

<bean id="dmnEngine" class="org.flowable.dmn.spring.DmnEngineFactoryBean">
  <property name="dmnEngineConfiguration" ref="dmnEngineConfiguration" />
</bean>

注意:DmnEngine Bean的配置现在使用的是org.flowable.dmn.spring.SpringDmnEngineConfiguration类。

4.2. 自动资源部署

Spring集成还有一个自动部署资源的特殊功能。在DMN引擎配置中,我们可以指定一组资源。一旦创建DMN引擎,所有指定的资源都会被扫描和部署。适当的过滤可以防止重复的部署。只有当资源确实发生变化时,才会重新部署至Flowable DMN数据库中。这在Spring容器经常重启(例如:测试)的时候非常有用。

以下是一个例子:

1
2
3
4
5
6
7
8
9
<bean id="dmnEngineConfiguration" class="org.flowable.spring.SpringDmnEngineConfiguration">
  ...
  <property name="deploymentResources"
    value="classpath*:/org/flowable/spring/test/autodeployment/autodeploy/decision*.dmn" />
</bean>

<bean id="dmnEngine" class="org.flowable.dmn.spring.DmnEngineFactoryBean">
  <property name="dmnEngineConfiguration" ref="dmnEngineConfiguration" />
</bean>

默认情况下,上面的配置方式会将符合这个过滤器的所有资源组织在一起,作为Flowable DMN引擎的一个部署。为避免未改变资源导致重复部署,重复检测过滤将作用于整个部署操作。有时候,这并不是你想要的。例如,如果我们以这种方式部署了一组DMN资源,即使这些资源中只有的一个DMN流程定义发生了改变,整个部署都被视为新的部署,这个部署中的所有流程定义都将被重新部署,这将导致每个流程定义都会刷新版本,即使实际上只有一个流程定义发生了变化。

要想定制部署的方式,我们可以在SpringProcessEngineConfiguration中指定一个额外属性deploymentMode,这个属性定义了部署一组符合过滤器的资源的策略。这个属性默认支持3个值:

  • default: 将所有资源组织在一个部署中,整体用于重复检测过滤。这是默认值,在不指定属性值的时候也使用这个。

  • single-resource: 为每个资源创建一个单独的部署,并用于重复检测过滤。如果希望单独部署每一个DMN流程定义,并且只有在它发生变化时才创建新的DMN流程定义版本,就应该使用这个值。

  • resource-parent-folder: 为同一个目录下的资源创建一个单独的部署,并用于重复检测过滤。这个属性值可以为大多数资源创建独立的部署。同时仍可以通过将部分资源放在同一个目录下,将它们组织在一起。以下是一个将deploymentMode设置为single-resource的例子:

1
2
3
4
5
6
<bean id="dmnEngineConfiguration"
    class="org.flowable.dmn.spring.SpringDmnEngineConfiguration">
  ...
  <property name="deploymentResources" value="classpath*:/flowable/*.dmn" />
  <property name="deploymentMode" value="single-resource" />
</bean>

除了使用上面列出的deploymentMode几个枚举值之外,我们还可以自定义自动部署的行为。如果是这样做,我们可以创建SpringDmnEngineConfiguration的子类并覆盖getAutoDeploymentStrategy(String deploymentMode)方法。 这个方法用来设置deploymentMode属性值。

4.3. 单元测试

集成Spring后,我们可以很轻松使用标准的Flowable测试工具测试业务流程。下面的例子我们来展示如何使用典型的Spring单元测试工具测试业务流程:

JUnit 5 测试
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@ExtendWith(FlowableDmnSpringExtension.class)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = DmnSpringJunitJupiterTest.TestConfiguration.class)
public class SpringJunit4Test {

    @Autowired
    private DmnEngine dmnEngine;

    @Autowired
    private DmnRuleService ruleService;

    @Test
    @DmnDeploymentAnnotation
    public void simpleDecisionTest() {
        Map<String, Object> executionResult = ruleService.createExecuteDecisionBuilder()
            .decisionKey("extensionUsage")
            .variable("inputVariable1", 2)
            .variable("inputVariable2", "test2")
            .executeWithSingleResult();

        Assertions.assertThat(executionResult).containsEntry("output1", "test1");
    }
}
JUnit 4 测试
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:org/flowable/spring/test/junit4/springTypicalUsageTest-context.xml")
public class SpringJunit4Test {

    @Autowired
    private DmnEngine dmnEngine;

    @Autowired
    private DmnRuleService ruleService;

    @Autowired
    @Rule
    public FlowableDmnRule flowableSpringRule;

    @Test
    @DmnDeploymentAnnotation
    public void simpleDecisionTest() {
        Map<String, Object> executionResult = ruleService.createExecuteDecisionBuilder()
                .decisionKey("extensionUsage")
                .variable("inputVariable1", 2)
                .variable("inputVariable2", "test2")
                .executeWithSingleResult();

        Assertions.assertThat(executionResult).containsEntry("output1", "test1");
    }
}

注意:这个例子正常运行的条件是,需要在Spring配置中定义一个 org.flowable.dmn.engine.test.FlowableDmnRule Bean(在上面的例子中通过@Autowire自动注入)

1
2
3
<bean id="flowableDmnRule" class="org.flowable.dmn.engine.test.FlowableDmnRule">
    <property name="dmnEngine" ref="dmnEngine"/>
</bean>

5. 部署

5.1. DMN定义

文件名后缀符合 +.dmn+的文件,可以部署到DMN引擎中。

当DMN引擎嵌入到流程引擎中,DMN定义文件可以和其他流程相关资源一起,打包到流程包(business archive BAR)里。流程引擎的部署服务会识别DMN资源,将其引入到DMN引擎中。

流程包中包含的自定义表达式函数的Java class文件*不会添加到classpath中*。这些自定义的决策表达式class文件应该添加到DMN引擎的classpath,这样引擎才能发现并使用这些决策表达式。

5.1.1. DMN定义文件,决策 和决策表

一个DMN定义包含(不仅仅是)许多决策。一个决策一个表达式。DMN规范定义(描述)了多种类型的表达式。目前在Flowable DMN中,我们支持决策表类型的表达式。 部署一个DMN定义是,定义中的每个*包含决策表*的决策定义,会分开插入到ACT_DMN_DECISION表里。

5.1.2. 编程方式部署

可以这样部署一个DMN定义:

1
2
3
4
5
6
String dmnDefinition = "path/to/definition-one.dmn"; //Don't forget the .dmn extension!

repositoryService.createDeployment()
    .name("Deployment of DMN definition-one")
    .addClasspathResource(dmnDefinition)
    .deploy();

也可以使用诸如`addInputStream`的其他方式部署DMN定义。以下是一个使用外部文件部署DMN定义的例子:

1
2
3
4
5
6
File dmnFile = new File("/path/to/definition-two.dmn"); //Don't forget the .dmn extension!

repositoryService.createDeployment()
    .name("Deployment of DMN definition-two")
    .addInputStream(dmnFile.getName(), new FileInputStream(dmnFile))
    .deploy();

部署的文件,名称可以是任意文本,但是作为有效的DMN定义文件,定义文件名后缀应该是(".dmn")。

5.1.3. Java 类

当决策执行时,使用的自定义Java class文件,需要放在引擎的classpath中。

在部署DMN定义时,这些class文件可以没有放到引擎的classpath下。

在测试时需要添加自定义Java类。需要把包含这些class文件的jar包放到flowable-ui-app或flowable-app-rest工程的lib下(${webserver}/${appname}/WEB-INF/lib/)。千万不要忘记这些依赖。另外,也可以将这些依赖放到tomcat中,${tomcat.home}/lib

5.1.4. 创建单应用

不用确保所有DMN引擎classpath中包含所有代理类,并且使用了正确的spring配置,你可以考虑在自己的webapp里引入flowable-rest,这样就只有一个+Dmn引擎+.

5.2. DMB决策版本控制

DMN没有版本控制的概念。这实际上很好,因为作为开发项目的一部分,可执行DMN定义文件可能位于版本控制系统存储库(例如Subversion、Git或Mercurial)中。部署期间创建DMN决策的版本。在部署过程中,flowable将为+decision+分配一个版本,然后将其存储在flowable db中。

因为DMN定义中的每个DMN决策都是一个DMN定义,将执行以下步骤来初始化属性+key+、versionname+和+id

  • 定义文件中 decision id 属性在决策表中是 key.

  • 定义文件中 decision name 属性在决策表中是 name.

  • 一个有特定的key的决策在首次部署时,版本标记为1。对于之后所有拥有相同key的发布,版本号相对于之前最高版本号+1。所以key属性是用来区分不同的决策。

  • id属性时在集群环境中,保证决策表的唯一的[数字]标识。

以下面的流程为例:

1
2
3
4
<definitions id="myDefinitions" >
  <decision id="myDecision" name="My important decision" >
    <decisionTable id="decisionTable1" hitPolicy="FIRST" >
    ...

当部署了该决策,决策表在数据库中是这样的:

id key name version

e29d4126-ed4d-11e6-9e00-7282cbd6ce64

myDecision

My important decision

1

当我们再发布这个流程的更新版本(比如:更改了用户任务),流程定义的id 和之前是一样的。 流程定义表会包含一下信息:

id key name version

e29d4126-ed4d-11e6-9e00-7282cbd6ce64

myDecision

My important decision

1

e9c2a6c0-c085-11e6-9096-6ab56fad108a

myDecision

My important decision

2

当调用了 dmnRuleService.executeDecisionByKey("myDecision") , 之后会调用版本号 2 的决策定义,因为这个是决策定义的最新版本。

如果我们创建第二个决策,定义如下所示,然后发布到flowable DMN中,数据库表中会增加第三行。

1
2
3
4
<definitions id="myNewDefinitions" >
  <decision id="myNewDecision" name="My important decision" >
    <decisionTable id="decisionTable1" hitPolicy="FIRST" >
      ...

表中数据是这样的:

id key name version

e29d4126-ed4d-11e6-9e00-7282cbd6ce64

myDecision

My important decision

1

e9c2a6c0-c085-11e6-9096-6ab56fad108a

myDecision

My important decision

2

d317d3f7-e948-11e6-9ce6-b28c070b517d

myNewDecision

My important decision

1

注意:新的决策的key和第一个决策的key是不一样的。尽管name属性是一样的(正常情况下,表意清晰的话,我们需要把name属性也改掉),FlowableDMN引擎通过 id 属性来区分不同的决策。新增的决策将会以版本1部署。

5.3. 分类

DMN部署和决策表都可以自定义分类。 DMN部署分类可以这样定义:

1
2
3
4
5
dmnRepository
    .createDeployment()
    .category("yourCategory")
    ...
    .deploy();

决策表分类可以这样定义:

1
dmnRepository.setDecisionTableCategory("e9c2a6c0-c085-11e6-9096-6ab56fad108a", "yourCategory");

6. DMN 1.1 入门

6.1. 什么是DMN?

Decision Model & Notation(DMN)是由对象管理组(OMG)发布的标准。它是描述和构建组织内可重复决策的标准方法,以确保决策模型在各组织之间是通用的。

6.2. 什么是DMN定义?

DMN 1.1模式的根元素是definitions。在这个项目中可以定义多个决策定义(尽管我们建议每个文件中只有一个决策定义,这可以简化开发过程的后期维护)。每个决策可以定义一个表达式。目前,Flowable支持几种表达式类型中的决策表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<definitions xmlns="http://www.omg.org/spec/DMN/20151101"
  namespace="http://www.flowable.org/dmn"
  name="DetermineDiscount">

  <decision id="DET_DISC_1" name="DetermineDiscount">

    <decisionTable id="determineDiscountTable1" hitPolicy="FIRST">
      ..
    </decisionTable>

  </decision>

</definitions>

6.3. 创建DMN定义

虽然使用纯文本编辑器创建DMN定义是可行的,但是对于此示例,我们将首先使用Flowable建模器的决策表编辑器。

接下来,我们将实现一个非常简单的用例:根据客户类别确定折扣百分比。

首先打开Flowable建模器中的决策表部分。

decision tables 1

选择Create Decision Table

decision tables 2

填写决策表名称和决策表唯一键,然后选择Create new decision table

decision tables 3

现在就可以定义决策表了。接下来我们对编辑器做个说明。

6.3.1. Hit Policy 命中策略

我们可以在左上角选择hit policy

可以看到,有7个命中策略可用。

单一命中

  • FIRST: 可以匹配多个(重叠)具有不同输出条目的规则。返回规则顺序中的第一次命中(返回后停止评估)。

  • UNIQUE: 没有重叠的可能,所有规则都是互斥的。只能匹配到一条规则。

  • ANY: 可能会有重叠,但如果所有匹配规则显示每个输出的输出条目相等,就可以使用任何匹配。如果输出条目不相等,则命中策略不正确,结果将为空并标记为failed。当禁用strict mode时,结果是最后一个有效规则。(违规将以验证消息的形式出现)

  • PRIORITY: 具有不同的输出条目的多个规则可以匹配。此策略返回具有最高输出优先级的匹配规则。输出优先级在输出值的有序列表中按优先级递减的顺序指定。当禁用strict mode且未定义输出值时,结果是最后一个有效规则。(违规将以验证消息的形式出现)

多重命中

  • OUTPUT ORDER: 按输出优先级递减的顺序返回所有命中规则。输出优先级在输出值的有序列表中按优先级递减的顺序指定。

  • RULE ORDER: 按规则顺序返回所有命中。

  • COLLECT: 以任意顺序返回所有命中。我们可以添加运算符(+<>)来将一个简单函数应用于输出。如果没有运算符,则结果是所有输出条目的列表。

    • + (sum): 决策表的结果是所有不同输出的总和。

    • < (min): 决策表的结果是所有输出的最小值。

    • > (max): 决策表的结果是所有输出的最大值。

    • # (count): 决策表的结果是所有不同输出的总数。

6.3.2. 输入和输出表达式

决策表本身的表头分为两部分;蓝色和绿色。蓝色部分是input expressions(输入表达式);绿色的是output expressions(输出表达式)。

decision tables 4

在输入表达式中,我们可以定义将在规则输入条目的表达式中使用的变量(下面解释)。还可以通过选择Add Input(右键单击option菜单或单击plus图标)来定义多个输入表达式。

decision tables 5

在输出表达式中,我们可以定义将创建什么变量来构成决策表执行的结果(变量的值将由输出条目表达式决定,下面解释)。还可以通过选择Add Output(右键单击option菜单或单击plus图标)来定义多个输出表达式。

6.3.3. 规则

每个规则由一个或多个输入项和一个或多个输出项组成。输入项是一个表达式,它将根据输入的变量(该“列”的值)求值。当所有输入项都为true时,就认为整个规则是true,开始计算输出项。

DMN规范定义了一种表达式语言:(S)-FEEL。目前,我们不支持这部分规范。 在Flowable DMN中,我们使用JUEL作为表达式语言。

decision tables 6

我们可以双击相应的单元格输入表达式。在此示例中,输入表达式== BRONZE。结合相应输入表达式(列标题)中定义的变量,将在运行时生成完整的表达式customerCat == "BRONZE"。

decision tables 7

然后双击相应的单元格输出表达式。这实际上更像是一个隐式赋值。 在此示例中,输入表达式5。

然后,我们可以通过添加更多规则(通过选择添加规则)继续完成决策表。

decision tables 8

在我们的示例中,规则4有一个空的输入条目,引擎将会把这个空输入条目评估为true。那么如果其他规则都无效,则规则4的结果将是该决策表的输出。在这种情况下,变量discountPerc的值为0

decision tables 9

现在我们可以保存决策表。填入决策表唯一键。

6.4. BPMN2.0流程中的应用

通过包含Decision task并选择Decision table reference,可以在BPMN2.0流程中使用新创建的决策表。

decision tables 10

上面定义的流程中,该流程有一个启动表单,它将customer category(客户类别)提供给流程实例(从而提供给决策表)。Display Discount(显示折扣)用户任务使用表达式表单字段显示决策表的结果;${discountperc}。

6.5. DMN 1.1 xml文件

上面示例的完整DMN 1.1 xml文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<definitions xmlns="http://www.omg.org/spec/DMN/20151101" id="definition_78d09dd7-374c-11e8-b5d8-0242ac120005" name="Determine Discount" namespace="http://www.flowable.org/dmn">
  <decision id="DET_DISC_1" name="Determine Discount">
    <decisionTable id="decisionTable_78d09dd7-374c-11e8-b5d8-0242ac120005" hitPolicy="UNIQUE">
      <input label="Customer Category">
        <inputExpression id="inputExpression_1" typeRef="string">
          <text>customerCat</text>
        </inputExpression>
        <inputValues>
          <text>"BRONZE","SILVER","GOLD"</text>
        </inputValues>
      </input>
      <output id="outputExpression_2" label="Discount Percentage" name="discountPerc" typeRef="number">
        <outputValues>
          <text>"0","5","10","20"</text>
        </outputValues>
      </output>
      <rule>
        <inputEntry id="inputEntry_1_1">
          <text><![CDATA[== "BRONZE"]]></text>
        </inputEntry>
        <outputEntry id="outputEntry_2_1">
          <text><![CDATA[5]]></text>
        </outputEntry>
      </rule>
      <rule>
        <inputEntry id="inputEntry_1_2">
          <text><![CDATA[== "SILVER"]]></text>
        </inputEntry>
        <outputEntry id="outputEntry_2_2">
          <text><![CDATA[10]]></text>
        </outputEntry>
      </rule>
      <rule>
        <inputEntry id="inputEntry_1_3">
          <text><![CDATA[== "GOLD"]]></text>
        </inputEntry>
        <outputEntry id="outputEntry_2_3">
          <text><![CDATA[20]]></text>
        </outputEntry>
      </rule>
      <rule>
        <inputEntry id="inputEntry_1_4">
          <text><![CDATA[-]]></text>
        </inputEntry>
        <outputEntry id="outputEntry_2_4">
          <text><![CDATA[0]]></text>
        </outputEntry>
      </rule>
    </decisionTable>
  </decision>
</definitions>
  • 此处需要重点强调的是,在Flowable中使用的决策表键是DMN xml文件中的决策ID。

7. DMN REST API

7.1. Flowable REST一般原则

7.1.1. 安装与认证

Flowable为Flowable引擎提供了REST API,可以通过在servlet容器(如Apache Tomcat)中部署flowable-rest.war文件来安装。另外,也可以通过在应用中引入servlet(包括对应的映射),并将所有flowable-rest的依赖加入classpath的方式使用。

默认情况下Flowable引擎会连接至一个H2内存数据库。可以通过WEB-INF/META-INF/flowable-app文件夹下的flowable-app.properties文件修改数据库设置。REST API使用JSON格式( http://www.json.org ),并基于Spring MVC( http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html )构建。

默认情况下访问任何REST资源都需要具有rest-access-api权限的合法用户。如果需要任何合法用户都可以访问REST API,可以将flowable.rest.app.authentication-mode设置为any-user(这也是之前版本Flowable的默认设置)。

通过如下参数设置可以访问REST API的默认用户:

flowable.rest.app.admin.user-id=rest-admin
flowable.rest.app.admin.password=test
flowable.rest.app.admin.first-name=Rest
flowable.rest.app.admin.last-name=Admin

当REST应用启动时,如果用户不存在或无法找到,则会创建该用户。这个用户会被赋予访问REST API所需的access-rest-api权限。请不要忘记修改这个用户的密码。如果未设置flowable.rest.app.admin.user-id,则不会创建用户或权限。也因为此,在初始化完成后删除这些参数,并不会删除之前已经配置的用户或权限。

使用基础HTTP访问认证,因此在请求时,需要在HTTP-header中添加 Authorization: Basic …​== 。也可以在请求url中包含用户名与密码(如 http://username:password@localhost:8080/xyz)。

建议使用基础认证时,同时使用HTTPS。

7.1.2. 配置

Flowable REST web应用使用Spring Java Configuration来启动Flowable引擎,使用Spring security定义基础认证安全,并为为特定的变量处理定义了变量转换。 有少量参数可以通过修改WEB-INF/classes文件夹下的engine.properties文件定义。 如果需要高级配置选项,可以在flowable-custom-context.xml文件中覆盖默认的Spring bean,这个文件也在WEB-INF/classes文件夹下。 该文件中已经以注释形式提供了示例配置。也可以在该文件中定义一个新的命名为restResponsefactory的Spring bean,覆盖默认的RestResponseFactory,并使用自定义实现类。

7.1.3. 在Tomcat中使用

由于Tomcat中的默认安全参数默认不能使用转义斜线符(%2F%5C)(将返回400)。这可能会影响部署资源与其数据URL,因为URL可能包含转义斜线符。

当发现400异常结果时,可以设置下列系统参数:

-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

最佳实践是(在post/put JSON时),在下面介绍的HTTP请求中,永远将AcceptContent-TypeHTTP头设置为application/json

7.1.4. 方法与返回码

Table 1. HTTP方法与对应操作
方法 操作

GET

获取单个资源,或获取一组资源。

POST

创建一个新资源。在查询结构太复杂,不能放入GET请求的查询URL中时,也用于执行资源查询。

PUT

更新一个已有资源的参数。也用于调用已有资源提供的操作。

DELETE

删除一个已有资源。

Table 2. HTTP方法响应码
响应 描述

200 - Ok

操作成功,返回响应(GETPUT请求)。

201 - 已创建

操作成功,已经创建了实体,并在响应体中返回(POST请求)。

204 - 无内容

操作成功,已经删除了实体,因此没有返回的响应体(DELETE请求)。

401 - 未认证

操作失败。操作要求设置认证头。如果请求中有认证头,则提供的鉴证并不合法,或者用户未被授权进行该操作。

403 - 禁止

操作被禁止,且不应重试。这不是鉴证或授权的问题,而是说明不允许该操作。例如:无论任何用户或流程/任务的状态,删除一个运行中流程的任务是且永远是不允许的。

404 - 未找到

操作失败。请求的资源未找到。

405 - 不允许的方法

操作失败。使用的方法不能用于该资源。例如,更新(PUT)部署资源将返回405响应码。

409 - 冲突

操作失败。该操作导致更新一个已被其他操作更新的资源,因此本更新不再有效。也可以表示正在为一个集合创建一个资源,但该标识符已存在。

415 - 不支持的媒体类型

操作失败。请求提包含了不支持的媒体类型。也会发生在请求体JSON中包含了未知的属性或值,但没有可用的格式/类型来处理的情况。

500 - 服务器内部错误

操作失败。执行操作时发生了未知异常。响应体中包含了错误的细节。

HTTP响应的media-type总是application/json,除非请求的是二进制内容(例如部署资源数据)。这时将使用内容的media-type。

7.1.5. 错误响应体

当发生错误时(可能是客户端或服务器端的错误,4XX及5XX状态码),响应体会包含一个描述了发生的错误的对象。任务未找到时的404状态的例子:

1
2
3
4
{
  "statusCode" : 404,
  "errorMessage" : "Could not find a task with id '444'."
}

7.1.6. 请求参数

URL片段

作为url的一部分的参数(例如,URL编码或百分号编码)。大多数框架都内建了这个功能,但要记得考虑它。特别是对可能包含斜线符的段落(例如部署资源),就必须要做转义。

Rest URL查询参数

作为查询字符串添加在URL中的参数(例如http://host/flowable-rest/service/deployments?name=Deployment中的name参数)可以使用下列类型。在相应的REST-API文档中也会提到:

Table 3. URL查询参数类型
类型 格式

String

纯文本参数。可以包含任何URL允许的合法字符。对于XXXLike参数,字符串可能会包含通配符%(需要进行URL编码)。可以进行like搜索,例如,'Tas%'将匹配所有以’Tas’开头的值。

Integer

整形参数。只能包含数字型非小数值,在-2.147.483.648至2.147.483.647之间。

Long

长整形参数。只能包含数字型非小数值,在-9.223.372.036.854.775.808至9.223.372.036.854.775.807之间。

Boolean

boolean型参数。可以为truefalse。任何其他值都会导致'405 - 错误请求'响应码。

Date

日期型参数。使用ISO-8601日期格式(参考wikipedia中的ISO-8601),使用时间与日期部分(例如2013-04-03T23:45Z)。

JSON body 参数
Table 4. JSON参数类型
类型 格式

String

纯文本参数。对于XXXLike参数,字符串可能会包含通配符%。可以进行like搜索。例如,'Tas%'将匹配所有以’Tas’开头的值。

Integer

整形参数,使用JSON数字。只能包含数字型非小数值,在-2.147.483.648至2.147.483.647之间。

Long

长整形参数,使用JSON数字。只能包含数字型非小数值,在-9.223.372.036.854.775.808至9.223.372.036.854.775.807之间。

Date

日期型参数,使用JSON文本。使用ISO-8601日期格式(参考wikipedia中的ISO-8601),使用时间与日期组分(例如2013-04-03T23:45Z)。

分页与排序

分页与排序参数可以作为查询字符串加入URL中(例如http://host/flowable-rest/service/deployments?sort=name中的name参数)。

Table 5. JSON查询变量参数
参数 默认值 描述

sort

各查询实现不同

排序键的名字,在各查询实现中默认值与可用值都不同。

order

asc

排序顺序,可以是’asc'(顺序)或’desc'(逆序)。

start

0

对结果分页的参数。默认结果从0开始。

size

10

对结果分页的参数。默认大小为10.

JSON查询变量格式
1
2
3
4
5
6
7

{
  "name" : "variableName",
  "value" : "variableValue",
  "operation" : "equals",
  "type" : "string"
}
Table 6. JSON查询变量参数
参数 必填 描述

name

包含在查询中的变量名。在有些使用'equals'的查询中可以为空,查询任意变量名为给定值的资源。

value

包含在查询中的变量值,需要使用给定类型的正确格式。

operator

查询使用的操作,可以为下列值:equals, notEquals, equalsIgnoreCase, notEqualsIgnoreCase, lessThan, greaterThan, lessThanOrEquals, greaterThanOrEqualslike

type

所用变量的类型。当省略时,会从value参数推理类型。任何JSON文本值都使用是string类型,JSON boolean值使用boolean类型,JSON数字使用longinteger,取决于数字的大小。建议在有疑惑时明确指定类型。其他支持的类型列在下面。

Table 7. 默认查询JSON类型
类型名 描述

string

值处理转换为java.lang.String

short

值处理转换为java.lang.Integer

integer

值处理转换为java.lang.Integer

long

值处理转换为java.lang.Long

double

值处理转换为java.lang.Double

boolean

值处理转换为java.lang.Boolean

date

值处理转换为java.util.Date。JSON字符串将使用ISO-8601日期格式转换。

变量表示

读取与写入变量(执行选择)时,REST API都使用通用原则与JSON格式。变量的JSON表示为:

1
2
3
4
5
6
{
  "name" : "variableName",
  "value" : "variableValue",
  "valueUrl" : "http://...",
  "type" : "string"
}
Table 8. 变量的JSON属性
参数 必填 描述

name

变量名。

value

变量的值。当写入变量且省略了value时,会使用null作为value。

valueUrl

当读取binaryserializable类型的变量时,这个属性将指向可用于获取原始二进制数据的URL。

type

变量的类型。查看下面的表格了解类型的更多信息。当写入变量且省略了这个值时,将使用请求的原始JSON属性类型推断,限制在string, double, integerboolean中。建议总是包含类型,以确保不会错误推断类型。

Table 9. 变量类型
类型名 描述

string

值按照java.lang.String处理。写入变量时使用原始JSON文本。

integer

值按照java.lang.Integer处理。按约定写入变量时使用JSON数字,失败则退回JSON文本。

short

值按照java.lang.Short处理。按约定写入变量时使用JSON数字,失败则退回JSON文本。

long

值按照java.lang.Long处理。按约定写入变量时使用JSON数字,失败则退回JSON文本。

double

值按照java.lang.Double处理。按约定写入变量时使用JSON数字,失败则退回JSON文本。

boolean

值按照java.lang.Boolean处理。按约定写入变量时使用JSON boolean。

date

值按照java.util.Date处理。写入变量时将转换为ISO-8601日期格式。

可以使用自定义JSON表示,以支持额外的变量类型(既可以是简单值,也可以是复杂/嵌套的JSON对象)。通过扩展org.flowable.rest.service.api.RestResponseFactoryinitializeVariableConverters()方法,可以添加额外的org.flowable.rest.service.api.engine.variable.RestVariableConverter类,用于将POJO转换为适合通过REST传输的格式,以及将REST值转换为POJO。实际转换JSON使用Jackson。

7.2. 部署

当使用tomcat时,请阅读 Usage in Tomcat.

7.2.1. 获取多个DMN部署

GET dmn-repository/deployments
Table 10. URL 查询参数
参数 必需 类型 描述

name

No

String

返回指定名称的部署.

nameLike

No

String

模糊查询指定名称.

category

No

String

返回指定类别.

categoryNotEquals

No

String

返回指定类别以外的部署.

tenantId

No

String

返回指定tenantId的部署.

tenantIdLike

No

String

模糊查询指定tenantId的部署.

withoutTenantId

No

Boolean

如果为true 则返回指定tenantId以外的部署,如果为false 则忽略掉该参数.

sort

No

id (default), name, deploytime or tenantId

属性进行排序,与“order”一起使用.

Table 11. REST 返回编码
Response code Description

200

Indicates the request was successful.

返回编码 描述

200

请求成功.

Success response body: 成功返回示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
  "data": [
    {
      "id": "03ab310d-c1de-11e6-a4f4-62ce84ef239e",
      "name": null,
      "deploymentTime": "2016-12-14T10:16:37.000+01:00",
      "category": null,
      "url": "http://localhost:8080/flowable-rest/dmn-api/dmn-repository/deployments/03ab310d-c1de-11e6-a4f4-62ce84ef239e",
      "parentDeploymentId": "17510",
      "tenantId": ""
    }
  ],
  "total": 1,
  "start": 0,
  "sort": "id",
  "order": "asc",
  "size": 1
}

7.2.2. 获取一个DMN部署

GET dmn-repository/deployments/{deploymentId}
Table 12. 获取一个部署- URL 参数
参数 必需 类型 描述

deploymentId

Yes

String

部署唯一id.

Table 13. 获取一个部署- 返回编码
返回编码 描述

200

找到并返回指定部署.

404

为找到指定的部署.

成功示例:

1
2
3
4
5
6
7
8
9
{
  "id": "03ab310d-c1de-11e6-a4f4-62ce84ef239e",
  "name": null,
  "deploymentTime": "2016-12-14T10:16:37.000+01:00",
  "category": null,
  "url": "http://localhost:8080/flowable-rest/dmn-api/dmn-repository/deployments/03ab310d-c1de-11e6-a4f4-62ce84ef239e",
  "parentDeploymentId": "17510",
  "tenantId": ""
}

7.2.3. Create a new DMN deployment

(创建一个DMN部署)

POST dmn-repository/deployments

Request body: 请求消息体:

The request body should contain data of type multipart/form-data. There should be exactly one file in the request: any additional files will be ignored. The deployment name is the name of the file-field passed in. (请求消息体应该包含 multipart/form-data 类型。请求中应该只有一个文件:任何额外的文件都将被忽略。file-field 的名称作为部署的名称) An additional parameter (form-field) can be passed in the request body with name tenantId. The value of this field will be used as the identifier of the tenant in which this deployment is done. (可以在请求体中通过name +tenantId+传递附加参数(表单字段)。此字段的值将用作执行此部署的租户的标识符。) .Create a new DMN deployment - Response codes (创建一个DMN部署-返回编码)

Response code Description

201

Indicates the deployment was created.

400

Indicates there was no content present in the request body or the content mime-type is not supported for deployment. The status-description contains additional information.

返回编码 描述

201

指定的部署已经存在.

400

请求主体中不存在内容,或部署不支持该内容的mime-type。状态描述包含附加信息。

Success response body: (成功示例:)

1
2
3
4
5
6
7
8
{
  "id": "03ab310d-c1de-11e6-a4f4-62ce84ef239e",
  "name": "newDeployment1",
  "deploymentTime": "2016-12-14T10:16:37.000+01:00",
  "category": null,
  "url": "http://localhost:8080/flowable-rest/dmn-api/dmn-repository/deployments/03ab310d-c1de-11e6-a4f4-62ce84ef239e",
  "tenantId" : "myTenant"
}

7.2.4. Delete a DMN deployment

(删除一个部署)

DELETE dmn-repository/deployments/{deploymentId}
Delete a DMN deployment - URL parameters

(删除一个部署- URL 参数)

Parameter Required Value Description

deploymentId

Yes

String

The identifier of the deployment to delete.

参数 必需 类型 描述

deploymentId

Yes

String

需要删除的部署的编号.

Delete a DMN deployment - Response codes

(删除一个部署 - 返回编码)

Response code Description

204

Indicates the deployment was found and has been deleted. Response-body is intentionally empty.

404

Indicates the requested deployment was not found.

返回编码 描述

204

指定的部署已经被删除。返回内容特意为空。

404

未找到指定的部署。

7.2.5. Get a DMN deployment resource content

(获取DMN部署资源内容)

GET dmn-repository/deployments/{deploymentId}/resourcedata/{resourceId}
Get a deployment resource content - URL parameters

(获取DMN部署资源内容 - URL 参数)

Parameter Required Value Description

deploymentId

Yes

String

The identifier of the deployment the requested resource is part of.

resourceId

Yes

String

The identifier of the resource to get the data for. Make sure you URL-encode the resourceId in case it contains forward slashes. For example, use decisions%2Fmy-decision.dmn instead of decisions/my-decision.dmn.

参数 必需 类型 描述

deploymentId

Yes

String

指定部署编号。

resourceId

Yes

String

指定资源编号。确保resourceId的URL编码,以防它包含前斜杠。例如,使用 decisions%2Fmy-decision.dmn。而不是’decisions/my-decision.dmn'

Get a deployment resource content - Response codes

(.获取DMN部署资源内容 - 返回编码)

Response code Description

200

Indicates both deployment and resource have been found and the resource data has been returned.

404

Indicates the requested deployment was not found or there is no resource with the given identifier present in the deployment. The status-description contains additional information.

Response code Description

200

已找到指定的部署和资源,并返回资源数据。

404

未找到所请求的部署,或部署中不存在指定的资源。状态描述包含附加信息。

Success response body:成功示例:

The response body will contain the binary resource-content for the requested resource. The response content-type will be the same as the type returned in the resources mimeType property. Also, a content-disposition header is set, allowing browsers to download the file instead of displaying it. (响应体将包含请求资源的二进制资源内容。响应内容类型将与资源“mimeType”属性中返回的类型相同。此外,header还设置了一个content-disposition ,允许浏览器下载文件而不是显示它。)

7.3. Decision Tables

(决策表)

7.3.1. List of decision tables

(获取决策表列表)

GET dmn-repository/decision-tables
List of process definitions - URL parameters

(获取流程定义列表- URL 参数)

Parameter Required Value Description

version

No

integer

Only return process definitions with the given version.

name

No

String

Only return process definitions with the given name.

nameLike

No

String

Only return process definitions with a name like the given name.

key

No

String

Only return process definitions with the given key.

keyLike

No

String

Only return process definitions with a name like the given key.

resourceName

No

String

Only return process definitions with the given resource name.

resourceNameLike

No

String

Only return process definitions with a name like the given resource name.

category

No

String

Only return process definitions with the given category.

categoryLike

No

String

Only return process definitions with a category like the given name.

categoryNotEquals

No

String

Only return process definitions which don’t have the given category.

deploymentId

No

String

Only return process definitions which are part of a deployment with the given identifier.

latest

No

Boolean

Only return the latest process definition versions. Can only be used together with key and keyLike parameters, using any other parameter will result in a 400-response.

sort

No

name (default), id, key, category, deploymentId and version

Property to sort on, to be used together with the order.

The general paging and sorting query-parameters can be used for this URL.

参数 必需 类型 描述

version

No

integer

返回指定版本的流程定义。

name

No

String

返回指定名称的流程定义。

nameLike

No

String

模糊查询指定名称的流程定义。

key

No

String

返回指定key的流程定义。

keyLike

No

String

模糊查询指定key的流程定义。

resourceName

No

String

返回指定资源名称的流程定义。

resourceNameLike

No

String

模糊查询指定资源名称的流程定义。

category

No

String

返回指定类别的流程定义。

categoryLike

No

String

模糊查询指定名称的流程定义。

categoryNotEquals

No

String

返回指定类型以外的流程定义。

deploymentId

No

String

返回指定部署编号的流程定义。

latest

No

Boolean

返回最新版本的流程定义。只能与“key”和“keyLike”参数一起使用,使用任何其他参数都会得到400个响应。

sort

No

name (default), id, key, category, deploymentId and version

排序,与“order”一起使用。

Table 14. 获取流程定义列表 - 返回编码
返回编码 描述

200

请求成功,并返回决策表

400

参数以错误的格式传递,或’latest' 与’key' 和 'keyLike’以外的其他参数一起使用。状态消息包含其他信息。

成功示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
  "data": [
        {
      "id": "46b0379c-c0a1-11e6-bc93-6ab56fad108a",
      "url": "http://localhost:8080/flowable-rest/dmn-api/dmn-repository/decision-tables/46b0379c-c0a1-11e6-bc93-6ab56fad108a",
      "category": null,
      "name": "Decision Table One",
      "key": "DecisionTableOne",
      "description": null,
      "version": 3,
      "resourceName": "dmn-DecisionTableOne.dmn",
      "deploymentId": "46aa6b3a-c0a1-11e6-bc93-6ab56fad108a",
      "parentDeploymentId": "5001",
      "tenantId": ""
    }
  ],
  "total": 1,
  "start": 0,
  "sort": "name",
  "order": "asc",
  "size": 1
}

7.3.2. 获取一个决策表

GET dmn-repository/decision-tables/{decisionTableId}
Table 15. 获取一个决策表 - URL 参数
参数 必需 类型 描述

decisionTableId

Yes

String

决策表编号。

Table 16. 获取一个决策表 - 返回编码
Response code Description

200

找到指定编号决策表并返回

404

未找到指定编号决策表

成功示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "id": "46b0379c-c0a1-11e6-bc93-6ab56fad108a",
  "url": "http://localhost:8080/flowable-rest/dmn-api/dmn-repository/decision-tables/46b0379c-c0a1-11e6-bc93-6ab56fad108a",
  "category": null,
  "name": "Decision Table One",
  "key": "DecisionTableOne",
  "description": null,
  "version": 3,
  "resourceName": "dmn-DecisionTableOne.dmn",
  "deploymentId": "46aa6b3a-c0a1-11e6-bc93-6ab56fad108a",
  "parentDeploymentId": "5001",
  "tenantId": ""
}

7.3.3. 获取一个决策表资源内容

GET dmn-repository/decision-tables/{decisionTableId}/resourcedata
Table 17. 获取一个决策表资源内容 - URL 参数
参数 必需 类型 描述

decisionTableId

Yes

String

决策表编号。

返回:

GET dmn-repository/deployment/{deploymentId}/resourcedata/{resourceId} 相同.

7.3.4. 获取一个决策表DMN模型

GET dmn-repository/decision-tables/{decisionTableId}/model
Table 18. 获取一个决策表DMN模型- URL 参数
参数 必需 类型 描述

decisionTableId

Yes

String

决策表编号。

Table 19. 获取一个决策表DMN模型- 返回编码
返回编码 描述

200

找到指定决策表并返回模型。

404

未找到指定决策表。

返回内容: 返回内容是+org.flowable.dmn.model.DmnDefinition+的JSON。并包含完整的DMN定义模型。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
   "processes":[
      {
         "id":"oneTaskProcess",
         "xmlRowNumber":7,
         "xmlColumnNumber":60,
         "extensionElements":{

         },
         "name":"The One Task Process",
         "executable":true,
         "documentation":"One task process description",

    ]
}

7.4. DMN规则服务

7.4.1. 执行一个决策

POST dmn-rule/execute

Request body:

请求体应该包含_multipart/form-data_类型的数据。需要decisionKey。tenantId、parentdeploymentd和inputVariables (restVariables)映射是可选的。

Response body:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
  "resultVariables": [
    [
      {
        "name": "output1",
        "type": "string",
        "value": "result 1"
      }
    ],
    [
      {
        "name": "output1",
        "type": "string",
        "value": "result 2"
      }
    ],
    [
      {
        "name": "output1",
        "type": "string",
        "value": "result 3"
      }
    ]
  ],
  "url": "http://localhost:8080/flowable-rest/dmn-api/dmn-rule/execute"
}
Table 20. 执行一个决策 - 返回编码
返回编码 描述

201

已执行该决策。

7.4.2. 执行一个单结果决策

POST dmn-rule/execute/single-result

Request body:

请求体应该包含_multipart/form-data_类型的数据。需要decisionKey。tenantId、parentdeploymentd和inputVariables (restVariables)映射是可选的。

当多个规则有效时,返回500。

注意:使用复合输出的单个命中是有效的(参见下面的响应)

Response body:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
  "resultVariables": [
    {
      "name": "output1",
      "type": "string",
      "value": "compound 1"
    },
    {
      "name": "output2",
      "type": "string",
      "value": "compound 2"
    }
  ],
  "url": "http://localhost:8080/flowable-rest/dmn-api/dmn-rule/execute/single-result"
}
Table 21. 执行一个单结果决策 - 返回编码
返回编码 描述

201

已执行指定决策。

500

指定决策返回多个结果。

7.5. 引擎

7.5.1. 获取一个DMN引擎信息

GET dmn-management/engine

返回此rest服务中使用的DMN引擎的只读视图。

响应成功:

1
2
3
4
5
6
{
   "name":"default",
   "version":"6.5.0.event-SNAPSHOT",
   "resourceUrl":"file://flowable-dmn/flowable.dmn.cfg.xml",
   "exception":null
}
Table 22. 获取引擎信息 - 返回编码
返回编码 描述

200

返回指定引擎信息。