This is an automated email from the ASF dual-hosted git repository.

tkobayas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git


The following commit(s) were added to refs/heads/main by this push:
     new 290d5db08c [incubator-kie-drools-6421] Rules in agenda group with 
auto-focus may… (#6449)
290d5db08c is described below

commit 290d5db08c71b184292059532c85ef3377b52941
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Fri Oct 3 09:52:42 2025 +0900

    [incubator-kie-drools-6421] Rules in agenda group with auto-focus may… 
(#6449)
    
    * [incubator-kie-drools-6421] Rules in agenda group with auto-focus may not 
fire immediately (or at all) after activation
    - Update case
    
    * more cleanup
---
 .../org/drools/core/reteoo/AlphaTerminalNode.java  | 17 +++++--
 .../model/codegen/execmodel/FiringOrderTest.java   | 53 ++++++++++++++++++----
 .../codegen/execmodel/RuleAttributesTest.java      | 27 +++++++++++
 3 files changed, 84 insertions(+), 13 deletions(-)

diff --git 
a/drools-core/src/main/java/org/drools/core/reteoo/AlphaTerminalNode.java 
b/drools-core/src/main/java/org/drools/core/reteoo/AlphaTerminalNode.java
index 1c168bf9b2..7a803073ed 100644
--- a/drools-core/src/main/java/org/drools/core/reteoo/AlphaTerminalNode.java
+++ b/drools-core/src/main/java/org/drools/core/reteoo/AlphaTerminalNode.java
@@ -50,11 +50,7 @@ public class AlphaTerminalNode extends LeftInputAdapterNode {
             RuleTerminalNodeLeftTuple leftTuple = (RuleTerminalNodeLeftTuple) 
TupleFactory.createLeftTuple(rtn, factHandle, true );
             leftTuple.setPropagationContext( propagationContext );
 
-            if ( rtn.getRule().getAutoFocus() && 
!agendaItem.getAgendaGroup().isActive() ) {
-                if 
(activationsManager.getAgendaGroupsManager().setFocus(agendaItem.getAgendaGroup()))
 {
-                    activationsManager.haltGroupEvaluation();
-                }
-            }
+            autoFocusIfNeeded(rtn, agendaItem, activationsManager);
 
             PhreakRuleTerminalNode.doLeftTupleInsert( rtn, 
agendaItem.getRuleExecutor(), activationsManager, agendaItem, leftTuple );
         }
@@ -87,12 +83,23 @@ public class AlphaTerminalNode extends LeftInputAdapterNode 
{
                 if ( context.getModificationMask().intersects( 
rtn.getInferredMask()) ) {
                     leftTuple = TupleFactory.createLeftTuple( rtn, factHandle, 
true );
                     leftTuple.setPropagationContext( context );
+
+                    autoFocusIfNeeded(rtn, agendaItem, activationsManager);
+
                     PhreakRuleTerminalNode.doLeftTupleInsert( rtn, executor, 
activationsManager, agendaItem, (RuleTerminalNodeLeftTuple) leftTuple );
                 }
             }
         }
     }
 
