第 81 章 KIE 会话
在 Red Hat Process Automation Manager 中,KIE 会话存储并执行运行时数据。如果您已在 KIE 模块描述符文件(kmodule.xml
)中定义 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 会话的类型取决于您的项目要求以及希望数据来自不同资产调用的数据。
81.1. 无状态 KIE 会话
无状态 KIE 会话是一种会话,不使用推断时间对事实进行迭代更改。在无状态 KIE 会话中,来自之前调用 KIE 会话(之前会话状态)中的数据会在会话调用之间丢弃,而在有状态 KIE 会话中,数据会被保留。无状态 KIE 会话的行为和函数类似,因为生成的结果由 KIE 基本的内容以及要在特定时间点上传递给 KIE 会话的数据决定。KIE 会话没有之前传递给 KIE 会话的任何数据的内存。
无状态 KIE 会话通常用于以下用例:
- 验证,例如验证某个人是否有资格获得分流
- 计算( 如计算抵抵达高级)
- 路由和过滤,如对传入电子邮件进行排序,或将传入电子邮件发送到目标
例如,请考虑以下驱动程序的许可证数据模型和示例 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
文件夹中的规则和所有其他文件都使用以下代码构建:
创建 KIE 容器
KieServices kieServices = KieServices.Factory.get(); KieContainer kContainer = kieServices.getKieClasspathContainer();
此代码编译类路径上找到的所有规则文件,并在 KieContainer
中添加了此编译结果(即 KieModule
对象)。
最后,State lessKieSession
对象由 KieContainer
进行实例化,并针对指定数据执行:
实例化无状态 KIE 会话并输入数据
StatelessKieSession kSession = kContainer.newStatelessKieSession(); Applicant applicant = new Applicant("Mr John Smith", 16); assertTrue(applicant.isValid()); ksession.execute(applicant); assertFalse(applicant.isValid());
在无状态 KIE 会话配置中,execute()
调用充当实例化 KieSession
对象的组合方法,添加所有用户数据并执行用户命令、调用 fireAllRules()
,然后调用 dispose()
。因此,通过无状态 KIE 会话,您不需要在会话调用后调用 fireAllRules()
或在使用有状态 KIE 会话时调用 dispose()
。
在这种情况下,指定的申请时间为 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 })); 1 assertFalse(application.isValid()); ksession.execute (CommandFactory.newInsertIterable(new Object[] { application, applicant })); 2 List<Command> cmds = new ArrayList<Command>(); 3 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 对象)
和execute(Iterable objects)
方法是来自BatchExecutor
接口的execute(Command 命令)
方法。 - 2
- 使用
CommandFactory
接口执行可迭代对象集合。 - 3
- 用于使用许多不同的命令或结果输出标识符的
BatchExecutor
和Command
onnectionFactoryy 配置。CommandFactory
接口支持在BatchExecutor
中使用的其他命令,如StartProcess
、Query、Query
和SetGlobal
。
81.1.1. 无状态 KIE 会话中全局变量
StatelessKieSession
对象支持全局变量(全局),您可以将它们配置为以会话范围的全局、委派全局或执行范围全局解析。
session -scoped globals: 对于会话范围的全局全局,您可以使用方法
get
返回可访问 KIE 会话全局的全局实例。这些全局用于所有执行调用。请谨慎使用 mutable 全局,因为可以在不同的线程中同时执行执行调用。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);
-
delegate globals:委派 全局值,您可以将值分配给全局(使用
setGlobal(String, Object)
),以便该值存储在将标识符映射到值的内部集合中。此内部集合中的标识符具有优先权,超过任何提供的委派。如果在此内部集合中找不到标识符,则使用委派全局(若有)。 -
执行范围的全局全局: 对于执行范围的全局,您可以使用
Command
对象来设置传递给命令执行程序接口以进行特定全局解析的全局。
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");