Linux下docker部署drools并集成项目使用

Linux下docker部署drools并集成项目使用

一、背景介绍

上一篇文章是对规则引擎的基本介绍,本篇文章是对于drools规则引擎的基本使用。

二、 思路方案

前提:首先保证主机联网、有docker环境、保证Linux空闲内存在4G左右

三、过程

一、搭建WorkBench

  1. 拉取镜像到本地
docker pull jboss/drools-workbench-showcase
  1. 启动镜像
docker run -p 8080:8080 -p 8001:8001 -d --name drools-workbench jboss/drools-workbench-showcase:latest
  1. 访问WorkBench
    浏览器访问http://ip:8080/business-central

在这里插入图片描述
4. workbench相关的账号密码:

USER PASSWORD ROLE
*********************************************
admin admin admin,analyst,kiemgmt
krisv krisv admin,analyst
john john analyst,Accounting,PM
sales-rep sales-rep analyst,sales
katy katy analyst,HR

二、搭建Kie-Server

  1. 拉取镜像到本地
docker pull jboss/kie-server-showcase
  1. 然后kie-server启动并与workbench关联
docker run -p 8180:8080 -d --name kie-server --link drools-workbench:kie_wb jboss/kie-server-showcase:latest
  1. 访问kie-server
 http://ip:8180/kie-server/services/rest/server/

在这里插入图片描述

三、Spring Boot项目整合Drools规则引擎

Spring boot整合Drools之后的最终效果是我在Drools workbench中修改对应的规则。然后将其发布到kie-server上。不用重启的应用程序,该规则可以在程序运行中生效。

示例:

在一个业务场景中我们需要多人员的上次的考核时间进行判断。如果考核时间超过了11个月则该人员需要重新考核。由于对于考核时间可能会根据业务调整发生改变,比如由于需要大家对人员的质量的保证这个时候需要缩短考核时间到5个月。及考核时间超过5个月之后该人员需要重新考核。针对于这样的业务场景我们将考核时间这个规则抽离到drools规则引擎中。

  1. 在spring boot项目中新建数据实体。
    数据实体里面的属性包括人员的基本数据,和上次考核时间以及是否需要重新考核的accessFlag属性。
    在这里插入图片描述

  2. 在drools workbench中创建项目并创建实体和配置规则,最后发布服务。
    1.进入workbench创建项目
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    2.创建资产——数据对象
    先创建数据对象,必须与项目中的数据对象保持一致(名称和包路径)
    在这里插入图片描述
    项目中的数据对象
    数据对象名称和软件包,分别对应项目中的数据对象名称和包路径
    软件包可以通过添加资产-软件包补充,最终创建出与项目中数据对象相同的包路径。
    在这里插入图片描述
    在这里插入图片描述
    3.编写数据对象的代码
    将程序中的数据对象的属性和方法复制到源代码中,并保存。
    在这里插入图片描述
    4.编写对应的规则
    这里考虑到需要一个可视化界面便于修改规则所以选用了决策表。
    在这里插入图片描述
    决策表的名称和软件包,可以任意修改。
    在这里插入图片描述
    首选引入对应的数据对象
    在这里插入图片描述
    在这里插入图片描述
    根据自己项目的要求,编写对应的规则。
    这里我只是做一个示例:
    添加对应的列
    在这里插入图片描述
    先选择Add a Condition 表示添加一个条件
    在这里插入图片描述
    选择计算类型
    在这里插入图片描述
    选择需要参与计算的字段
    在这里插入图片描述
    选择操作符
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    点击完成之后,可以再Columns中查看
    在这里插入图片描述
    再选择条件通过之后的执行,选择Set the value of a field
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
再点击Model可以看到可视化界面
在这里插入图片描述
选择增加一行
在这里插入图片描述
补充上我们的规则数据
在这里插入图片描述

点击源代码就可以看到生成的代码,之后点击保存
在这里插入图片描述
5.设置kie bases将该项目发布到kie-server中
在这里插入图片描述
在这里插入图片描述
6.进行构建和发布
在这里插入图片描述
7.查看kie-server
在这里插入图片描述
在这里插入图片描述
访问kie-server容器信息

http://ip:8180/kie-server/services/rest/server/containers

页面中能够找到对应的容器,表示已经发布到kie-server中了。
在这里插入图片描述

  1. 项目引入依赖:
<!-- kie-server -->
<dependency>
    <groupId>org.kie.server</groupId>
    <artifactId>kie-server-client</artifactId>
<drools.version>7.73.0.Final</drools.version>
</dependency>
<dependency>
    <groupId>org.kie.server</groupId>
    <artifactId>kie-server-api</artifactId>
<drools.version>7.73.0.Final</drools.version>
</dependency>
  1. 填写配置文件:
drools服务
kie-server:
url: http://ip:8180/kie-server/services/rest/server
username: ***
password: ***
#配置容器名
containerId: test_1.0.0-SNAPSHOT
timeout: 1000
#在kie-server中配置的session
session: session6
#session: hello-session
  1. 定义资源类


import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;

/**
 * kie-server相关配置
 *
 * @author 
 * @date 2023/9/6 11:16
 **/
@Data
@RefreshScope
@ConfigurationProperties(prefix = "kie-server")
public class KieServerProperties {

    /**
     * 地址
     */
    private String url;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 容器
     */
    private String containerId;

    /**
     * 过期时间
     */
    private String timeout;

    /**
     * 会话名称
     */
    private String session;
}

  1. 封装kie server服务类


