[jboss-jira] [JBoss JIRA] (DROOLS-1010) AlphNode sharing fails to propagate match to BetaNode when match is defined separate rule package

Anantjot Anand (JIRA) issues at jboss.org
Mon Jan 25 22:58:00 EST 2016


     [ https://issues.jboss.org/browse/DROOLS-1010?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Anantjot Anand reopened DROOLS-1010:
------------------------------------


My typo falsely made me believe that I was successful in writing the reproducer. I now have a reproducer working correctly to reproduce this issue. I am not sure if this would allow me to attach the reproducer here but if not I will send you separate email with Unit test.


{code:java}
package com.test.unittest;

import java.util.HashSet;

import org.drools.core.audit.event.ActivationLogEventFilter;
import org.junit.Assert;
import org.junit.Test;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.io.ResourceType;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.runtime.StatefulKnowledgeSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.test.unittest.DroolsTest.TypeA;
import com.test.unittest.DroolsTest.TypeB;
import com.test.unittest.DroolsTest.TypeC;
import com.test.unittest.DroolsTest.TypeD;
import com.test.unittest.DroolsTest.TypeE;


public class AlphaNodeSharingWithDiffPackageName {
	
		public static class TypeA { 
			private int parentId = 2; 
			private int id = 3; 
			public int getParentId() { return parentId; } 
			public int getId() { return id; } 
			private String alphaNode;
			private HashSet<String> firings = new HashSet<String>();
			public HashSet<String> getFirings(){if (firings == null) firings = new HashSet<String>(); return firings;}
			public void setFirings(HashSet<String> x){firings = x;}
			
			private String data = "AlphaNodeHashingThreshold Data"; 
			public String getData() { return data; } 
			
			public String getAlphaNode() {
				return alphaNode;
			}
	
			public void setAlphaNode(String alphaNode) {
				this.alphaNode = alphaNode;
			}
		} 
		

		 
		public static class TypeB { 
			private int parentId = 1; 
			private int id = 2; 
			public int getParentId() { return parentId; } 
			public int getId() { return id; } 
		} 
		
		 
		public static class TypeC { 
			private int parentId = 0; 
			private int id = 1; 
			public int getParentId() { return parentId; } 
			public int getId() { return id; } 		
		} 
		

		public static class TypeD { 
			private int value; 
			public int getValue() { return value; } 
			public void setValue(int value) { this.value = value; } 
		} 
		public static class TypeE { 
			private int value; 
			public int getValue() { return value; } 
			public void setValue(int value) { this.value = value; } 
		} 

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	static String rule1 ="package com.test.rule1;\r\n" + 
			"\r\n" + 
			"import "+ TypeA.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeB.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeC.class.getCanonicalName()	+";\r\n" + 
			"			\r\n" + 
			"rule R1\r\n" + 
			"	dialect \"java\"\r\n" + 
			"when\r\n" + 
			"	$c : TypeC()\r\n" + 
			"	$b : TypeB(parentId == $c.Id)\r\n" + 
			"	$a : TypeA( parentId == $b.Id, firings not contains \"R1 Fired\")\r\n" + 
			"then\r\n" + 
			"	$a.setAlphaNode(\"value contains TypeD TypeE data type\");\r\n" + 
			"	$a.getFirings().add(\"R1 Fired\");\r\n" + 
			"	update($a);\r\n" + 
			"end";
	
	static String rule2 ="package com.test.rule2;\r\n" + 
			"\r\n" + 
			"import "+ TypeA.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeB.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeC.class.getCanonicalName()	+";\r\n" + 
			"\r\n" + 
			"rule R2 \r\n" + 
			"	dialect \"java\"\r\n" + 
			"when\r\n" + 
			"	$c : TypeC()\r\n" + 
			"	$b : TypeB(parentId == $c.Id)\r\n" + 
			"	$a : TypeA(parentId == $b.Id, \r\n" + 
			"				alphaNode==\"value contains TypeD TypeE data type\", \r\n" + 
			"				firings not contains \"R2 Fired\")\r\n" + 
			"then\r\n" + 
			"		$a.getFirings().add(\"R2 Fired\");\r\n" + 
			"		update($a);\r\n" + 
			"end";
	static String rule3 ="package com.test.rule3;\r\n" + 
			"\r\n" + 
			"import "+ TypeA.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeB.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeC.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeD.class.getCanonicalName()	+";\r\n" + 
			"\r\n" + 
			"rule R3 \r\n" + 
			"	dialect \"java\"\r\n" + 
			"when\r\n" + 
			"	$d : TypeD()\r\n" + 
			"	$c : TypeC()\r\n" + 
			"	$b : TypeB(parentId == $c.Id)\r\n" + 
			"	$a : TypeA( parentId == $b.Id,\r\n" + 
			"			    alphaNode==\"value contains TypeD TypeE data type\", \r\n" + 
			"				firings not contains \"R3 Fired\")\r\n" + 
			"then\r\n" + 
			"	$a.getFirings().add(\"R3 Fired\");\r\n" + 
			"	update($a);\r\n" + 
			"end;";

	static String rule4 ="package com.test.rule4;\r\n" + 
			"\r\n" + 
			"import "+ TypeA.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeB.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeC.class.getCanonicalName()	+";\r\n" + 
			"import "+ TypeE.class.getCanonicalName()	+";\r\n" + 
			"\r\n" + 
			"rule R4 \r\n" + 
			"	dialect \"java\"\r\n" + 
			"when\r\n" + 
			"	$e: TypeE()\r\n" + 
			"	$c : TypeC()\r\n" + 
			"	$b : TypeB(parentId == $c.Id)\r\n" + 
			"	$a : TypeA( parentId == $b.Id,\r\n" + 
			"			    alphaNode==\"value contains TypeD TypeE data type\", \r\n" + 
			"				firings not contains \"R4 Fired\")\r\n" + 
			"then\r\n" + 
			"	$a.getFirings().add(\"R4 Fired\");\r\n" + 
			"	update($a);\r\n" + 
			"end;";
	

	@Test
	public void testalphaNode()
	{
		Logger logger = LoggerFactory.getLogger(AlphaNodeSharingWithDiffPackageName.class);
		
		KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
		
		builder.add( ResourceFactory.newByteArrayResource( rule1.getBytes() ), ResourceType.DRL); 
		if ( builder.hasErrors() ) { 
			throw new RuntimeException(builder.getErrors().toString()); 
		} 
		
		builder.add( ResourceFactory.newByteArrayResource( rule2.getBytes() ), ResourceType.DRL); 
		if ( builder.hasErrors() ) { 
			throw new RuntimeException(builder.getErrors().toString()); 
		} 
		
		builder.add( ResourceFactory.newByteArrayResource( rule3.getBytes() ), ResourceType.DRL); 
		if ( builder.hasErrors() ) { 
			throw new RuntimeException(builder.getErrors().toString()); 
		} 

		builder.add( ResourceFactory.newByteArrayResource( rule4.getBytes() ), ResourceType.DRL); 
		if ( builder.hasErrors() ) { 
			throw new RuntimeException(builder.getErrors().toString()); 
		} 
		
		KieBaseConfiguration kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); 
		KnowledgeBase knowledgeBase  = KnowledgeBaseFactory.newKnowledgeBase(kconf); 
		knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());  

		StatefulKnowledgeSession ksession = knowledgeBase.newStatefulKnowledgeSession(); 
        
        TypeC c= new TypeC();
        TypeB b= new TypeB();
        TypeA a= new TypeA();
        TypeD d= new TypeD();
        TypeE e= new TypeE();
        
		 ksession.insert(a);  
		 ksession.insert(b);  
		 ksession.insert(c);  
		 ksession.insert(d);  
		 ksession.insert(e);  
		 
		 ksession.fireAllRules();  
		 
		 Assert.assertEquals(true, a.getFirings().contains("R1 Fired"));  
		 Assert.assertEquals(true, a.getFirings().contains("R2 Fired"));  
		 Assert.assertEquals(true, a.getFirings().contains("R3 Fired"));  
		 Assert.assertEquals(true, a.getFirings().contains("R4 Fired"));  


	}
}
{code}


