Skip to content

Commit

Permalink
[DROOLS-4672] Executable model compilation fails with function call a…
Browse files Browse the repository at this point in the history
…nd large input array (apache#2628)
  • Loading branch information
lucamolteni authored and mariofusco committed Oct 25, 2019
1 parent b595e00 commit 78d8c7c
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 0 deletions.
Expand Up @@ -727,6 +727,11 @@ public static <A, B, C, D, E, F, G, H, I, J, K, L> ConsequenceBuilder._12<A, B,
return new ConsequenceBuilder._12(decl1, decl2, decl3, decl4, decl5, decl6, decl7, decl8, decl9, decl10, decl11, decl12);
}

public static <A, B, C, D, E, F, G, H, I, J, K, L, M> ConsequenceBuilder._13<A, B, C, D, E, F, G, H, I, J, K, L, M> on(Variable<A> decl1, Variable<B> decl2, Variable<C> decl3, Variable<D> decl4, Variable<E> decl5, Variable<F> decl6,
Variable<G> decl7, Variable<H> decl8, Variable<I> decl9, Variable<J> decl10, Variable<K> decl11, Variable<L> decl12, Variable<M> decl13) {
return new ConsequenceBuilder._13(decl1, decl2, decl3, decl4, decl5, decl6, decl7, decl8, decl9, decl10, decl11, decl12, decl13);
}

public static ConsequenceBuilder._N on(Variable... declarations) {
return new ConsequenceBuilder._N(declarations);
}
Expand Down
Expand Up @@ -10,6 +10,7 @@
import org.drools.model.functions.Block11;
import org.drools.model.functions.Block12;
import org.drools.model.functions.Block13;
import org.drools.model.functions.Block14;
import org.drools.model.functions.Block2;
import org.drools.model.functions.Block3;
import org.drools.model.functions.Block4;
Expand Down Expand Up @@ -381,6 +382,31 @@ public _12<A, B, C, D, E, F, G, H, I, J, K, L> executeScript(String language, Cl
}
}

public static class _13<A, B, C, D, E, F, G, H, I, J, K, L, M> extends AbstractValidBuilder<_13<A,B,C,D,E,F,G,H,I,J,K,L, M>> {
public _13(Variable<A> decl1, Variable<B> decl2, Variable<C> decl3, Variable<D> decl4, Variable<E> decl5, Variable<F> decl6,
Variable<G> decl7, Variable<H> decl8, Variable<I> decl9, Variable<J> decl10, Variable<K> decl11, Variable<L> decl12, Variable<M> decl13) {
super(decl1, decl2, decl3, decl4, decl5, decl6, decl7, decl8, decl9, decl10, decl11, decl12, decl13);
}

public _13<A, B, C, D, E, F, G, H, I, J, K, L, M> execute(final Block13<A, B, C, D, E, F, G, H, I, J, K, L, M> block) {
this.block = block.asBlockN();
return this;
}

public _13<A, B, C, D, E, F, G, H, I, J, K, L, M> execute(final Block14<Drools, A, B, C, D, E, F, G, H, I, J, K, L, M> block ) {
this.usingDrools = true;
this.block = block.asBlockN();
return this;
}

public _13<A, B, C, D, E, F, G, H, I, J, K, L, M> executeScript(String language, Class<?> ruleClass, String script) {
this.usingDrools = true;
this.language = language;
this.block = new ScriptBlock(ruleClass, script);
return this;
}
}

public static class _N extends AbstractValidBuilder<_N> {

public _N(Variable... declarations) {
Expand Down
@@ -0,0 +1,31 @@
package org.drools.model.functions;

import java.io.Serializable;

public interface Block14<A, B, C, D, E, F, G, H, I, J, K, L, M, O> extends Serializable {
void execute(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, O o) throws Exception;

default BlockN asBlockN() {
return new Impl( this );
}

class Impl extends IntrospectableLambda implements BlockN {

private final Block14 block;

public Impl(Block14 block) {
this.block = block;
}

@Override
public void execute( Object... objs ) throws Exception {
block.execute(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5], objs[6], objs[7], objs[8], objs[9], objs[10], objs[11], objs[12], objs[13]);
}

@Override
public Object getLambda() {
return block;
}
}

}
Expand Up @@ -18,6 +18,7 @@

import java.lang.reflect.Method;

import org.drools.modelcompiler.domain.InputDataTypes;
import org.drools.modelcompiler.domain.Person;
import org.drools.modelcompiler.domain.Result;
import org.junit.Test;
Expand Down Expand Up @@ -136,6 +137,23 @@ public boolean arrayContainsInstanceWithParameters(Object[] array, Object[] parm

return false;
}

public Double sumOf(Object[] objects) {
Double ret = null;
for (Object o : objects) {
if ((o instanceof Number))
{
Double d = Double.valueOf(o.toString());
if (ret == null) {
ret = d;
} else {
ret = Double.valueOf(ret.doubleValue() + d.doubleValue());
}
}
}
return ret;
}

}

@Test
Expand Down Expand Up @@ -332,4 +350,69 @@ public void testGlobalOnTypeDeclaration() throws Exception {

KieSession ksession = getKieSession(str);
}

