[
https://issues.jboss.org/browse/DROOLS-1087?page=com.atlassian.jira.plugi...
]
Matteo Mortari commented on DROOLS-1087:
----------------------------------------
Ciao Mario, thanks for the feedback but one case is still not fully explained and still
failing on upgrade.
First thing first, thank you for the explanation about how the incremental compilation
works based at resource level. I advised the business how to more properly handle
incremental versioning of new rules, e.g.: try to maintain unchanged rule in a given file,
and provide new one in separate new file; or alternatively, rewrite the rule with
additional condition to avoid "unexpected" refires.
There is a case of upgrade with reteoo, as per original description, which is failing on
rule upgrade. I'll attach reproducer rewritten to (hopefully) better highlight the
problem experienced. I understand reteoo is being deprecated in favor of phreak, so if
this case is not supported due to deprecation, at least it can be helpful for posterity
:)
In the new reproducer, the rules are as per original description, and dropping the no-loop
attributes as you correctly pointed out, was not necessary.
So with the new reproducer, I highlight and comment below the most interesting part:
{code}
ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade",
"1.0.0" );
KieModuleModel kieModuleModel = ks.newKieModuleModel();
kieModuleModel.newKieBaseModel( "KBase1 ")
.setDefault( true )
.setEqualsBehavior( EqualityBehaviorOption.IDENTITY )
.setEventProcessingMode( EventProcessingOption.STREAM );
Resource resourceDRL1 = ks.getResources()
.newReaderResource( new StringReader(drl1) )
.setResourceType( ResourceType.DRL )
.setSourcePath( "drl1.drl" );
createAndDeployJar(ks, kieModuleModel.toXML(), releaseId1, resourceDRL1);
KieContainer kc = ks.newKieContainer( releaseId1 );
KieBase kieBase = kc.getKieBase();
KieSessionConfiguration config = ks.newKieSessionConfiguration();
config.setOption( ClockTypeOption.get("pseudo") );
KieSession ksession = kieBase.newKieSession(config, null);
SessionPseudoClock clock = ksession.getSessionClock();
clock.advanceTime(1, TimeUnit.MINUTES);
ksession.insert( new org.acme.sensors.Measurement("color", "red") );
assertEquals( 1, ksession.fireAllRules() );
{code}
up to here all is fine, on the console is:
{code}
2016-05-03 16:19:31,795 INFO [org.drools.compiler.kie.builder.impl.KieRepositoryImpl]
(main) KieModule was added: MemoryKieModule[releaseId=org.kie:test-upgrade:1.0.0]
I have seen color RED in the last 2m [red]
{code}
And this is OK, only Measurement id=color val=red was inserted into the session.
Now introducing the DRL2, for the rule taking care for Measurement id=x:
{code}
ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade",
"1.1.0" );
resourceDRL1 = ks.getResources()
.newReaderResource( new StringReader(drl1 + " ") ) // trivial update to force
realize indeed Measurement is declared as @role event, maybe another bug report later =)
.setResourceType( ResourceType.DRL )
.setSourcePath( "drl1.drl" );
Resource resourceDRL2 = ks.getResources()
.newReaderResource( new StringReader(drl2) )
.setResourceType( ResourceType.DRL )
.setSourcePath( "drl2.drl" );
createAndDeployJar(ks, kieModuleModel.toXML(), releaseId2, resourceDRL1, resourceDRL2);
kc.updateToVersion( releaseId2 );
final List<String> fired = new ArrayList<String>();
ksession.addEventListener(new DefaultAgendaEventListener() {
@Override
public void afterMatchFired(AfterMatchFiredEvent event) {
fired.add(event.getMatch().getRule().getName());
}
});
HashSet<String> controlSet = new HashSet<String>();
ksession.setGlobal("controlSet", controlSet);
clock.advanceTime(1, TimeUnit.MINUTES);
ksession.insert( new org.acme.sensors.Measurement("x", "x") );
ksession.fireAllRules();
assertTrue("because trivial update to drl1, rule for color RED should have fired
again, now I understand why and is OK:",
fired.contains("color RED seen in the last 2 minutes"));
assertTrue("and inserted Measurement x x , so also the rule in drl2 should have
fired, this is OK:",
fired.contains("id X seen in the last 2 minutes"));
System.err.println("rule which fired: "+fired);
System.err.println("global control set: "+controlSet);
assertTrue("because inserted Measurement x x , the rule in drl2 should have fired,
this is OK",
controlSet.contains("x"));
// THIS FAILS:
assertTrue("because inserted ONLY Measurement x x , the rule in drl2 should have
fired only for it, not for the color-red",
controlSet.size() == 1);
// THIS FAILS TOO:
assertFalse("but nobody inserted color GREEN, so it should NOT have fired:",
fired.contains("color GREEN seen in the last 2 minutes"));
{code}
and on the console:
{code}
2016-05-03 16:32:38,194 INFO [org.drools.compiler.kie.builder.impl.KieRepositoryImpl]
(main) KieModule was added: MemoryKieModule[releaseId=org.kie:test-upgrade:1.1.0]
I have seen Measurement for id=x in the last 2m [red, x]
I have seen color GREEN in the last 2m [red]
I have seen color RED in the last 2m [red]
rule which fired: [id X seen in the last 2 minutes, color GREEN seen in the last 2
minutes, color RED seen in the last 2 minutes]
global control set: [red, x]
{code}
and the assertions as per comments fail.
We can notice that:
* the rule for "color green" is firing for a wrong match (it is matching on
val=red)
* the rule for Measurement id=x has matched also for Measurement id=color.
I hope the JUnit assertions highlight better the unexpected behavior, and once again to be
noted this is with reteoo, and I submit for completeness, I can understand if this
use-case scenario is no longer covered due to the deprecation of this old algo in favor of
phreak
KieBase update wrong match for rules containing constraints over the
accumulate
-------------------------------------------------------------------------------
Key: DROOLS-1087
URL:
https://issues.jboss.org/browse/DROOLS-1087
Project: Drools
Issue Type: Bug
Components: core engine
Affects Versions: 6.2.0.Final, 6.3.0.Final, 6.4.0.Beta2
Reporter: Matteo Mortari
Assignee: Mario Fusco
Attachments: 20160309.DROOLS-1087.zip
Ciao, I will attach reproducer with same style as
{{org.drools.compiler.integrationtests.IncrementalCompilationTest.testIncrementalCompilation}}
/ {{testIncrementalCompilationWithRedeclares}}
h2. Executive summary
When performing KieBase update, rules containing constraints over the accumulate Event,
are firing with wrong matches and/or firing for already seen matches and violating the
no-loop.
h2. Detailed description of the reproducer.
Assume a KB starting with only these two rules:
{code}
declare Measurement
@role(event)
end
rule "color RED seen in the last 2 minutes"
no-loop
when
accumulate ( $token: Measurement( id == "color", $colorVal : val, $colorVal ==
"red") over window:time(2m);
$mySet : collectSet( $colorVal ),
$val : count($token) ;
$val >= 1
)
then
System.out.println("I have seen color RED in the last 2m "+$mySet);
end
rule "color GREEN seen in the last 2 minutes"
no-loop
when
accumulate ( $token: Measurement( id == "color", $colorVal : val, $colorVal ==
"green") over window:time(2m);
$mySet : collectSet( $colorVal ),
$val : count($token) ;
$val >= 1
)
then
System.out.println("I have seen color GREEN in the last 2m "+$mySet);
end
{code}
and then on upgrade/update, the same rule as above un-touched, but additionally the
following rule:
{code}
rule "id X seen in the last 2 minutes"
no-loop
when
accumulate ( $token: Measurement( id == "x", $colorVal : val) over
window:time(2m);
$mySet : collectSet( $colorVal ),
$val : count($token) ;
$val >= 1
)
then
System.out.println("I have seen Measurement for id=x in the last 2m
"+$mySet);
end
{code}
Where {{Measurement}} just a POJO as per Kie Artifact, basically containing fields:
{{String id;String val;}}
with the following of Measurement insertions, one at each minute:
{code}
-> Measurement [id=color, val=red]
(KB update here)
-> Measurement [id=x, val=x]
-> Measurement [id=color, val=green]
...
{code}
the following problems are highlighted:
h6. Drools version 6.2.0.Final with Reteoo
The problem is highlighted after the 2nd Measurment event insertion below, the rules
"color GREEN seen in the last 2 minutes" and "id X seen in the last 2
minutes" are firing with wrong matches, because:
* the rule "color GREEN seen in the last 2 minutes" should fire only for
{{Measurement\[id=color, val=green]}} Events, which has not occured, and is matching
instead over {{Measurement\[id=color, val=red]}}
* the rule "id X seen in the last 2 minutes" should fire only for
{{Measurement\[id=x, _]}} Events, but is considering also the {{Measurement\[id=color,
_]}} event which occured earlier.
{code}
2016-03-09 09:33:20,952 INFO [org.drools.compiler.kie.builder.impl.KieRepositoryImpl]
(main) KieModule was added: MemoryKieModule[releaseId=org.test:test:1.0.0]
2016-03-09 09:33:21,240 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) There
should be rules:
2016-03-09 09:33:21,240 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule color RED seen in the last 2 minutes
2016-03-09 09:33:21,240 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule color GREEN seen in the last 2 minutes
2016-03-09 09:33:21,240 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) Creating
kieSession
2016-03-09 09:33:21,319 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) Now
running data
2016-03-09 09:33:21,321 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) advance
clock @ 60000
-> Measurement [id=color, val=red]
I have seen color RED in the last 2m [red]
2016-03-09 09:33:21,539 INFO [org.drools.compiler.kie.builder.impl.KieRepositoryImpl]
(main) KieModule was added: MemoryKieModule[releaseId=org.test:test:1.0.1]
2016-03-09 09:33:21,743 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) Update of
KB performed.
2016-03-09 09:33:21,744 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule color RED seen in the last 2 minutes
2016-03-09 09:33:21,744 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule color GREEN seen in the last 2 minutes
2016-03-09 09:33:21,744 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule id X seen in the last 2 minutes
2016-03-09 09:33:21,744 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) advance
clock @ 120000
-> Measurement [id=x, val=x]
I have seen Measurement for id=x in the last 2m [red, x]
I have seen color GREEN in the last 2m [red]
I have seen color RED in the last 2m [red]
2016-03-09 09:33:21,750 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) advance
clock @ 180000
<- Measurement [id=color, val=red]
-> Measurement [id=color, val=green]
I have seen color GREEN in the last 2m [green]
I have seen Measurement for id=x in the last 2m [x]
2016-03-09 09:33:21,752 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) advance
clock @ 240000
<- Measurement [id=x, val=x]
-> Measurement [id=color, val=blue]
2016-03-09 09:33:21,752 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) Final
checks
{code}
h6. Drools version 6.2.0.Final with Phreak
NPE
{code}
java.lang.NullPointerException
at org.drools.core.reteoo.NodeTypeEnums.isBetaNode(NodeTypeEnums.java:87)
at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:252)
at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:161)
at
org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:116)
at org.drools.core.phreak.RuleExecutor.evaluateNetwork(RuleExecutor.java:92)
at org.drools.core.common.DefaultAgenda.evaluateEagerList(DefaultAgenda.java:1044)
at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:996)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1302)
at
org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1289)
at
org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1262)
at com.acme.accumulateUpgradeTest.RuleTest.test(RuleTest.java:185)
{code}
h6. Drools version 6.3.0.Final with Reteoo
Not in scope of this JIRA record. I think this release had a bug when running with the
setup of this reproducer because if I try I get NPE at
{{org.drools.core.RuleBaseConfiguration.configureReteComponentFactory()}}
h6. Drools version 6.3.0.Final with Phreak
Same NPE as "6.2.0.Final with Phreak"
h6. Drools version 6.4.0.Beta2 with Reteoo
Same problem as "6.2.0.Final with Reteoo"
h6. Drools version 6.4.0.Beta2 with Phreak
Better, but I'm not sure why rule "color RED seen in the last 2 minutes" is
firing again after the rule-update, it is no-loop and the conditions of the rules are the
same as before the rule-update, hence I'm not sure why it fired again.
{code}
2016-03-09 09:45:25,301 INFO [org.drools.compiler.kie.builder.impl.KieRepositoryImpl]
(main) KieModule was added: MemoryKieModule[releaseId=org.test:test:1.0.0]
2016-03-09 09:45:25,594 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) There
should be rules:
2016-03-09 09:45:25,594 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule color RED seen in the last 2 minutes
2016-03-09 09:45:25,594 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule color GREEN seen in the last 2 minutes
2016-03-09 09:45:25,594 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) Creating
kieSession
2016-03-09 09:45:25,696 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) Now
running data
2016-03-09 09:45:25,698 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) advance
clock @ 60000
-> Measurement [id=color, val=red]
I have seen color RED in the last 2m [red]
2016-03-09 09:45:25,854 INFO [org.drools.compiler.kie.builder.impl.KieRepositoryImpl]
(main) KieModule was added: MemoryKieModule[releaseId=org.test:test:1.0.1]
2016-03-09 09:45:26,023 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) Update of
KB performed.
2016-03-09 09:45:26,023 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule color RED seen in the last 2 minutes
2016-03-09 09:45:26,023 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule color GREEN seen in the last 2 minutes
2016-03-09 09:45:26,023 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) kp
[Package name=com.acme.accumulateUpgradeTest] rule id X seen in the last 2 minutes
2016-03-09 09:45:26,023 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) advance
clock @ 120000
-> Measurement [id=x, val=x]
I have seen color RED in the last 2m [red]
I have seen Measurement for id=x in the last 2m [x]
2016-03-09 09:45:26,029 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) advance
clock @ 180000
-> Measurement [id=color, val=green]
<- Measurement [id=color, val=red]
I have seen color GREEN in the last 2m [green]
2016-03-09 09:45:26,033 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) advance
clock @ 240000
-> Measurement [id=color, val=blue]
<- Measurement [id=x, val=x]
2016-03-09 09:45:26,033 INFO [com.acme.accumulateUpgradeTest.RuleTest] (main) Final
checks
{code}
h2. Final note.
Please notice in the reproducer I've used {{setSourcePath}} to ".txt"
because I'm aliging with the Drool's JUnit tests:
https://github.com/droolsjbpm/drools/blob/master/drools-compiler/src/test...
However changing {{setSourcePath}} to ".drl" would NOT solve the problem, at
least for the rule "id X seen in the last 2 minutes".
Can you kindly advise, please?
Thank you
Ciao,
MM
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)