部署
DMN 定义
扩展名为 .dmn 的 DMN 定义可以部署到 DMN 引擎。
当 DMN 引擎插入流程引擎时,DMN 定义可以与其他流程相关资源一起打包到业务归档(BAR)中。流程引擎部署服务会负责将 DMN 资源部署到 DMN 引擎。
注意
业务归档中用于自定义表达式函数的 Java 类不会被添加到 classpath。业务归档中决策表达式所用的所有自定义类都应位于 Flowable(DMN)引擎的 classpath 上,才能运行这些决策。
DMN 定义、决策与决策表
DMN 定义由决策等内容组成。一个决策有一个表达式。DMN 规范描述了多种表达式类型。目前 Flowable DMN 支持决策表类型的表达式。
部署 DMN 定义时,每个决策(可以包含一个决策表)会被分别插入 ACT_DMN_DECISION 表。
以编程方式部署
部署 DMN 定义可以这样完成:
String dmnDefinition = "path/to/definition-one.dmn"; //Don't forget the .dmn extension!
repositoryService.createDeployment()
.name("Deployment of DMN definition-one")
.addClasspathResource(dmnDefinition)
.deploy();
你可以使用其他方法将 DMN 定义添加到部署中,例如 addInputStream。下面是从外部文件部署 DMN 定义的示例:
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")。
Java 类
当执行决策时,包含决策所用自定义表达式函数的所有类都应位于引擎的 classpath 上。
但是,在部署 DMN 定义时,这些类不必位于 classpath 上。
当你使用 demo 设置并希望添加自定义类时,应将包含你类的 JAR 添加到 flowable-app-rest webapp 的 lib 中。不要忘记同时包含自定义类的依赖(如果有的话)。或者,你也可以将依赖包含到 Tomcat 安装的 libraries 目录中,即 ${tomcat.home}/lib。
创建单一应用
与其确保所有 DMN 引擎都在其 classpath 上拥有所有委派类并使用正确的 Spring 配置,你可以考虑将 flowable-rest webapp 包含在你自己的 webapp 中,从而只有一个 DmnEngine。
DMN 决策的版本 管理
DMN 没有版本管理的概念。这实际上是好事,因为可执行的 DMN 定义文件很可能作为开发项目的一部分存放在版本控制系统仓库中(例如 Subversion、Git 或 Mercurial)。DMN 决策的版本在部署期间创建。部署时,Flowable 会在将决策存入 Flowable 数据库之前为其分配一个版本。
对于 DMN 定义中的每个 DMN 决策,执行以下步骤来初始化属性 key、version、name 和 id:
- 定义 XML 文件中的决策 id 属性用作决策表的 key 属性。
- XML 文件中的决策 name 属性用作决策表的 name 属性。
- 首次部署具有特定 key 的决策时,分配版本 1。对于后续部署具有相同 key 的决策,版本将比当前已部署的最大版本高 1。key 属性用于区分决策。
- id 属性是一个唯一编号,用于保证集群环境中决策表缓存的决策表标识符唯一性。
以下面这个流程为例:
<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 | 我的重要决策 | 1 |
假设我们现在部署同一流程的更新版本(例如更改了某些用户任务),但流程定义的 id 保持不变。流程定义表现在将包含以下条目:
| id | key | name | version |
|---|---|---|---|
| e29d4126-ed4d-11e6-9e00-7282cbd6ce64 | myDecision | 我的重要决策 | 1 |
| e9c2a6c0-c085-11e6-9096-6ab56fad108a | myDecision | 我的重要决策 | 2 |
当调用 dmnRuleService.executeDecisionByKey("myDecision") 时,它现在将使用版本 2 的决策定义,因为这是决策定义的最新版本。
如果我们创建第二个决策(如下所定义)并将其部署到 Flowable DMN,表中将添加第三行。
<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 | 我的重要决策 | 1 |
| e9c2a6c0-c085-11e6-9096-6ab56fad108a | myDecision | 我的重要决策 | 2 |
| d317d3f7-e948-11e6-9ce6-b28c070b517d | myNewDecision | 我的重要决策 | 1 |
请注意新决策的 key 与我们第一个决策不同。尽管 name 相同(我们可能也应该改一下 name),Flowable DMN 在区分决策时只考虑 id 属性。因此新决策以版本 1 部署。
类别
DMN 部署和决策表都可以具有用户定义的类别。
部署类别可以在 API 中这样指定:
dmnRepository
.createDeployment()
.category("yourCategory")
...
.deploy();
决策表类别可以在 API 中这样指定:
dmnRepository.setDecisionTableCategory("e9c2a6c0-c085-11e6-9096-6ab56fad108a", "yourCategory");