+    private static void autoFocusIfNeeded(TerminalNode rtn, RuleAgendaItem 
agendaItem, ActivationsManager activationsManager) {
+        if ( rtn.getRule().getAutoFocus() && 
!agendaItem.getAgendaGroup().isActive() ) {
+            if 
(activationsManager.getAgendaGroupsManager().setFocus(agendaItem.getAgendaGroup()))
 {
+                activationsManager.haltGroupEvaluation();
+            }
+        }
+    }
+
     @Override
     public void retractLeftTuple(TupleImpl leftTuple, PropagationContext 
context, ReteEvaluator reteEvaluator) {
         ActivationsManager activationsManager = 
reteEvaluator.getActivationsManager();
diff --git 
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FiringOrderTest.java
 
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FiringOrderTest.java
index c77872b5de..af0623da65 100644
--- 
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FiringOrderTest.java
+++ 
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FiringOrderTest.java
@@ -32,8 +32,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class FiringOrderTest extends BaseModelTest {
 
-    private static final org.slf4j.Logger log = 
org.slf4j.LoggerFactory.getLogger(FiringOrderTest.class);
-
     public static class State {
 
         private int value;
@@ -66,8 +64,6 @@ public class FiringOrderTest extends BaseModelTest {
                                       
                                       import %s.State;
                                       
-                                      global java.util.List firingOrder;
-                                      
                                       // Rule A: in ruleflow-group XGroup. It 
modifies State so that B and C become eligible.
                                       rule "A"
                                           ruleflow-group "XGroup"
@@ -100,10 +96,54 @@ public class FiringOrderTest extends BaseModelTest {
                                       end
                                       
""".formatted(FiringOrderTest.class.getName());
 
+    private static final String DRL_UPDATE_FACT = """
+                                      package com.example.drools
+                                      
+                                      import %s.State;
+                                      
+                                      // Rule A: in ruleflow-group XGroup. It 
modifies State so that B and C become eligible.
+                                      rule "A"
+                                          ruleflow-group "XGroup"
+                                      when
+                                          $s : State(aFired == false, value == 
0)
+                                      then
+                                          // Mark A as fired and set value to 
1 so that B condition is met
+                                          modify($s) { setAFired(true), 
setValue(1) };
+                                      end
+                                      
+                                      // Rule B: in ruleflow-group XGroup 
(same as A).
+                                      rule "B"
+                                          ruleflow-group "XGroup"
+                                      when
+                                          State(value == 1, aFired == true)
+                                      then
+                                      end
+                                      
+                                      // Rule C: in ruleflow-group YGroup with 
auto-focus true.
+                                      // When this rule becomes active, it 
will push its ruleflow group to the focus stack.
+                                      rule "C"
+                                          ruleflow-group "YGroup"
+                                          auto-focus true
+                                      when
+                                          State(value == 1, aFired == true)
+                                      then
+                                      end
+                                      
""".formatted(FiringOrderTest.class.getName());
+
     @ParameterizedTest
     @MethodSource("parameters")
     void ruleCActivatesBeforeRuleBInsertTest(RUN_TYPE runType) {
-        final KieSession kieSession = getKieSession(runType, DRL_INSERT_FACT);
+        ruleCActivatesBeforeRuleB(runType, DRL_INSERT_FACT);
+    }
+
+    @ParameterizedTest
+    @MethodSource("parameters")
+    void ruleCActivatesBeforeRuleBUpdateTest(RUN_TYPE runType) {
+        ruleCActivatesBeforeRuleB(runType, DRL_UPDATE_FACT);
+    }
+
+    void ruleCActivatesBeforeRuleB(RUN_TYPE runType, String drl) {
+        final KieSession kieSession = getKieSession(runType, drl);
 
         try {
             final List<String> firingOrder = new ArrayList<>();
@@ -117,9 +157,6 @@ public class FiringOrderTest extends BaseModelTest {
             };
             kieSession.addEventListener(listener);
 
-            // Global for firing order from the DRL RHS for additional 
verification
-            kieSession.setGlobal("firingOrder", firingOrder);
-
             // Initial fact to trigger A
             State state = new State(0, false);
             kieSession.insert(state);
diff --git 
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/RuleAttributesTest.java
 
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/RuleAttributesTest.java
index 14eb8e4fda..7b6ce9895d 100644
--- 
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/RuleAttributesTest.java
+++ 
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/RuleAttributesTest.java
@@ -361,6 +361,33 @@ public class RuleAttributesTest extends BaseModelTest {
         
assertThat(listener.getAfterMatchFired()).hasSize(2).containsExactly("b2", 
"b1");
     }
 
+    @ParameterizedTest
+    @MethodSource("parameters")
+    public void testAutoFocusWithModify(RUN_TYPE runType) {
+        String str =
+                "import " + Person.class.getCanonicalName() + ";" +
+                        "rule R1\n" +
+                        "when\n" +
+                        "  $p : Person(age == 18)\n" +
+                        "then\n" +
+                        "  modify($p) { setAge(19) };\n" +
+                        "end\n" +
+                        "rule R2\n" +
+                        "  agenda-group \"groupA\"\n" +
+                        "  auto-focus true\n" +
+                        "when\n" +
+                        "  $p : Person(age == 19)\n" +
+                        "then\n" +
+                        "end";
+
+        KieSession ksession = getKieSession(runType, str);
+
+        Person me = new Person( "Mario", 18 );
+        ksession.insert( me );
+        int fired = ksession.fireAllRules();
+
+        assertThat(fired).isEqualTo(2);
+    }
 
     @ParameterizedTest
        @MethodSource("parameters")


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to