> AlphNode sharing fails to propagate match to BetaNode when match is defined separate rule package
> -------------------------------------------------------------------------------------------------
>
>                 Key: DROOLS-1010
>                 URL: https://issues.jboss.org/browse/DROOLS-1010
>             Project: Drools
>          Issue Type: Bug
>          Components: core engine
>    Affects Versions: 6.3.0.Final
>            Reporter: Anantjot Anand
>            Assignee: Mario Fusco
>         Attachments: AlphaNodeSharingWithDiffPackageName.java
>
>
> The issue was happening for us when LHS matches for some rules with thousands of rules in rulebase  only one rule would fire in PHREAK algo however all matches will fire in REETO. 
> It turns out the root cause was that the two rules that had LHS matching criteria are defined in separate rule package name and was stemming from AlphaNode.equals returning false when it should return true. I believe underlying issue is further in MevelConstraint.equals compares the package name.
> This can be reproduce using attached unit testcase.
> I am not sure of the reasoning behind for the MevelConstraint.equals implementation...if it is important to keep that logic same way...following workaround has worked for me.
> In class org.drools.core.reteoo.CompositeObjectSinkAdapter following function definitions..
> org.drools.core.reteoo.CompositeObjectSinkAdapter.propagateModifyObject(InternalFactHandle, ModifyPreviousTuples, PropagationContext, InternalWorkingMemory)
> org.drools.core.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(InternalFactHandle, PropagationContext, InternalWorkingMemory)
> org.drools.core.reteoo.CompositeObjectSinkAdapter.byPassModifyToBetaNode(InternalFactHandle, ModifyPreviousTuples, PropagationContext, InternalWorkingMemory)
> I changed the call from this.hashedSinkMap.get( hashKey ) to this.hashedSinkMap.getAll( hashKey ) and defined a new function as following to retrieve all alpha nodes that have same HashKey.
>     public Object[] getAll(final Object key) {
>         final int hashCode = this.comparator.hashCodeOf( key );
>         final int index = indexOf( hashCode,
>                                    this.table.length );
>         List arr = new ArrayList();
>         ObjectEntry current = (ObjectEntry) this.table[index];
>         while ( current != null ) {
>             if ( hashCode == current.cachedHashCode && this.comparator.equal( key,
>                                                                         current.key ) ) {
>                 arr.add(current.value);
>             }
>             current = (ObjectEntry) current.getNext();
>         }
>         return arr.toArray();
>     }



--
This message was sent by Atlassian JIRA
(v6.4.11#64026)


More information about the jboss-jira mailing list