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

mariofusco 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 577ebb87be [KIE-686] fix peer update propagation for FromNode (#5584)
577ebb87be is described below

commit 577ebb87bef03376edcae540154a0e9c4c49234e
Author: Mario Fusco <[email protected]>
AuthorDate: Mon Nov 13 08:18:04 2023 +0100

    [KIE-686] fix peer update propagation for FromNode (#5584)
    
    * [KIE-686] fix peer update propagation for FromNode
    
    * Update 
drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/UnexpectedLoopTest.java
    
    Co-authored-by: Toshiya Kobayashi <[email protected]>
    
    ---------
    
    Co-authored-by: Toshiya Kobayashi <[email protected]>
---
 .../java/org/drools/base/reteoo/NodeTypeEnums.java |  4 --
 .../org/drools/core/phreak/SegmentPropagator.java  |  4 +-
 .../protobuf/marshalling/MarshallingHelper.java    | 11 +++-
 .../integrationtests/UnexpectedLoopTest.java       | 75 ++++++++++++++++++++++
 .../compiler/integrationtests/model/CalcFact.java  | 34 ++++++++++
 .../compiler/integrationtests/model/Item.java      | 25 ++++++++
 .../integrationtests/model/RecordFact.java         | 34 ++++++++++
 .../compiler/integrationtests/joinFromFrom.drl     | 35 ++++++++++
 8 files changed, 214 insertions(+), 8 deletions(-)

diff --git 
a/drools-base/src/main/java/org/drools/base/reteoo/NodeTypeEnums.java 
b/drools-base/src/main/java/org/drools/base/reteoo/NodeTypeEnums.java
index df05b2fb78..c78a15f580 100644
--- a/drools-base/src/main/java/org/drools/base/reteoo/NodeTypeEnums.java
+++ b/drools-base/src/main/java/org/drools/base/reteoo/NodeTypeEnums.java
@@ -110,8 +110,4 @@ public class NodeTypeEnums {
     public static boolean isLeftTupleNode(NetworkNode node) {
         return isLeftTupleSource(node) || isLeftTupleSink(node);
     }
-
-    public static boolean hasNodeMemory(NetworkNode node) {
-        return node.getType() == FromNode || node.getType() == 
ReactiveFromNode || node.getType() == AccumulateNode;
-    }
 }
diff --git 
a/drools-core/src/main/java/org/drools/core/phreak/SegmentPropagator.java 
b/drools-core/src/main/java/org/drools/core/phreak/SegmentPropagator.java
index 2986421497..2f723dea80 100644
--- a/drools-core/src/main/java/org/drools/core/phreak/SegmentPropagator.java
+++ b/drools-core/src/main/java/org/drools/core/phreak/SegmentPropagator.java
@@ -28,7 +28,7 @@ import org.drools.core.reteoo.LeftTupleSource;
 import org.drools.core.reteoo.PathMemory;
 import org.drools.core.reteoo.SegmentMemory;
 
-import static org.drools.base.reteoo.NodeTypeEnums.hasNodeMemory;
+import static org.drools.base.reteoo.NodeTypeEnums.AccumulateNode;
 import static org.drools.core.phreak.TupleEvaluationUtil.forceFlushLeftTuple;
 import static org.drools.core.phreak.TupleEvaluationUtil.forceFlushWhenRiaNode;
 
@@ -134,7 +134,7 @@ public class SegmentPropagator {
                 break;
             default:
                 // no clash, so just add
-                if ( hasNodeMemory( childLeftTuple.getTupleSink() ) ) {
+                if ( childLeftTuple.getTupleSink().getType() == AccumulateNode 
) {
                     trgLeftTuples.addInsert(childLeftTuple);
                 } else {
                     trgLeftTuples.addUpdate(childLeftTuple);
diff --git 
a/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/marshalling/MarshallingHelper.java
 
b/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/marshalling/MarshallingHelper.java
index bbd31d15fd..df17f92c99 100644
--- 
a/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/marshalling/MarshallingHelper.java
+++ 
b/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/marshalling/MarshallingHelper.java
@@ -18,11 +18,14 @@
  */
 package org.drools.serialization.protobuf.marshalling;
 
+import org.drools.base.common.NetworkNode;
 import org.drools.core.reteoo.LeftTupleSource;
-import org.drools.base.reteoo.NodeTypeEnums;
 import org.drools.core.reteoo.TerminalNode;
 import org.drools.core.reteoo.Tuple;
 
+import static org.drools.base.reteoo.NodeTypeEnums.AccumulateNode;
+import static org.drools.base.reteoo.NodeTypeEnums.FromNode;
+import static org.drools.base.reteoo.NodeTypeEnums.ReactiveFromNode;
 import static org.drools.core.marshalling.TupleKey.createTupleArray;
 
 public class MarshallingHelper {
@@ -51,6 +54,10 @@ public class MarshallingHelper {
         if (leftTupleSource == null) {
             return false;
         }
-        return NodeTypeEnums.hasNodeMemory( leftTupleSource ) ? true : 
hasNodeMemory(leftTupleSource.getLeftTupleSource());
+        return nodeWithMemory( leftTupleSource ) || 
hasNodeMemory(leftTupleSource.getLeftTupleSource());
+    }
+
+    private static boolean nodeWithMemory(NetworkNode node) {
+        return node.getType() == FromNode || node.getType() == 
ReactiveFromNode || node.getType() == AccumulateNode;
     }
 }
diff --git 
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/UnexpectedLoopTest.java
 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/UnexpectedLoopTest.java
new file mode 100644
index 0000000000..6997504707
--- /dev/null
+++ 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/UnexpectedLoopTest.java
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.compiler.integrationtests;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.drools.compiler.integrationtests.model.CalcFact;
+import org.drools.compiler.integrationtests.model.Item;
+import org.drools.compiler.integrationtests.model.RecordFact;
+import org.drools.testcoverage.common.util.KieBaseTestConfiguration;
+import org.drools.testcoverage.common.util.KieBaseUtil;
+import org.drools.testcoverage.common.util.TestParametersUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.kie.api.KieBase;
+import org.kie.api.runtime.KieSession;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(Parameterized.class)
+public class UnexpectedLoopTest {
+
+    private final KieBaseTestConfiguration kieBaseTestConfiguration;
+
+    public UnexpectedLoopTest(final KieBaseTestConfiguration 
kieBaseTestConfiguration) {
+        this.kieBaseTestConfiguration = kieBaseTestConfiguration;
+    }
+
+    @Parameterized.Parameters(name = "KieBase type={0}")
+    public static Collection<Object[]> getParameters() {
+        return TestParametersUtil.getKieBaseCloudConfigurations(true);
+    }
+
+    @Test
+    public void joinFromFromPeerUpdate_shouldNotLoop() {
+
+        final KieBase kieBase = 
KieBaseUtil.getKieBaseFromClasspathResources(getClass(), 
kieBaseTestConfiguration,
+                                                                             
"org/drools/compiler/integrationtests/joinFromFrom.drl");
+        final KieSession ksession = kieBase.newKieSession();
+        try {
+            RecordFact record1 = new RecordFact(null, 0);
+            Item item1 = new Item(null);
+            CalcFact calcFact = new CalcFact(List.of(item1), 4144);
+
+            ksession.insert("test");
+            ksession.insert(record1);
+            ksession.insert(item1);
+            ksession.insert(calcFact);
+
+            int fired = ksession.fireAllRules(10);
+
+            assertThat(fired).as("Unexpected loop detected. Expects firing R2 
once").isEqualTo(1);
+        } finally {
+            ksession.dispose();
+        }
+    }
+}
diff --git 
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/CalcFact.java
 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/CalcFact.java
new file mode 100644
index 0000000000..47afd6f718
--- /dev/null
+++ 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/CalcFact.java
@@ -0,0 +1,34 @@
+package org.drools.compiler.integrationtests.model;
+
+import java.util.List;
+
+public class CalcFact {
+
+    private List<Item> itemList;
+    private int lineNumber;
+
+    public CalcFact(List<Item> itemList, int lineNumber) {
+        this.itemList = itemList;
+        this.lineNumber = lineNumber;
+    }
+
+    public List<Item> getItemList() {
+        return itemList;
+    }
+
+    public void setItemList(List<Item> itemList) {
+        this.itemList = itemList;
+    }
+
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public String toString() {
+        return "CalcFact{" +
+                "itemList=" + itemList +
+                ", lineNumber=" + lineNumber +
+                '}';
+    }
+}
diff --git 
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/Item.java
 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/Item.java
new file mode 100644
index 0000000000..665fc8b7b0
--- /dev/null
+++ 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/Item.java
@@ -0,0 +1,25 @@
+package org.drools.compiler.integrationtests.model;
+
+public class Item {
+
+    private String decomposedPointFlag;
+
+    public Item(String decomposedPointFlag) {
+        this.decomposedPointFlag = decomposedPointFlag;
+    }
+
+    public String getDecomposedPointFlag() {
+        return decomposedPointFlag;
+    }
+
+    public void setDecomposedPointFlag(String decomposedPointFlag) {
+        this.decomposedPointFlag = decomposedPointFlag;
+    }
+
+    @Override
+    public String toString() {
+        return "Item{" +
+                "pointFlag='" + decomposedPointFlag + '\'' +
+                '}';
+    }
+}
diff --git 
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/RecordFact.java
 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/RecordFact.java
new file mode 100644
index 0000000000..0338cc46cf
--- /dev/null
+++ 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/model/RecordFact.java
@@ -0,0 +1,34 @@
+package org.drools.compiler.integrationtests.model;
+
+import java.math.BigDecimal;
+
+public class RecordFact {
+
+    private BigDecimal decomposedPoint;
+    private int lineNumber;
+
+    public RecordFact(BigDecimal decomposedPoint, int lineNumber) {
+        this.decomposedPoint = decomposedPoint;
+        this.lineNumber = lineNumber;
+    }
+
+    public BigDecimal getDecomposedPoint() {
+        return decomposedPoint;
+    }
+
+    public void setDecomposedPoint(BigDecimal decomposedPoint) {
+        this.decomposedPoint = decomposedPoint;
+    }
+
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public String toString() {
+        return "RecordFact{" +
+                ", decomposedPoint=" + decomposedPoint +
+                ", lineNumber=" + lineNumber +
+                '}';
+    }
+}
diff --git 
a/drools-test-coverage/test-compiler-integration/src/test/resources/org/drools/compiler/integrationtests/joinFromFrom.drl
 
b/drools-test-coverage/test-compiler-integration/src/test/resources/org/drools/compiler/integrationtests/joinFromFrom.drl
new file mode 100644
index 0000000000..329fe0efa5
--- /dev/null
+++ 
b/drools-test-coverage/test-compiler-integration/src/test/resources/org/drools/compiler/integrationtests/joinFromFrom.drl
@@ -0,0 +1,35 @@
+package org.drools.compiler.integrationtests;
+
+import org.drools.compiler.integrationtests.model.CalcFact;
+import org.drools.compiler.integrationtests.model.Item;
+import org.drools.compiler.integrationtests.model.RecordFact;
+
+dialect "mvel"
+
+rule R1
+       when
+        String()
+        CalcFact( $lineNumber : lineNumber, $itemList : itemList )
+        Integer()
+       then
+end
+
+rule R2
+       when
+        String()
+        $fact : CalcFact( $itemList : itemList )
+        $item : Item( decomposedPointFlag == null ) from $itemList
+        $record : RecordFact( decomposedPoint == null )
+        not RecordFact( lineNumber == $fact.lineNumber )
+       then
+        modify($record){
+          decomposedPoint = null
+        }
+        modify($item){
+          decomposedPointFlag = "1"
+        }
+        modify($fact){
+          itemList = $itemList
+        }
+        System.out.println("[DEBUG] after  $item=" + $item);
+end


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

Reply via email to