使用Kogito实现BPM业务流程自动化

在本文中,我们了解了Kogito作为创建云原生业务应用程序的自动化工具。该项目目前仍在进行大量的开发,因此界面也在不断变化。我们可以使用Kogito Examples Repository上的示例作为指南。

Apache Kogito是一个用于构建云原生业务应用程序的开源平台。在本教程中,我们将学习如何使用它以及如何使用Kogito集成构建应用程序。

什么是Kogito?
与传统的业务流程管理(BPM)工具不同,Kogito采用了微服务优先和Kubernetes原生的方法。它允许开发人员将业务流程和规则建模、执行和监控为可以独立扩展的独立服务。

Kogito的架构深受领域特定语言(DSL)和行业标准的影响,如BPMN 2.0(业务流程模型和符号)和DMN(决策模型和符号)。这些不仅仅是可视化的表示-它们成为可执行的模型,直接集成到应用程序中。

“Kogito”这个名字来源于拉丁语“Cogito”(“我认为”),而“K”指的是Kubernetes和Kogito起源于的知识就是一切(KIE)开源业务自动化项目。

Kogito背后的核心技术
Kogito是两个成熟项目的现代演变,这两个项目也是KIE的一部分:

  • jBPM -用于建模和执行业务流程(使用业务流程模型和表示法/ BPMN)
  • Drools -一个强大的规则引擎(用于使用Drules规则语言/ DRL或决策模型和符号/ DMN的决策逻辑)
Kogito通过提供云原生打包、Quarkus和Spring靴子支持、DevOps就绪以及与Prometheus、Grafana和OpenAPI等工具的无缝集成,扩展并现代化了这些技术。

关键特征
1. Cloud-Native和Kubernetes-First
Kogito应用程序被设计为在Kubernetes上原生运行。这意味着自动可扩展性,容器化和弹性是内置的。开发人员可以独立部署服务,并根据需求变化调整决策或工作流逻辑。

2.事件驱动架构
Kogito通过与Apache Kafka的集成支持事件驱动设计,从而实现服务之间的异步通信。这对于能够近乎实时地响应业务事件的反应式、解耦的系统来说是必不可少的。

3.模型驱动开发MDA
Kogito强调模型驱动的开发,使用可视化工具和BPMN和DMN编辑器。这些模型不仅仅是文档-它们被编译成可执行的服务。

4.以机器人为中心的工具
Kogito提供VS Code插件、Kogito Tooling等在线编辑器,以及Quarkus和Spring靴子等框架的原生支持,帮助Java开发人员以最小的摩擦构建自动化服务。

5. DevOps-Ready
得益于自动化代码生成、容器化部署和GitOps兼容性等功能,Kogito可以轻松融入CI/CD管道。它支持使用OpenTelemetry进行跟踪,使用Prometheus和Grafana进行监控,以及与Kubernetes的活跃性和就绪性探针兼容的健康检查。

用例
Kogito在基于规则的决策和工作流编排至关重要的领域大放异彩。一些典型的使用案例包括:

  • 贷款和保险索赔处理-自动执行复杂的资格、审批和路由规则
  • 客户入职-通过合规性检查和批准管理多步骤工作流
  • 供应链管理-根据与库存、物流和供应商行为相关的规则触发操作
  • 医疗保健工作流程-处理患者旅程、文档和规则驱动的治疗方案

案例
让我们创建一个小示例来演示Kogito如何工作。我们需要一个基于规则的信用决策服务,其规则如下:

  1. 贷款申请需要包含申请人的姓名和年龄以及他们的收入和现有债务。
  2. 如果申请人未满18岁,我们将拒绝申请,因为申请人的未成年人身份。
  3. 如果信用评分低于700分,我们会拒绝申请,因为信用不好。
  4. 如果申请人的现有债务高于收入的50%,我们会拒绝其申请,因为其信用不佳。
  5. 否则,申请被批准。

例如,让我们向服务发送一个应用程序列表:

{
    "applications": [
        {
           
"id": "1fe1aED7-ca61-Eeb4-78fA-55f5E568Aa8b",
           
"person": {
               
"name": "Mr Smith",
               
"age": 25
            },
           
"conditions": {
               
"creditScore": 400,
               
"income": 30000,
               
"debt": 0
            }
        },
        {
           
"id": "b2c0a268-aa6f-44b8-b644-f466cb35504c",
           
"person": {
               
"name": "Mrs Doe",
               
"age": 35
            },
           
"conditions": {
               
"creditScore": 700,
               
"income": 70000,
               
"debt": 3000
            }
        }
    ]
}

让我们看看结果:

[
    {
        "id": "1fe1aed7-ca61-eeb4-78fa-55f5e568aa8b",
       
"decision": "rejected-not-creditworthy"
    },
    {
       
"id": "b2c0a268-aa6f-44b8-b644-f466cb35504c",
       
"decision": "approved"
    }
]

1. Drools规则
我们可以使用Drools及其规则语言(DSL)来实现示例。规则文件可能如下所示:

