搜索

第 5 章 使用 DMN 为红帽构建 Kogito 微服务设计应用程序逻辑

download PDF

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

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

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

先决条件

流程

  1. 在您为 Red Hat Process Automation Manager 服务生成的 Maven 项目中,导航到 src/main/java/org/acme 文件夹并添加以下 Person.java 文件:

    个人 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 对象集并检索一个人的名称、年龄和 adult 状态。

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

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

    个人决策图的镜像

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

    个人决策表的镜像

    图 5.3. DMN 数据类型示例

    角色数据类型的镜像

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

    在 VS Code 中,您可以添加 Red Hat Business Automation Bundle VS Code 扩展,以通过 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 型号在 VS Code 中创建此示例 DMN 模型,请按照以下步骤操作:

    1. 打开空 PersonDecisions.dmn 文件,点 DMN 模型器右上角的 Properties 图标,并确认 DMN 模型名称已设为 PersonDecisions
    2. 在左侧面板中,选择 DMN Input Data,将节点拖到 canvas 中,然后双击该节点将其命名为 Person
    3. 在左侧面板,将 DMN 决策 节点拖放到 canvas 中,双击节点将其命名为 Adult,并从输入节点链接到其中。
    4. 选择决策节点以显示节点选项,并点击 Edit 图标打开 DMN 框的表达式编辑器,以定义节点的决策逻辑。
    5. 单击 undefined 表达式 字段,再选择 Decision Table
    6. 单击决策表的左上角,将点击策略设置为 unique
    7. 设置输入和输出列,使输入源 Person.Age 使用类型 编号 决定年龄限制,输出目标为:带有类型布尔值的 isAdult (类型 布尔值 )决定了dult 状态:

      图 5.4. 对 isAdult 决策的 DMN 决策示例

      个人决策表的镜像
    8. 在 upper 选项卡中,选择 Data Types 选项卡并添加以下 tPerson 结构化数据类型和嵌套的数据类型:

      图 5.5. DMN 数据类型示例

      角色数据类型的镜像
    9. 定义数据类型后,选择 Editor 选项卡以返回到 DMN 模型器。
    10. 选择 Person 输入节点,单击 Properties 图标,然后在 Information 项 下,将数据类型设置为 tPerson
    11. 选择 isAdult 决策节点,单击 Properties 图标,然后在 Information 项 下,确认 数据类型 是否仍然设置为 布尔值。以前,在创建决策表时设置此数据类型。
    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 的人被归类为dult。规则文件还声明该规则属于规则单元 PersonRules。构建项目时,将生成规则单元并将其与 DRL 文件关联。

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

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

    使用传统表示法的 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 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

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

© 2024 Red Hat, Inc.