import org.kie.api.KieServices;
import org.kie.api.command.Command;
import org.kie.api.command.KieCommands;
import org.kie.api.runtime.ExecutionResults;
import org.kie.server.api.marshalling.MarshallingFormat;
import org.kie.server.api.model.KieServiceResponse;
import org.kie.server.api.model.ServiceResponse;
import org.kie.server.client.KieServicesClient;
import org.kie.server.client.KieServicesConfiguration;
import org.kie.server.client.KieServicesFactory;
import org.kie.server.client.RuleServicesClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 远程kie-server相关服务
 *
 * @author 
 * @date 2023/9/6 13:51
 **/
@Service
public class KieClientService {

    private static final Logger log = LoggerFactory.getLogger(KieClientService.class);

    @Autowired
    private KieServerProperties kieServerProperties;

    /**
     * 获取命令对象
     *
     * @return 命令对象
     */
    public KieCommands getKieCommands() {
        return KieServices.Factory.get().getCommands();
    }

    /**
     * 获取存放命令的LinkedList
     *
     * @return 存放命令的LinkedList
     */
    public List<Command<?>> getKieCommandList() {
        return new LinkedList<>();
    }

    /**
     * 执行规则
     *
     * @param commandList 存放命令的LinkedList
     * @param kieCommands 命令对象
     * @return 执行结果
     */
    public ExecutionResults executeCommands(List<Command<?>> commandList, KieCommands kieCommands) {
        RuleServicesClient client = this.getClient();
        ServiceResponse<ExecutionResults> serviceResponse = client.executeCommandsWithResults(kieServerProperties.getContainerId(),
                kieCommands.newBatchExecution(commandList, kieServerProperties.getSession()));
        if (serviceResponse == null || !KieServiceResponse.ResponseType.SUCCESS.equals(serviceResponse.getType())) {
            log.error("调用kie-server失败");
            throw ServiceExceptionUtil.exception(new ErrorCode(500, "调用kie-server失败"));
        }
        return serviceResponse.getResult();
    }

    /**
     * 根据配置获取连接
     *
     * @return 与kie-server的连接
     */
    private RuleServicesClient getClient() {
        //配置信息
        KieServicesConfiguration kieServicesConfiguration = KieServicesFactory.newRestConfiguration(
                kieServerProperties.getUrl(), kieServerProperties.getUsername(),
                kieServerProperties.getPassword(), Long.parseLong(kieServerProperties.getTimeout()));
        kieServicesConfiguration.setMarshallingFormat(MarshallingFormat.JSON);

        RuleServicesClient servicesClient;
        try {
            //创建规则服务客户端
            KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(kieServicesConfiguration);
            servicesClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
        } catch (Exception exception) {
            log.error(exception.getMessage());
            throw ServiceExceptionUtil.exception(new ErrorCode(500, "无法建立到kie-server的连接"));
        }
        if (servicesClient == null) {
            log.error("servicesClient为null");
            throw ServiceExceptionUtil.exception(new ErrorCode(500, "无法建立到kie-server的连接"));
        }
        return servicesClient;
    }

    /**
     * 将list插入kie-server工作内存并处理
     *
     * @param list 要插入的数据列表
     * @param <T>  数据的类型
     * @return 原列表,内容已改变
     */
    public <T> List<T> processList(List<T> list) {
        if (StringUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<Command<?>> kieCommandList = this.getKieCommandList();
        KieCommands kieCommands = this.getKieCommands();
        for (int i = 0; i < list.size(); i++) {
            kieCommandList.add(kieCommands.newInsert(list.get(i), String.valueOf(i)));
        }
        ExecutionResults executionResults = this.executeCommands(kieCommandList, kieCommands);
        for (int i = 0; i < list.size(); i++) {
            BeanUtils.copyProperties(executionResults.getValue(String.valueOf(i)), list.get(i));
        }
        return list;
    }
}

  1. 编写测试代码
@SpringBootTest
public class TrainingApplicationTest {

    @Autowired
    private KieClientService kieClientService;

    @Test
    public void test(){
        QualificationAssessmentDTO qualificationAssessmentDTO=new QualificationAssessmentDTO();
        qualificationAssessmentDTO.setScore(2.4);
        qualificationAssessmentDTO.setType("飞行签派员");
        qualificationAssessmentDTO.setIntervalTime(12);

        KieCommands kieCommands = kieClientService.getKieCommands();
        List<Command<?>> kieCommandList = kieClientService.getKieCommandList();
        kieCommandList.add(kieCommands.newInsert(qualificationAssessmentDTO,"qualificationAssessmentDTO"));
        ExecutionResults executionResults = kieClientService.executeCommands(kieCommandList, kieCommands);
        QualificationAssessmentDTO dto = (QualificationAssessmentDTO) executionResults.getValue("qualificationAssessmentDTO");
        System.out.println(JsonUtils.toJsonString(dto));

    }







}

测试结果:
在这里插入图片描述
在workbench中修改判断条件的值为5,并重新发布。
可以发现规则已经生效。
在这里插入图片描述

四、总结

drools规则引擎运行逻辑:在drools-workBench中编写对应的规则最后将其发布到kie-server中。在我们程序中集成kie-Server将我们需要进行规则判断的model传输到kie-server进行规则判断。kie-server再将修改之后的mode传输到我们的应用程序中。由于规则和规则的判断是放到drools-workbench和kie-server中。所以当规则发生变动,并不会影响到原有的应用程序的正常运行。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王卫——David

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值