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]