package com.baeldung.kogito.rules
unit LoanApplicationUnit
import com.baeldung.kogito.rules.model.LoanApplication
import com.baeldung.kogito.rules.model.Person
import com.baeldung.kogito.rules.model.Conditions
import com.baeldung.kogito.rules.model.Decision
rule "only-adults"
    salience 10
    when
        $application: /applications[
            person.age < 18
        ]
    then
        modify($application){
            setDecision(Decision.REJECTED_UNDERAGE)
        }
end
rule
"Good Credit Score And High Income"
    when
        $application: /applications[
            person.age >= 18,
            conditions.creditScore >= 700,
            conditions.income > 2*conditions.debt
        ]
    then
        modify($application){
            setDecision(Decision.APPROVED)
        }
end
rule
"Low Credit Score Or High Debt"
    when
        $application: /applications[
            person.age >= 18,
            (
                conditions.creditScore < 700 ||
                conditions.income <= 2*conditions.debt
            )
        ]
    then
        modify($application){
            setDecision(Decision.REJECTED_NOT_CREDITWORTHY)
        }
end
query applications
      $result: /applications
end


如果我们希望它作为一个带有HTTP/REST端点的微服务运行,我们只需创建一个Quarkus项目并将其添加到pom.xml中:

<project>
    <dependencyManagement>
        <dependencies>
            <!-- ... -->
            <dependency>
                <groupId>org.kie.kogito</groupId>
                <artifactId>kogito-bom</artifactId>
                <version>${kogito.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- ... -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.kie.kogito</groupId>
            <artifactId>kogito-quarkus-rules</artifactId>
        </dependency>
    </dependencies>
    <properties>
        <kogito.version>2.44.0.Alpha</kogito.version>
    </properties>
</project>

解释:

  • 给定的Kogito版本必须支持Quarkus 3
  • Kogito仅支持Quarkus RESTEasy扩展,但不支持Quarkus REST扩展
然后,将Drools规则文件放在src/main/resources下。Kogito会自动检测到它,因此我们可以运行Quarkus应用程序并发送请求-通过curl,例如:

curl -X 'POST' \
  'http://localhost:8080/applications' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
       
"applications": [ 
            { 
               
"id": "1fe1aED7-ca61-Eeb4-78fA-55f5E568Aa8b",
               
"person": { 
                   
"name": "Mr Smith"
                   
"age": 25 
                }, 
               
"conditions": { 
                   
"creditScore": 400, 
                   
"income": 30000, 
                   
"debt": 0 
                } 
            }, 
            { 
               
"id": "b2c0a268-aa6f-44b8-b644-f466cb35504c"
               
"person": { 
                   
"name": "Mrs Doe"
                   
"age": 35 
                }, 
               
"conditions": { 
                   
"creditScore": 700, 
                   
"income": 70000, 
                   
"debt": 3000 
                } 
            } 
        ] 
    }'

正如我们所看到的,它在没有任何Quarkus代码的情况下工作。我们可以使用现有的生态系统来构建Quarkus微服务并将其部署到任何云环境中。

自定义API
Kogito是一种快速创建REST资源的方法,无需编写任何代码。但是,我们自己为API编写代码可能是有意义的。通过这种方式,我们可以定义自定义端点的URL和JSON模式以进行数据交换。

在发送请求时,我们可以看到响应体包含来自请求体的全部数据,并补充了信用决策。我们可能会想添加杰克逊或JSON-B注释来定义只读和只写属性,但这对于Drools规则模型类来说不是一个好主意,因为Drools引擎在内部对它们进行JSON序列化和JSON序列化,所以这不会起作用。

因此,我们可以创建自定义REST资源和DTO,使用映射器(例如,使用MapStruct)将DTO映射到Drools规则模型,并调用使用Drools规则引擎的域服务。这样的域服务可能看起来像:

import org.kie.kogito.incubation.application.AppRoot;
import org.kie.kogito.incubation.common.MapDataContext;
import org.kie.kogito.incubation.rules.RuleUnitIds;
import org.kie.kogito.incubation.rules.services.RuleUnitService;
// ...
@ApplicationScoped
public class LoanApplicationService {
    @Inject
    AppRoot appRoot;
    @Inject
    RuleUnitService ruleUnitService;
    public Stream<LoanApplication> evaluate(LoanApplication... applications) {
        var queryId = appRoot
          .get(RuleUnitIds.class)
          .get(LoanApplicationUnit.class)
          .queries()
          .get(
"applications");
        var ctx = MapDataContext
          .of(
            Map.of(
"applications", applications)
          );
        return ruleUnitService
          .evaluate(queryId, ctx)
          .map(
            result -> result
              .as(MapDataContext.class)
              .get(
"$result", LoanApplication.class)
            );
    }
}

正如我们所看到的,我们使用的Kogito API仍处于孵化状态。但是这个API允许我们将Drools规则引擎集成到任何Quarkus应用程序中。