第 5 章 使用 DMN 为 Kogito 微服务构建的设计应用逻辑


创建项目后,您可以在项目的 src/main/resources 文件夹中创建或导入 Decision Model 和 Notation (DMN)决策模型和 Drools 规则语言(DRL)业务规则。您还可以在项目的 src/main/java 文件夹中包括作为 Java 服务或提供您从决策调用的实施的 Java 类。

此流程的示例是 Kogito 微服务的基本红帽构建,可提供 REST 端点 /persons。此端点根据示例 PersonDecisions.dmn DMN 模型自动生成,以根据正在处理的数据做出决策。

业务决策包含红帽决策管理器服务的决策逻辑。您可以通过不同的方式定义业务规则和决策,如使用 DMN 模型或 DRL 规则。此流程的示例使用 DMN 模型。

先决条件

流程

  1. 在您为红帽决策管理器服务生成的 Maven 项目中,导航到 src/main/java/org/acme 文件夹,再添加以下 Person.java 文件:

    person Java 对象示例

    package org.acme;
    
    import java.io.Serializable;
    
    public class Person {
    
    	private String name;
    	private int age;
    	private boolean adult;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public boolean isAdult() {
    		return adult;
    	}
    
    	public void setAdult(boolean adult) {
    		this.adult = adult;
    	}
    
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + ", adult=" + adult + "]";
    	}
    
    }

    这个示例 Java 对象集并检索人的名称、年龄和行业状态。

  2. 导航到 src/main/resources 文件夹并添加以下 PersonDecisions.dmn DMN 决策模型:

    图 5.1. PersonDecisions DMN 决策要求图(DRD)示例

    PersonDecisions 决策图的镜像

    图 5.2. 用于 isAdult 决策的 DMN 框表达式示例

    PersonDecisions 决策表的镜像

    图 5.3. DMN 数据类型示例

    PersonDecisions 数据类型的镜像

    这个示例 DMN 模型包含一个基本的 DMN 输入节点,以及由带有自定义结构化数据类型的 DMN 决策表定义的决策节点。

    在 VSCode 中,您可以添加 Red Hat Business Automation Bundle VSCode 扩展,以使用 DMN 模型器设计决策要求图(DRD)、框表达式和数据类型。

    要快速创建这个示例 DMN 模型,您可以复制以下 PersonDecisions.dmn 文件内容:

    DMN 文件示例

    <dmn:definitions xmlns:dmn="http://www.omg.org/spec/DMN/20180521/MODEL/" xmlns="https://kiegroup.org/dmn/_52CEF9FD-9943-4A89-96D5-6F66810CA4C1" xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/" xmlns:kie="http://www.drools.org/kie/dmn/1.2" xmlns:dmndi="http://www.omg.org/spec/DMN/20180521/DMNDI/" xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/" xmlns:feel="http://www.omg.org/spec/DMN/20180521/FEEL/" id="_84B432F5-87E7-43B1-9101-1BAFE3D18FC5" name="PersonDecisions" typeLanguage="http://www.omg.org/spec/DMN/20180521/FEEL/" namespace="https://kiegroup.org/dmn/_52CEF9FD-9943-4A89-96D5-6F66810CA4C1">
      <dmn:extensionElements/>
      <dmn:itemDefinition id="_DEF2C3A7-F3A9-4ABA-8D0A-C823E4EB43AB" name="tPerson" isCollection="false">
        <dmn:itemComponent id="_DB46DB27-0752-433F-ABE3-FC9E3BDECC97" name="Age" isCollection="false">
          <dmn:typeRef>number</dmn:typeRef>
        </dmn:itemComponent>
        <dmn:itemComponent id="_8C6D865F-E9C8-43B0-AB4D-3F2075A4ECA6" name="Name" isCollection="false">
          <dmn:typeRef>string</dmn:typeRef>
        </dmn:itemComponent>
        <dmn:itemComponent id="_9033704B-4E1C-42D3-AC5E-0D94107303A1" name="Adult" isCollection="false">
          <dmn:typeRef>boolean</dmn:typeRef>
        </dmn:itemComponent>
      </dmn:itemDefinition>
      <dmn:inputData id="_F9685B74-0C69-4982-B3B6-B04A14D79EDB" name="Person">
        <dmn:extensionElements/>
        <dmn:variable id="_0E345A3C-BB1F-4FB2-B00F-C5691FD1D36C" name="Person" typeRef="tPerson"/>
      </dmn:inputData>
      <dmn:decision id="_0D2BD7A9-ACA1-49BE-97AD-19699E0C9852" name="isAdult">
        <dmn:extensionElements/>
        <dmn:variable id="_54CD509F-452F-40E5-941C-AFB2667D4D45" name="isAdult" typeRef="boolean"/>
        <dmn:informationRequirement id="_2F819B03-36B7-4DEB-AED6-2B46AE3ADB75">
          <dmn:requiredInput href="#_F9685B74-0C69-4982-B3B6-B04A14D79EDB"/>
        </dmn:informationRequirement>
        <dmn:decisionTable id="_58370567-05DE-4EC0-AC2D-A23803C1EAAE" hitPolicy="UNIQUE" preferredOrientation="Rule-as-Row">
          <dmn:input id="_ADEF36CD-286A-454A-ABD8-9CF96014021B">
            <dmn:inputExpression id="_4930C2E5-7401-46DD-8329-EAC523BFA492" typeRef="number">
              <dmn:text>Person.Age</dmn:text>
            </dmn:inputExpression>
          </dmn:input>
          <dmn:output id="_9867E9A3-CBF6-4D66-9804-D2206F6B4F86" typeRef="boolean"/>
          <dmn:rule id="_59D6BFF0-35B4-4B7E-8D7B-E31CB0DB8242">
            <dmn:inputEntry id="_7DC55D63-234F-497B-A12A-93DA358C0136">
              <dmn:text>&gt; 18</dmn:text>
            </dmn:inputEntry>
            <dmn:outputEntry id="_B3BB5B97-05B9-464A-AB39-58A33A9C7C00">
              <dmn:text>true</dmn:text>
            </dmn:outputEntry>
          </dmn:rule>
          <dmn:rule id="_8FCD63FE-8AD8-4F56-AD12-923E87AFD1B1">
            <dmn:inputEntry id="_B4EF7F13-E486-46CB-B14E-1D21647258D9">
              <dmn:text>&lt;= 18</dmn:text>
            </dmn:inputEntry>
            <dmn:outputEntry id="_F3A9EC8E-A96B-42A0-BF87-9FB1F2FDB15A">
              <dmn:text>false</dmn:text>
            </dmn:outputEntry>
          </dmn:rule>
        </dmn:decisionTable>
      </dmn:decision>
      <dmndi:DMNDI>
        <dmndi:DMNDiagram>
          <di:extension>
            <kie:ComponentsWidthsExtension>
              <kie:ComponentWidths dmnElementRef="_58370567-05DE-4EC0-AC2D-A23803C1EAAE">
                <kie:width>50</kie:width>
                <kie:width>100</kie:width>
                <kie:width>100</kie:width>
                <kie:width>100</kie:width>
              </kie:ComponentWidths>
            </kie:ComponentsWidthsExtension>
          </di:extension>
          <dmndi:DMNShape id="dmnshape-_F9685B74-0C69-4982-B3B6-B04A14D79EDB" dmnElementRef="_F9685B74-0C69-4982-B3B6-B04A14D79EDB" isCollapsed="false">
            <dmndi:DMNStyle>
              <dmndi:FillColor red="255" green="255" blue="255"/>
              <dmndi:StrokeColor red="0" green="0" blue="0"/>
              <dmndi:FontColor red="0" green="0" blue="0"/>
            </dmndi:DMNStyle>
            <dc:Bounds x="404" y="464" width="100" height="50"/>
            <dmndi:DMNLabel/>
          </dmndi:DMNShape>
          <dmndi:DMNShape id="dmnshape-_0D2BD7A9-ACA1-49BE-97AD-19699E0C9852" dmnElementRef="_0D2BD7A9-ACA1-49BE-97AD-19699E0C9852" isCollapsed="false">
            <dmndi:DMNStyle>
              <dmndi:FillColor red="255" green="255" blue="255"/>
              <dmndi:StrokeColor red="0" green="0" blue="0"/>
              <dmndi:FontColor red="0" green="0" blue="0"/>
            </dmndi:DMNStyle>
            <dc:Bounds x="404" y="311" width="100" height="50"/>
            <dmndi:DMNLabel/>
          </dmndi:DMNShape>
          <dmndi:DMNEdge id="dmnedge-_2F819B03-36B7-4DEB-AED6-2B46AE3ADB75" dmnElementRef="_2F819B03-36B7-4DEB-AED6-2B46AE3ADB75">
            <di:waypoint x="504" y="489"/>
            <di:waypoint x="404" y="336"/>
          </dmndi:DMNEdge>
        </dmndi:DMNDiagram>
      </dmndi:DMNDI>
    </dmn:definitions>

    要使用 DMN 模型器在 VSCode 中创建这个示例 DMN 模型,请按照以下步骤执行:

    1. 打开空 PersonDecisions.dmn 文件,点 DMN 模型程序右上角的 Properties 图标,并确认 DMN 模型 名称 是否已设置为 PersonDecisions
    2. 在左侧面板中,选择 DMN Input Data,将节点拖到 canvas,然后双击该节点将其命名为 Person
    3. 在左侧面板中,将 DMN Decision 节点拖到 canvas,双击节点以将其命名为 isAdult,并将它从输入节点链接到它。
    4. 选择决策节点以显示节点选项,然后单击 Edit 图标以打开 DMN boxed 表达式编辑器,以定义节点的决策逻辑。
    5. 单击 未定义表达式 字段,再选择 Decision Table
    6. 单击路由表的左上角,将 hit 策略设置为 unique
    7. 设置输入和输出列,使输入源 Person.Age 带有类型 决定了年龄限制,输出目标为 Adult with type boolean determines adult status:

      图 5.4. 的 DMN 路由表示例

      PersonDecisions 决策表的镜像
    8. 在上面的标签页选项中,选择 Data Types 选项卡,并添加以下 tPerson 结构化数据类型和嵌套数据类型:

      图 5.5. DMN 数据类型示例

      PersonDecisions 数据类型的镜像
    9. 定义数据类型后,选择 Editor 选项卡以返回到 DMN 模型程序 canvas。
    10. 选择 Person 输入节点,单击 Properties 图标,然后在 Information 项 下,将 Data type 设置为 tPerson
    11. 选择 isAdult decision node,点 Properties 图标,然后在 Information 项 下,确认 Data type 仍然设置为 布尔值。您之前在创建路由表时设置此数据类型。
    12. 保存 DMN 决策文件。

