假定以下规则侦听具有特定标识符的事件。每个标识符只能处理一个事件。
rule "SampleRule"
dialect "mvel"
no-loop true
when
Event( $identifier : identifier)
not(EventHandler( identifier == $identifier ))
then
EventHandler $h = new EventHandler();
$h.setIdentifier( $identifier );
insert( $h );
end
事件类:
...
@javax.persistence.Entity
@org.kie.api.definition.type.Role(org.kie.api.definition.type.
Role.Type.EVENT) // line break just for SO
public class Event implements java.io.Serializable {
static final long serialVersionUID = 1L;
@javax.persistence.GeneratedValue(generator = "STATUSNOTIFICATION_ID_GENERATOR", strategy = javax.persistence.GenerationType.AUTO)
@javax.persistence.SequenceGenerator(name = "STATUSNOTIFICATION_ID_GENERATOR", sequenceName = "STATUSNOTIFICATION_ID_SEQ")
private java.lang.Long id;
private java.lang.String identifier;
public Event() {
}
public java.lang.String getIdentifier() {
return this.identifier;
}
public void setIdentifier(java.lang.String identifier) {
this.identifier = identifier;
}
}
事件类是通过Drools Workbench配置的。除了将课程声明为“ EVENT”外,我没有做任何其他更改。
将事件插入规则引擎的方式:
KieServicesConfiguration conf = KieServicesFactory.newRestConfiguration(
url, user, pass);
conf.setMarshallingFormat(FORMAT);
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(conf);
RuleServicesClient rulesClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
KieCommands commandsFactory = KieServices.Factory.get().getCommands();
while (hasEvent) {
String identifier = ... // get the identifier of the event, events with same identifier possible, sometimes within same seconds, sometimes several minutes/hours in between
Event event = new Event();
event.setIdentifier(identifier);
Command<?> insert = commandsFactory.newInsert(event, "notificationIdentifier");
Command<?> fireAllRules = commandsFactory.newFireAllRules();
Command<?> batchCommand = commandsFactory.newBatchExecution(Arrays.asList(insert, fireAllRules));
ServiceResponse<ExecutionResults> executeResponse = rulesClient.executeCommandsWithResults("name_of_rules_package_incl_version", batchCommand);
if (executeResponse.getType() == ResponseType.SUCCESS) {
...
} else {
...
}
}
除了上面的“ SampleRule”规则外,我还启用了另一个规则,如果每个标识符存在一个EventHandler,该规则将从工作内存中撤回事件:
rule "SampleRuleClear"
dialect "mvel"
no-loop true
when
$E : Event( $identifier : identifier)
EventHandler( identifier == $identifier )
then
retract( $E );
end
实际上,不需要“ SampleRuleClear”规则来防止重复。出于完整性考虑,我在这里只提到它。
我希望每个标识符每个事件仅触发一次“ SampleRule”规则。不幸的是,即使事件间隔很大,它也会触发多次。