@Test
public void testGlobalFunctionWithArrayInput() {
String str =
"package org.mypkg;" +
"import " + InputDataTypes.class.getCanonicalName() + ";" +
"import " + Functions.class.getCanonicalName() + ";" +
"global Functions functions;" +
"rule useSumOf when\n" +
" $input : InputDataTypes( $no1Count_1 : no1Count\n" +
" , $no2Count_1 : no2Count\n" +
" , $no3Count_1 : no3Count\n" +
" , $no4Count_1 : no4Count\n" +
" , $no5Count_1 : no5Count\n" +
" , $no6Count_1 : no6Count\n" +
" , $no7Count_1 : no7Count\n" +
" , $no8Count_1 : no8Count\n" +
" , $no9Count_1 : no9Count\n" +
" , $no10Count_1 : no10Count\n" +
" , firings not contains \"fired\")\n" +
"then\n" +
" $input.setNo12Count(functions.sumOf(new Object[]{$no1Count_1, $no2Count_1, $no3Count_1, $no4Count_1, $no5Count_1, $no6Count_1, $no7Count_1, $no8Count_1, $no9Count_1, $no10Count_1}).intValue());\n" +
" $input.getFirings().add(\"fired\");\n" +
" update($input);\n" +
"end";

KieSession ksession = getKieSession( str );
ksession.setGlobal("functions", new Functions());
ksession.insert(new InputDataTypes());

assertEquals( 1, ksession.fireAllRules() );
}

@Test
public void testGlobalFunctionWithLargeArrayInput() {
String str =
"package org.mypkg;" +
"import " + InputDataTypes.class.getCanonicalName() + ";" +
"import " + Functions.class.getCanonicalName() + ";" +
"global Functions functions;" +
"rule useSumOf when\n" +
" $input : InputDataTypes( $no1Count_1 : no1Count\n" +
" , $no2Count_1 : no2Count\n" +
" , $no3Count_1 : no3Count\n" +
" , $no4Count_1 : no4Count\n" +
" , $no5Count_1 : no5Count\n" +
" , $no6Count_1 : no6Count\n" +
" , $no7Count_1 : no7Count\n" +
" , $no8Count_1 : no8Count\n" +
" , $no9Count_1 : no9Count\n" +
" , $no10Count_1 : no10Count\n" +
" , $no11Count_1 : no11Count\n" +
" , firings not contains \"fired\")\n" +
"then\n" +
" $input.setNo12Count(functions.sumOf(new Object[]{$no1Count_1, $no2Count_1, $no3Count_1, $no4Count_1, $no5Count_1, $no6Count_1, $no7Count_1, $no8Count_1, $no9Count_1, $no10Count_1, $no11Count_1}).intValue());\n" +
" $input.getFirings().add(\"fired\");\n" +
" update($input);\n" +
"end";

KieSession ksession = getKieSession( str );
ksession.setGlobal("functions", new Functions());
ksession.insert(new InputDataTypes());

assertEquals( 1, ksession.fireAllRules() );
}
}
@@ -0,0 +1,130 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.modelcompiler.domain;

import java.util.ArrayList;
import java.util.List;

public class InputDataTypes{
private int no1Count;
private int no2Count;
private int no3Count;
private int no4Count;
private int no5Count;
private int no6Count;
private int no7Count;
private int no8Count;
private int no9Count;
private int no10Count;
private int no11Count;
private int no12Count;
private List<String> firings = new ArrayList<String>();

public InputDataTypes() {
no1Count = 1;
no2Count = 1;
no3Count = 1;
no4Count = 1;
no5Count = 1;
no6Count = 1;
no7Count = 1;
no8Count = 1;
no9Count = 1;
no10Count = 1;
no11Count = 1;
no12Count = 1;
}

public int getNo1Count() {
return no1Count;
}
public void setNo1Count(int no1Count) {
this.no1Count = no1Count;
}
public int getNo2Count() {
return no2Count;
}
public void setNo2Count(int no2Count) {
this.no2Count = no2Count;
}
public int getNo3Count() {
return no3Count;
}
public void setNo3Count(int no3Count) {
this.no3Count = no3Count;
}
public int getNo4Count() {
return no4Count;
}
public void setNo4Count(int no4Count) {
this.no4Count = no4Count;
}
public int getNo5Count() {
return no5Count;
}
public void setNo5Count(int no5Count) {
this.no5Count = no5Count;
}
public int getNo6Count() {
return no6Count;
}
public void setNo6Count(int no6Count) {
this.no6Count = no6Count;
}
public int getNo7Count() {
return no7Count;
}
public void setNo7Count(int no7Count) {
this.no7Count = no7Count;
}
public int getNo8Count() {
return no8Count;
}
public void setNo8Count(int no8Count) {
this.no8Count = no8Count;
}
public int getNo9Count() {
return no9Count;
}
public void setNo9Count(int no9Count) {
this.no9Count = no9Count;
}
public int getNo10Count() {
return no10Count;
}
public void setNo10Count(int no10Count) {
this.no10Count = no10Count;
}
public int getNo11Count() {
return no11Count;
}
public void setNo11Count(int no11Count) {
this.no11Count = no11Count;
}
public int getNo12Count() {
return no12Count;
}
public void setNo12Count(int no12Count) {
this.no12Count = no12Count;
}
public List<String> getFirings() {
return firings;
}
public void setFirings(List<String> firings) {
this.firings = firings;
}
}

0 comments on commit 78d8c7c

Please sign in to comment.