5.1. 使用 DRL 规则单元作为替代决策服务

您还可以使用作为规则单元实施的 Drools 规则语言(DRL)文件来定义此示例决策服务,作为使用 Decision Model 和 Notation (DMN)的替代选择。

DRL 规则单元是规则和执行单元的模块。规则单元收集一组规则,并声明规则所执行的事实类型。规则单元也充当每个规则组的唯一命名空间。单个规则基础可以包含多个规则单元。您通常在与单元声明相同的文件中存储单元的所有规则,以便该单元是自包含的。有关规则单元的更多信息,请参阅使用 DRL 规则设计决策服务

先决条件

流程

  1. 在示例项目的 src/main/resources 文件夹中,而不是使用 DMN 文件,请添加以下 PersonRules.drl 文件:

    PersonRules DRL 文件示例

    package org.acme
    unit PersonRules;
    
    import org.acme.Person;
    
    rule isAdult
    	when
    		$person: /person[ age > 18 ]
    	then
        modify($person) {
        	setAdult(true)
        };
    	end
    
    	query persons
    		$p : /person[ adult ]
    		end

    这个示例规则决定了任何早于 18 的人被归类为 adult。规则文件还声明该规则属于规则 unit PersonRules。构建项目时,会生成规则单元并与 DRL 文件关联。

    规则还使用 OOPath 表示法定义条件。OOPath 是 XPath 的面向对象的语法扩展,用于在处理集合和过滤限制时通过相关元素导航。

    您还可以使用传统规则模式语法以更明确的形式重写相同的规则条件,如下例所示:

    使用传统表示法的 PersonRules DRL 文件示例

    package org.acme
    unit PersonRules;
    
    import org.acme.Person;
    
    rule isAdult
    	when
    		$person: Person(age > 18) from person
    	then
        modify($person) {
        	setAdult(true)
        };
    	end
    
    	query persons
    		$p : /person[ adult ]
    		end

Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2026 Red Hat
返回顶部