1. 想要调用rest接口,先准备Docker环境,参考官网安装教程或菜鸟教程。
2. workbench的安装:
1)打开Windows PowerShell
2)输入以下命令,从镜像仓库拉取drools-workbench文件:
docker pull jboss/drools-workbench-showcase
3)输入以下命令,启动drools-workbench镜像:
docker run -p 8080:8080 -p 8001:8001 -d --name drools-workbench jboss/drools-workbench-showcase:latest
4)创建完成后,访问:http://localhost:8080/business-central
5)使用账号密码登录,账号:admin,密码:admin。
3. 使用workbench创建项目:
可参考:(六)drools可视化规则编辑器WorkBench安装 | 海元的小站 (diaohaiyuan.github.io)
1)新建space,名称为{myspace}
2)新建project,名称为{project}
3)新建软件包,名称为{fact}
4)新建数据对象,名称为Person,内容如下:
package com.myspace.project.fact;
/**
* This class was automatically generated by the data modeler tool.
*/
public class Person implements java.io.Serializable {
static final long serialVersionUID = 1L;
private java.lang.String id;
private java.lang.String name;
private int age;
private int score;
public Person() {
}
public java.lang.String getId() {
return this.id;
}
public void setId(java.lang.String id) {
this.id = id;
}
public java.lang.String getName() {
return this.name;
}
public void setName(java.lang.String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return this.score;
}
public void setScore(int score) {
this.score = score;
}
public Person(java.lang.String id, java.lang.String name, int age, int score) {
this.id = id;
this.name = name;
this.age = age;
this.score = score;
}
}
5)新建drl规则文件,名称为person,内容如下:
package com.myspace.project.fact;
import com.myspace.project.fact.Person;
rule "rule_person_1"
when
$person:Person(age<=6);
then
$person.setName("zionw");
$person.setScore(0);
System.out.println("this is a child @_"+$person.getName()+$person.getScore());
end
rule "rule_person_2"
when
$person:Person(age>6&&age<=18);
then
$person.setScore(40);
$person.setName("RWESTBROOK");
System.out.println("this is a NBA player @_"+$person.getName()+$person.getScore());
end
rule "rule_person_3"
when
$person:Person(age>18&&age<=30);
then
$person.setScore(60);
end
rule "rule_person_4"
when
$person:Person(age>30&&age<=50);
then
$person.setScore(95);
end
rule "rule_person_5"
when
$person:Person(age>50&&age<=70);
then
$person.setScore(80);
end
rule "rule_person_6"
when
$person:Person(age>70);
then
$person.setScore(20);
end
6)新建测试场景,名称为{test1},如下:
7)运行测试场景:
8)查看控制台输出:
9)设置KieBase和KieSession(KieSession的名称要记住,需要用到,此处是{ksession}):
4. 安装kie-server:
1)打开Windows PowerShell
2)输入以下命令,从镜像仓库拉取kie-server镜像
docker pull jboss/kie-server-showcase
3)输入以下命令,启动kie-server并关联到workbench
docker run -p 8180:8080 -d --name kie-server --link drools-workbench:kie_wb jboss/kie-server-showcase:latest
4)在workbench的server中查看workbench和kie-server是否已经关联,已关联如下图
5. 在IDEA中通过单元测试,测试REST接口的调用:
1)新建maven项目,导入以下依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.31.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.31.0.Final</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.22</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.0</version>
</dependency>
<dependency>
<groupId>org.kie.server</groupId>
<artifactId>kie-server-client</artifactId>
<version>7.67.0.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- Apache Tapestry -->
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-core</artifactId>
<version>${tapestry-version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- CoffeeScript & Less support, plus resource minification -->
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-webresources</artifactId>
<version>${tapestry-version}</version>
<scope>compile</scope>
</dependency>
<!-- Unit Testing -->
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-test</artifactId>
<version>${tapestry-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<!-- Miscellaneous -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j-version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j-version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>${yasson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
2)新建Person类,路径和内容都要跟workbench中定义的完全一样,此处是com.myspace.project.fact.Person
3)新建单元测试的类,需要import的包有
import com.myspace.project.fact.Person;
import org.junit.Test;
import org.kie.api.KieServices;
import com.alibaba.fastjson.JSONObject;
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.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 java.util.LinkedList;
import java.util.List;
4)编写测试方法:
@Test
public void test3() throws Exception{
String SERVER_URL = "http://localhost:8180/kie-server/services/rest/server"; //server路径
String PASSWORD = "admin"; // 用户名
String USERNAME = "admin"; // 密码
String KIE_CONTAINER_ID = "project_1.0.0"; // 容器id(此容器id可进入 http://localhost:8180/kie-server/services/rest/server/containers 中查看)
// KisService 配置信息设置
KieServicesConfiguration kieServicesConfiguration =
KieServicesFactory.newRestConfiguration(SERVER_URL, USERNAME, PASSWORD, 10000L);
kieServicesConfiguration.setMarshallingFormat(MarshallingFormat.JSON);
// 创建规则服务客户端
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(kieServicesConfiguration);
RuleServicesClient ruleServicesClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
// 规则输入条件
Person person = new Person();
person.setAge(19);
person.setName("mt");
person.setId("wwwID");
// 命令定义,包含插入数据,执行规则
KieCommands kieCommands = KieServices.Factory.get().getCommands();
List<Command<?>> commands = new LinkedList<Command<?>>();
commands.add(kieCommands.newInsert(person, "Person"));
commands.add(kieCommands.newFireAllRules());
ServiceResponse<ExecutionResults> results = ruleServicesClient.executeCommandsWithResults(KIE_CONTAINER_ID,
kieCommands.newBatchExecution(commands,"ksession")); // 此处为KieSession的名称
// 返回值读取
Person value = (Person) results.getResult().getValue("Person");
System.out.println("======从这里开始======");
System.out.println(JSONObject.toJSON(value).toString());
System.out.println("======到这里结束======");
// String msg = (String) results.getResult().getValue("hello");
System.out.println("根据输入的条件,返回的值为:"+value.getScore());
}
5)执行单元测试
6. 遇到的问题
1)docker上的workbench经常掉线,需要经常重启,非常不方便。
2)导入pom文件依赖的时候,踩了一些坑,导入的版本不合适,以上的版本均合适版本。
3)idea中的Person对象的路径和内容一定要跟WorkBench中的完全一样,否则识别不出来。
4)当对drl规则文件进行修改后(已build和deploy-覆盖),在workbench中进行场景测试并且通过,但通过单元测试调用rest接口并不能触发修改后的规则,触发的依然是修改前的规则。
解决方法:
(1)在docker中把kie-server容器移除
(2)重新使用 4 - 3)中命令添加kie-server关联workbench
(3)重新执行单元测试,通过,执行修改后的规则
5)想知道是否已触发规则,可以这样操作:
(1)在规则文件中写System.out.println("打印测试文字!");
(2)在PowerShell输入以下命令,记下对应的workbench的容器id(container_id)
docker ps -a
(3)再输入以下命令,查看workbench的控制台信息
docker logs -f -t --tail 10 容器id
(4)方法2:直接输入
docker logs -f drools-workbench
7. 总结:
实现本demo的过程中遇到的问题,可以根据报错的信息到百度寻找解决方法,由于网络上对于kie的rest接口的参考信息较少,可以参考官方文档(19章):Drools Documentation (jboss.org)