第 78 章 KIE 会话
在 Red Hat Process Automation Manager 中,KIE 会话存储和执行运行时数据。如果您为项目定义了 KIE 模块描述符文件(kmodule.xml)中的 KIE 会话,则 KIE 会话是从 KIE 容器创建的 KIE 会话。
kmodule.xml 文件中的 KIE 会话配置示例
<kmodule>
...
<kbase>
...
<ksession name="KSession2_1" type="stateless" default="true" clockType="realtime">
...
</kbase>
...
</kmodule>
KIE 基础是您在 KIE 模块描述符文件(kmodule.xml)中定义的存储库,包含 Red Hat Process Automation Manager 中的所有规则、进程和其他业务资产。
kmodule.xml 文件中的 KIE 基础配置示例
<kmodule>
...
<kbase name="KBase2" default="false" eventProcessingMode="stream" equalsBehavior="equality" declarativeAgenda="enabled" packages="org.domain.pkg2, org.domain.pkg3" includes="KBase1">
...
</kbase>
...
</kmodule>
KIE 会话可以是无状态或有状态的。在无状态 KIE 会话中,之前调用 KIE 会话(之前会话状态)的数据在会话调用之间被丢弃。在有状态 KIE 会话中,数据会被保留。您使用的 KIE 会话类型取决于您的项目要求,以及如何保留来自不同资产调用的数据。
78.1. 无状态 KIE 会话 复制链接链接已复制到粘贴板!
无状态 KIE 会话是一个会话,它不会随着时间进行迭代更改。在无状态 KIE 会话中,之前调用 KIE 会话的数据(前面的会话状态)在会话调用之间丢弃,而在有状态 KIE 会话中,数据会被保留。无状态 KIE 会话的行为与一个功能相似,其生成的结果由 KIE 基础的内容决定,并由传递给 KIE 会话的数据,以便在特定时间点上执行。KIE 会话没有之前传递给 KIE 会话的任何数据的内存。
无状态 KIE 会话通常用于以下用例:
- 验证,例如验证人是否有资格获得电池
- 计算, 如计算一个月子(mortgage Premium)
- 路由和过滤,例如将传入的电子邮件排序到文件夹中,或向目的地发送传入的电子邮件
例如,请考虑以下驱动程序的许可证数据模型和 DRL 规则示例:
驱动程序许可证应用程序的数据模型
public class Applicant {
private String name;
private int age;
private boolean valid;
// Getter and setter methods
}
驱动程序许可证应用程序的 DRL 规则示例
package com.company.license
rule "Is of valid age"
when
$a : Applicant(age < 18)
then
$a.setValid(false);
end
有效期限规则不限于 18 年以上的任何应用程序期限。当 Applicant 对象插入到决策引擎中时,决策引擎会评估每个规则的限制,并搜索匹配项。"objectType" 约束始终表示,之后评估任何数量的显式字段约束。变量 $a 是一个绑定变量,在规则结果中引用匹配对象。
数字符号($)是可选的,有助于区分变量名称和字段名称。
在本例中,Red Hat Process Automation Manager 项目的 ~/resources 文件夹中的 ~/resources 文件夹中的示例规则和所有其他文件使用以下代码构建:
创建 KIE 容器
KieServices kieServices = KieServices.Factory.get();
KieContainer kContainer = kieServices.getKieClasspathContainer();
此代码编译类路径上找到的所有规则文件,并在 KieContainer 中添加此编译(一个 KieModule 对象)的结果。
最后,StatelessKieSession 对象从 KieContainer 实例化,并根据指定的数据执行:
实例化无状态 KIE 会话并输入数据
StatelessKieSession kSession = kContainer.newStatelessKieSession();
Applicant applicant = new Applicant("Mr John Smith", 16);
assertTrue(applicant.isValid());
ksession.execute(applicant);
assertFalse(applicant.isValid());
在无状态 KIE 会话配置中,exec () 调用充当实例化 KieSession 对象的组合方法,添加所有用户数据并执行用户数据,调用 fireAllRules (),然后调用 dispose ()。因此,使用无状态 KIE 会话,您不需要在会话调用有状态 KIE 会话后调用 fireAllRules () 或调用 dispose ()。
在这种情况下,指定的 applicant 位于 18 的年龄下,因此应用程序会下降。
有关更复杂的用例,请参见以下示例。本例使用无状态 KIE 会话,并对可迭代的对象列表(如集合)执行规则。
为驱动程序许可证应用程序扩展数据模型
public class Applicant {
private String name;
private int age;
// Getter and setter methods
}
public class Application {
private Date dateApplied;
private boolean valid;
// Getter and setter methods
}
为驱动程序许可证应用程序展开的 DRL 规则集
package com.company.license
rule "Is of valid age"
when
Applicant(age < 18)
$a : Application()
then
$a.setValid(false);
end
rule "Application was made this year"
when
$a : Application(dateApplied > "01-jan-2009")
then
$a.setValid(false);
end
在无状态 KIE 会话中扩展 Java 源
StatelessKieSession ksession = kbase.newStatelessKnowledgeSession();
Applicant applicant = new Applicant("Mr John Smith", 16);
Application application = new Application();
assertTrue(application.isValid());
ksession.execute(Arrays.asList(new Object[] { application, applicant }));
assertFalse(application.isValid());
ksession.execute
(CommandFactory.newInsertIterable(new Object[] { application, applicant }));
List<Command> cmds = new ArrayList<Command>();
cmds.add(CommandFactory.newInsert(new Person("Mr John Smith"), "mrSmith"));
cmds.add(CommandFactory.newInsert(new Person("Mr John Doe"), "mrDoe"));
BatchExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(cmds));
assertEquals(new Person("Mr John Smith"), results.getValue("mrSmith"));
- 1
- 对
Arrays.asList ()方法生成的对象的可迭代集合执行规则的方法。每个集合元素都会在执行任何匹配规则前插入。execute (Object object)和执行(Iterable objects)方法围绕来自BatchExecutor接口的execute (Command command)方法进行包装程序。 - 2
- 使用
CommandFactory接口执行可划分的对象集合。 - 3
BatchExecutor和CommandFactory配置,用于处理许多不同的命令或结果输出标识符。CommandFactory接口支持您可以在BatchExecutor中使用的其他命令,如StartProcess、Query和SetGlobal。
78.1.1. 无状态 KIE 会话中的全局变量 复制链接链接已复制到粘贴板!
StatelessKieSession 对象支持全局变量(全局),您可以将它们配置为作为会话范围的全局范围、委派全局或执行范围全局。
会话范围全局: 对于会话范围全局,您可以使用方法
get返回提供对 KIE 会话全局访问权限的 Globals 实例。这些全局组用于所有执行调用。请谨慎与可变全局使用,因为可以在不同的线程中同时执行调用。Globals()会话范围全局
import org.kie.api.runtime.StatelessKieSession; StatelessKieSession ksession = kbase.newStatelessKieSession(); // Set a global `myGlobal` that can be used in the rules. ksession.setGlobal("myGlobal", "I am a global"); // Execute while resolving the `myGlobal` identifier. ksession.execute(collection);-
委托 全局: 为了委托全局值,您可以为全局分配值(使用
setGlobal (String, Object)),以便该值存储在将标识符映射到值的内部集合中。此内部集合中的标识符优先于任何提供的委托。如果无法在此内部集合中找到标识符,则使用委派全局(若有)。 -
执行范围全局: 对于执行范围全局,您可以使用
Command对象设置传递给CommandExecutor接口以进行特定执行的全局解析。
CommandExecutor 接口还允许您使用全局、插入的事实和查询结果的标识符导出数据:
超出全局、插入的事实和查询结果的标识符
import org.kie.api.runtime.ExecutionResults;
// Set up a list of commands.
List cmds = new ArrayList();
cmds.add(CommandFactory.newSetGlobal("list1", new ArrayList(), true));
cmds.add(CommandFactory.newInsert(new Person("jon", 102), "person"));
cmds.add(CommandFactory.newQuery("Get People" "getPeople"));
// Execute the list.
ExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(cmds));
// Retrieve the `ArrayList`.
results.getValue("list1");
// Retrieve the inserted `Person` fact.
results.getValue("person");
// Retrieve the query as a `QueryResults` instance.
results.getValue("Get People");