diff --git a/NOTICE b/NOTICE index 2fe21eeead1..43c4b92efb0 100644 --- a/NOTICE +++ b/NOTICE @@ -14,6 +14,10 @@ This product also includes the following third-party components: Downloaded from: https://lunrjs.com/ License: MIT +* Saxon-HE + Downloaded from: https://www.saxonica.com/ + License: Mozilla Public License 2.0 + * search-ui Downloaded from: https://gitlab.com/antora/antora-lunr-extension License: Mozilla Public License 2.0 diff --git a/build-parent/pom.xml b/build-parent/pom.xml index eb2cdb36d1f..a382b7c2310 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -66,7 +66,7 @@ 4.31.0 3.7.4 1.0.1 - 3.25.0 + 3.25.5 2.2.220 1.0.86 4.0.4 diff --git a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderImpl.java b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderImpl.java index ec1cb65533d..61e1796506f 100644 --- a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderImpl.java +++ b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderImpl.java @@ -298,6 +298,12 @@ private static void buildKieProject( BuildContext buildContext, kieRepository.addKieModule( kDep ); } } + + clearBuilderCache(); + } + + private static void clearBuilderCache() { + DecisionTableFactory.clearCompilerCache(); } private void addKBasesFilesToTrg() { diff --git a/drools-decisiontables/pom.xml b/drools-decisiontables/pom.xml index f916aee6d04..9aaa947aa23 100644 --- a/drools-decisiontables/pom.xml +++ b/drools-decisiontables/pom.xml @@ -87,8 +87,13 @@ - junit - junit + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core test @@ -101,11 +106,6 @@ logback-classic test - - org.assertj - assertj-core - test - diff --git a/drools-decisiontables/src/main/java/org/drools/decisiontable/DecisionTableProviderImpl.java b/drools-decisiontables/src/main/java/org/drools/decisiontable/DecisionTableProviderImpl.java index a809b8ff8e1..a843964a7fa 100644 --- a/drools-decisiontables/src/main/java/org/drools/decisiontable/DecisionTableProviderImpl.java +++ b/drools-decisiontables/src/main/java/org/drools/decisiontable/DecisionTableProviderImpl.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.drools.decisiontable.parser.xls.PropertiesSheetListener; import org.drools.drl.extensions.DecisionTableProvider; @@ -42,7 +43,9 @@ public class DecisionTableProviderImpl implements DecisionTableProvider { - private static final transient Logger logger = LoggerFactory.getLogger( DecisionTableProviderImpl.class ); + private static final Logger logger = LoggerFactory.getLogger( DecisionTableProviderImpl.class ); + + private Map compiledDtablesCache = new ConcurrentHashMap<>(); @Override public String loadFromResource(Resource resource, @@ -50,8 +53,6 @@ public String loadFromResource(Resource resource, try { return compileResource( resource, configuration ); - } catch (IOException e) { - throw new UncheckedIOException( e ); } catch (Exception e) { throw new DecisionTableParseException(resource, e); } @@ -78,29 +79,46 @@ public List loadFromInputStreamWithTemplates(Resource resource, return drls; } - private String compileResource(Resource resource, - DecisionTableConfiguration configuration) throws IOException { + private String compileResource(Resource resource, DecisionTableConfiguration configuration) { + if (resource.getSourcePath() == null) { + return internalCompileResource(resource, configuration); + } + String resourceKey = resource.getSourcePath() + "?trimCell=" + configuration.isTrimCell() + "&worksheetName=" + configuration.getWorksheetName(); + return compiledDtablesCache.computeIfAbsent(resourceKey, path -> internalCompileResource(resource, configuration)); + } + + private String internalCompileResource(Resource resource, DecisionTableConfiguration configuration) throws UncheckedIOException { SpreadsheetCompiler compiler = new SpreadsheetCompiler(configuration.isTrimCell()); switch ( configuration.getInputType() ) { case XLS : case XLSX : if ( StringUtils.isEmpty( configuration.getWorksheetName() ) ) { - return compiler.compile( resource, - InputType.XLS ); + return compiler.compile( resource, InputType.XLS ); } else { - return compiler.compile( resource.getInputStream(), - configuration.getWorksheetName() ); + try { + return compiler.compile( resource.getInputStream(), configuration.getWorksheetName() ); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } case CSV : { - return compiler.compile( resource.getInputStream(), - InputType.CSV ); + try { + return compiler.compile( resource.getInputStream(), InputType.CSV ); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } } return null; } + @Override + public void clearCompilerCache() { + compiledDtablesCache.clear(); + } + @Override public Map> loadPropertiesFromFile(File file, DecisionTableConfiguration configuration) { switch (configuration.getInputType()) { diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/CalendarTimerResourcesTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/CalendarTimerResourcesTest.java index 875c57a2f9f..35ce863d23f 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/CalendarTimerResourcesTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/CalendarTimerResourcesTest.java @@ -21,9 +21,9 @@ import java.util.Calendar; import java.util.concurrent.TimeUnit; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; @@ -42,7 +42,7 @@ public class CalendarTimerResourcesTest { private SessionPseudoClock clock; - @Before + @BeforeEach public void init() { final KieServices ks = KieServices.Factory.get(); @@ -66,7 +66,7 @@ public void init() { clock = ksession.getSessionClock(); } - @After + @AfterEach public void tearDown() { if (ksession != null) { diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/ColumnReplaceTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/ColumnReplaceTest.java index 62b75c7751d..a70b119dddf 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/ColumnReplaceTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/ColumnReplaceTest.java @@ -21,7 +21,7 @@ import org.drools.base.definitions.rule.impl.RuleImpl; import org.drools.kiesession.rulebase.InternalKnowledgeBase; import org.drools.kiesession.rulebase.KnowledgeBaseFactory; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.kie.api.io.ResourceType; import org.kie.internal.builder.DecisionTableConfiguration; import org.kie.internal.builder.DecisionTableInputType; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/DecimalSeparatorTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/DecimalSeparatorTest.java index 92e749eca2c..da45b0d48cf 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/DecimalSeparatorTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/DecimalSeparatorTest.java @@ -20,8 +20,8 @@ import java.util.Locale; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; @@ -56,7 +56,7 @@ public void init() { ksession = ks.newKieContainer(ks.getRepository().getDefaultReleaseId()).newKieSession(); } - @After + @AfterEach public void tearDown() { if (ksession != null) { ksession.dispose(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/DumpGeneratedDrlTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/DumpGeneratedDrlTest.java index 214859716fe..b58f03248db 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/DumpGeneratedDrlTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/DumpGeneratedDrlTest.java @@ -23,9 +23,9 @@ import org.apache.commons.io.FileUtils; import org.drools.util.IoUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.ReleaseId; import org.kie.api.io.Resource; @@ -57,7 +57,7 @@ public class DumpGeneratedDrlTest { private File dumpDir; private String dumpDirPropOrigValue; - @Before + @BeforeEach public void setUp() { dumpDir = new File("target/drools-dump-dir"); // delete the dir before test to remove possible leftovers from previous runs @@ -71,7 +71,7 @@ public void setUp() { System.setProperty(DumpDirOption.PROPERTY_NAME, dumpDir.getAbsolutePath()); } - @After + @AfterEach public void tearDown() { if (dumpDirPropOrigValue != null) { System.setProperty(DumpDirOption.PROPERTY_NAME, dumpDirPropOrigValue); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/EmptyHeaderTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/EmptyHeaderTest.java index d3be1fbfb0e..1a03b5bdee8 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/EmptyHeaderTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/EmptyHeaderTest.java @@ -19,11 +19,12 @@ package org.drools.decisiontable; import org.drools.template.parser.DecisionTableParseException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.kie.internal.builder.DecisionTableConfiguration; import org.kie.internal.builder.KnowledgeBuilder; import org.kie.internal.builder.KnowledgeBuilderFactory; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.kie.api.io.ResourceType.DTABLE; import static org.kie.internal.builder.DecisionTableInputType.CSV; import static org.kie.internal.builder.DecisionTableInputType.XLS; @@ -31,21 +32,23 @@ public class EmptyHeaderTest { - @Test(expected = DecisionTableParseException.class) + @Test public void testEmptyConditionInXLS() { DecisionTableConfiguration dtconf = KnowledgeBuilderFactory.newDecisionTableConfiguration(); dtconf.setInputType(XLS); KnowledgeBuilder kbuilder = KnowledgeBuilderFactory .newKnowledgeBuilder(); - kbuilder.add(newClassPathResource("emptyCondition.drl.xls", getClass()), DTABLE, dtconf); + assertThatExceptionOfType((DecisionTableParseException.class)).isThrownBy( + () -> kbuilder.add(newClassPathResource("emptyCondition.drl.xls", getClass()), DTABLE, dtconf)); } - @Test(expected = DecisionTableParseException.class) + @Test public void testEmptyActionInCSV() { DecisionTableConfiguration dtconf = KnowledgeBuilderFactory.newDecisionTableConfiguration(); dtconf.setInputType(CSV); KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); - kbuilder.add(newClassPathResource("emptyAction.drl.csv", getClass()), DTABLE, dtconf); + assertThatExceptionOfType((DecisionTableParseException.class)).isThrownBy( + () -> kbuilder.add(newClassPathResource("emptyAction.drl.csv", getClass()), DTABLE, dtconf)); } } diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerTest.java index ede2030c4d4..6ce3b82e134 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/ExternalSpreadsheetCompilerTest.java @@ -29,8 +29,8 @@ import org.drools.kiesession.rulebase.KnowledgeBaseFactory; import org.drools.template.parser.DataListener; import org.drools.template.parser.TemplateDataListener; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; import org.kie.internal.builder.KnowledgeBuilder; @@ -49,7 +49,7 @@ public class ExternalSpreadsheetCompilerTest { private ExternalSpreadsheetCompiler converter; - @Before + @BeforeEach public void setUp() { converter = new ExternalSpreadsheetCompiler(); } diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/FixedPatternTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/FixedPatternTest.java index 99d1f0adc48..02fe7159aa5 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/FixedPatternTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/FixedPatternTest.java @@ -23,8 +23,8 @@ import org.drools.kiesession.rulebase.InternalKnowledgeBase; import org.drools.kiesession.rulebase.KnowledgeBaseFactory; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; import org.kie.internal.builder.DecisionTableConfiguration; @@ -40,7 +40,7 @@ public class FixedPatternTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { ksession.dispose(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/IgnoreNumericFormatTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/IgnoreNumericFormatTest.java index 857ace04324..1f854ee2324 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/IgnoreNumericFormatTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/IgnoreNumericFormatTest.java @@ -23,8 +23,8 @@ import org.drools.kiesession.rulebase.InternalKnowledgeBase; import org.drools.kiesession.rulebase.KnowledgeBaseFactory; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; import org.kie.internal.builder.DecisionTableConfiguration; @@ -40,7 +40,7 @@ public class IgnoreNumericFormatTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { ksession.dispose(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/LineBreakXLSTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/LineBreakXLSTest.java index 864e15ccd46..37903db8589 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/LineBreakXLSTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/LineBreakXLSTest.java @@ -21,8 +21,8 @@ import com.sample.FactData; import org.drools.kiesession.rulebase.InternalKnowledgeBase; import org.drools.kiesession.rulebase.KnowledgeBaseFactory; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; import org.kie.internal.builder.DecisionTableConfiguration; @@ -38,7 +38,7 @@ public class LineBreakXLSTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { ksession.dispose(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/LinkedWorkbookTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/LinkedWorkbookTest.java index 557bbc8fdf2..7be86113af9 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/LinkedWorkbookTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/LinkedWorkbookTest.java @@ -20,7 +20,7 @@ import java.io.InputStream; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.kie.api.KieBase; import org.kie.api.io.ResourceType; import org.kie.internal.io.ResourceFactory; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/MakeSureMultiLinesWorkTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/MakeSureMultiLinesWorkTest.java index 4200d906990..2d539087876 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/MakeSureMultiLinesWorkTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/MakeSureMultiLinesWorkTest.java @@ -20,8 +20,7 @@ import java.io.InputStream; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; import org.kie.api.KieBase; import org.kie.api.io.ResourceType; import org.kie.internal.io.ResourceFactory; @@ -29,10 +28,10 @@ import static org.assertj.core.api.Assertions.assertThat; -@Ignore +@Disabled public class MakeSureMultiLinesWorkTest { - @Test + @org.junit.jupiter.api.Test public void makeSureMultiLinesWork() { KieHelper kieHelper = new KieHelper(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/PrioritySetWithFormulaTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/PrioritySetWithFormulaTest.java index 35f057a84d8..9610a8baac9 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/PrioritySetWithFormulaTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/PrioritySetWithFormulaTest.java @@ -19,8 +19,8 @@ package org.drools.decisiontable; import org.drools.base.definitions.rule.impl.RuleImpl; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.kie.api.KieBase; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; @@ -33,7 +33,7 @@ public class PrioritySetWithFormulaTest { private KieBase kieBase; - @Before + @BeforeEach public void init() { final KieServices ks = KieServices.Factory.get(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java index b7b7a897cab..33f3d2d7dd8 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetCompilerUnitTest.java @@ -34,8 +34,8 @@ import org.drools.template.model.Global; import org.drools.template.model.Import; import org.drools.template.parser.DataListener; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.kie.api.KieBase; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; @@ -61,7 +61,7 @@ public class SpreadsheetCompilerUnitTest { private SpreadsheetCompiler converter; - @Before + @BeforeEach public void setUp() { converter = new SpreadsheetCompiler(); } diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetIntegrationExampleTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetIntegrationExampleTest.java index 4114466232a..11e5711d95e 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetIntegrationExampleTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/SpreadsheetIntegrationExampleTest.java @@ -22,8 +22,8 @@ import java.util.List; import org.acme.insurance.launcher.PricingRuleLauncher; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.KieBase; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; @@ -44,7 +44,7 @@ public class SpreadsheetIntegrationExampleTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { ksession.dispose(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/UnicodeInCSVTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/UnicodeInCSVTest.java index 9f8da876726..9b8da2b6eae 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/UnicodeInCSVTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/UnicodeInCSVTest.java @@ -24,8 +24,8 @@ import org.drools.drl.extensions.DecisionTableFactory; import org.drools.kiesession.rulebase.InternalKnowledgeBase; import org.drools.kiesession.rulebase.KnowledgeBaseFactory; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.command.Command; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; @@ -43,7 +43,7 @@ public class UnicodeInCSVTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { ksession.dispose(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/UnicodeInXLSTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/UnicodeInXLSTest.java index 43dedef0e93..c385dadcc3f 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/UnicodeInXLSTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/UnicodeInXLSTest.java @@ -24,8 +24,8 @@ import org.drools.drl.extensions.DecisionTableFactory; import org.drools.kiesession.rulebase.InternalKnowledgeBase; import org.drools.kiesession.rulebase.KnowledgeBaseFactory; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.command.Command; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; @@ -43,7 +43,7 @@ public class UnicodeInXLSTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { ksession.dispose(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/XlsFormulaTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/XlsFormulaTest.java index 0536688654b..eb0a5bb3171 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/XlsFormulaTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/XlsFormulaTest.java @@ -21,8 +21,8 @@ import java.util.ArrayList; import java.util.List; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; @@ -36,7 +36,7 @@ public class XlsFormulaTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { ksession.dispose(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/integrationtests/IncrementalCompilationTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/integrationtests/IncrementalCompilationTest.java index ff6213f89f3..373ce0b37c7 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/integrationtests/IncrementalCompilationTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/integrationtests/IncrementalCompilationTest.java @@ -21,7 +21,7 @@ import java.io.InputStream; import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/integrationtests/KModuleWithDecisionTablesTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/integrationtests/KModuleWithDecisionTablesTest.java index 8ec05fd9d7d..4eee4f66c46 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/integrationtests/KModuleWithDecisionTablesTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/integrationtests/KModuleWithDecisionTablesTest.java @@ -18,7 +18,6 @@ */ package org.drools.decisiontable.integrationtests; -import org.junit.Test; import org.kie.api.KieBase; import org.kie.api.KieServices; import org.kie.api.builder.KieFileSystem; @@ -27,6 +26,8 @@ import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; + /** * Basic tests for creation of a KieBase from CSV and XLS resources. */ diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ActionTypeTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ActionTypeTest.java index d86cd606185..1c0572eda70 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ActionTypeTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ActionTypeTest.java @@ -22,7 +22,7 @@ import java.util.Map; import org.drools.decisiontable.parser.ActionType.Code; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java index 20384ab5118..3bf6c558119 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/ColumnFactoryTest.java @@ -23,8 +23,8 @@ import org.drools.template.parser.ColumnFactory; import org.drools.template.parser.LongColumn; import org.drools.template.parser.StringColumn; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -33,7 +33,7 @@ public class ColumnFactoryTest { private ColumnFactory f; - @Before + @BeforeEach public void setUp() { f = new ColumnFactory(); } diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/LhsBuilderTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/LhsBuilderTest.java index 4ba1b0c0be0..25ff4a2e599 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/LhsBuilderTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/LhsBuilderTest.java @@ -18,7 +18,7 @@ */ package org.drools.decisiontable.parser; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.drools.decisiontable.parser.LhsBuilder.FieldType.FORALL_FIELD; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/PropertiesSheetListenerTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/PropertiesSheetListenerTest.java index acba2c64b5a..1a7657af207 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/PropertiesSheetListenerTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/PropertiesSheetListenerTest.java @@ -20,7 +20,7 @@ import org.drools.decisiontable.parser.xls.PropertiesSheetListener; import org.drools.decisiontable.parser.xls.PropertiesSheetListener.CaseInsensitiveMap; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.drools.template.parser.DataListener.NON_MERGED; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RhsBuilderTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RhsBuilderTest.java index 555af32b981..81cadaa6419 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RhsBuilderTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RhsBuilderTest.java @@ -18,7 +18,7 @@ */ package org.drools.decisiontable.parser; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleSheetParserUtilTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleSheetParserUtilTest.java index 3463fc43829..e10aa378866 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleSheetParserUtilTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleSheetParserUtilTest.java @@ -23,8 +23,8 @@ import org.drools.template.model.Global; import org.drools.template.model.Import; import org.drools.template.parser.DecisionTableParseException; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -52,7 +52,7 @@ public void testRuleName() { /** * This is here as the old way was to do this. */ - @Ignore + @Disabled @Test public void testInvalidRuleName() { final String row = "RuleTable This is my rule name (type class)"; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParse2Test.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParse2Test.java index 64f56d6cc17..cc98b5b43a4 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParse2Test.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParse2Test.java @@ -22,7 +22,7 @@ import org.drools.template.model.Package; import org.drools.template.parser.DataListener; import org.drools.template.parser.DecisionTableParseException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatException; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseFromFileTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseFromFileTest.java index 1857e5fed37..7dbbe642b7a 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseFromFileTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseFromFileTest.java @@ -29,8 +29,8 @@ import org.drools.template.model.Package; import org.drools.template.model.Rule; import org.drools.template.parser.DecisionTableParseException; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -180,7 +180,8 @@ public void testComplexWorksheetMissingConditionsInLocaleEnUs() throws Exception } } - @Test @Ignore // TODO JBRULES-2880 TIRELLI: Ignore test while we decide what to do in order to solve i18n issues + @Disabled // TODO JBRULES-2880 TIRELLI: Ignore test while we decide what to do in order to solve i18n issues + @Test public void testComplexWorksheetMissingConditionsInLocaleFrFr() throws Exception { Locale originalDefaultLocale = Locale.getDefault(); Locale.setDefault(Locale.FRANCE); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseLargeTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseLargeTest.java index 5aa984eb3bb..de7a9edceaa 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseLargeTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/RuleWorksheetParseLargeTest.java @@ -21,7 +21,7 @@ import java.io.InputStream; import org.drools.template.model.Package; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvLineParserTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvLineParserTest.java index 01cdff89842..66d1cd5e00b 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvLineParserTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvLineParserTest.java @@ -20,7 +20,7 @@ import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java index ff69bb3ad50..0c120756e3e 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/csv/CsvParserTest.java @@ -22,7 +22,7 @@ import java.util.Map; import org.drools.template.parser.DataListener; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.drools.template.parser.DataListener.NON_MERGED; diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/ExcelParserTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/ExcelParserTest.java index 90556d0615d..219db5752de 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/ExcelParserTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/parser/xls/ExcelParserTest.java @@ -29,8 +29,8 @@ import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.drools.template.parser.DataListener; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -47,7 +47,7 @@ public class ExcelParserTest { private Sheet sheet; - @After + @AfterEach public void tearDown() throws IOException { if(workbook != null) { workbook.close(); diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/project/MultiKieBaseTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/project/MultiKieBaseTest.java index 1deb04797a4..8d28fd985b8 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/project/MultiKieBaseTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/project/MultiKieBaseTest.java @@ -18,8 +18,8 @@ */ package org.drools.decisiontable.project; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; @@ -34,7 +34,7 @@ public class MultiKieBaseTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { diff --git a/drools-decisiontables/src/test/java/org/drools/decisiontable/project/MultiSheetsTest.java b/drools-decisiontables/src/test/java/org/drools/decisiontable/project/MultiSheetsTest.java index 0b44cf395b3..182f8c8afaf 100644 --- a/drools-decisiontables/src/test/java/org/drools/decisiontable/project/MultiSheetsTest.java +++ b/drools-decisiontables/src/test/java/org/drools/decisiontable/project/MultiSheetsTest.java @@ -18,8 +18,6 @@ */ package org.drools.decisiontable.project; -import org.junit.After; -import org.junit.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; @@ -28,13 +26,16 @@ import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + import static org.assertj.core.api.Assertions.assertThat; public class MultiSheetsTest { private KieSession ksession; - @After + @AfterEach public void tearDown() { if (ksession != null) { diff --git a/drools-drl/drools-drl-extensions/src/main/java/org/drools/drl/extensions/DecisionTableFactory.java b/drools-drl/drools-drl-extensions/src/main/java/org/drools/drl/extensions/DecisionTableFactory.java index caef7c8ed27..ab46e273557 100644 --- a/drools-drl/drools-drl-extensions/src/main/java/org/drools/drl/extensions/DecisionTableFactory.java +++ b/drools-drl/drools-drl-extensions/src/main/java/org/drools/drl/extensions/DecisionTableFactory.java @@ -42,6 +42,12 @@ public static List loadFromInputStreamWithTemplates(Resource resource, D return getDecisionTableProvider().loadFromInputStreamWithTemplates( resource, configuration ); } + public static void clearCompilerCache() { + if (provider != null) { + provider.clearCompilerCache(); + } + } + public static synchronized void setDecisionTableProvider(DecisionTableProvider provider) { DecisionTableFactory.provider = provider; } diff --git a/drools-drl/drools-drl-extensions/src/main/java/org/drools/drl/extensions/DecisionTableProvider.java b/drools-drl/drools-drl-extensions/src/main/java/org/drools/drl/extensions/DecisionTableProvider.java index 7b2fbdc0551..c11a1f9a78e 100644 --- a/drools-drl/drools-drl-extensions/src/main/java/org/drools/drl/extensions/DecisionTableProvider.java +++ b/drools-drl/drools-drl-extensions/src/main/java/org/drools/drl/extensions/DecisionTableProvider.java @@ -29,13 +29,13 @@ public interface DecisionTableProvider extends KieService { - String loadFromResource(Resource resource, - DecisionTableConfiguration configuration); + String loadFromResource(Resource resource, DecisionTableConfiguration configuration); - List loadFromInputStreamWithTemplates(Resource resource, - DecisionTableConfiguration configuration); + List loadFromInputStreamWithTemplates(Resource resource, DecisionTableConfiguration configuration); Map> loadPropertiesFromFile(File file, DecisionTableConfiguration configuration); Map> loadPropertiesFromInputStream(InputStream inputStream, DecisionTableConfiguration configuration); + + void clearCompilerCache(); } diff --git a/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/pom.xml b/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/pom.xml index 0ff6b0f9605..4940cce95d9 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/pom.xml +++ b/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/pom.xml @@ -34,13 +34,13 @@ - org.assertj - assertj-core + org.junit.jupiter + junit-jupiter test - junit - junit + org.assertj + assertj-core test diff --git a/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/java/org/drools/drlonyaml/cli/tests/ConversionsUsingCliTest.java b/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/java/org/drools/drlonyaml/cli/tests/ConversionsUsingCliTest.java index d9e8ed0570d..ba58e64cf1d 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/java/org/drools/drlonyaml/cli/tests/ConversionsUsingCliTest.java +++ b/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/java/org/drools/drlonyaml/cli/tests/ConversionsUsingCliTest.java @@ -23,7 +23,7 @@ import java.io.InputStream; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class ConversionsUsingCliTest { diff --git a/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/pom.xml b/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/pom.xml index d9eaa5c8b58..72e71252110 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/pom.xml +++ b/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/pom.xml @@ -47,8 +47,8 @@ test - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/src/test/java/org/drools/drlonyaml/integration/tests/ProgrammaticProjectTest.java b/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/src/test/java/org/drools/drlonyaml/integration/tests/ProgrammaticProjectTest.java index 9496a739438..00ba840ce00 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/src/test/java/org/drools/drlonyaml/integration/tests/ProgrammaticProjectTest.java +++ b/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/src/test/java/org/drools/drlonyaml/integration/tests/ProgrammaticProjectTest.java @@ -18,72 +18,26 @@ */ package org.drools.drlonyaml.integration.tests; -import java.io.StringReader; -import java.io.StringWriter; import java.util.ArrayList; import java.util.List; +import java.util.stream.Stream; -import org.drools.drl.ast.descr.PackageDescr; -import org.drools.drl.parser.DrlParser; -import org.drools.drlonyaml.model.DrlPackage; import org.drools.model.codegen.ExecutableModelProject; -import org.junit.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.kie.api.runtime.KieSession; import org.kie.internal.utils.KieHelper; import static org.assertj.core.api.Assertions.assertThat; -import static org.drools.drlonyaml.model.Utils.getYamlMapper; public class ProgrammaticProjectTest { - @Test - public void testDrl() { - KieSession ksession = new KieHelper() - .addContent(getDrlRule(), "org/drools/drlonyaml/integration/tests/rule.drl") - .build(ExecutableModelProject.class) - .newKieSession(); - - checkKieSession(ksession); - } - - @Test - public void testYaml() { - KieSession ksession = new KieHelper() - .addContent(getYamlRule(), "org/drools/drlonyaml/integration/tests/rule.drl.yaml") - .build(ExecutableModelProject.class) - .newKieSession(); - - checkKieSession(ksession); - } - - private static void checkKieSession(KieSession ksession) { - List result = new ArrayList<>(); - ksession.setGlobal("result", result); - - ksession.insert(new Message("test")); - ksession.insert(new Message("Hello World")); - ksession.insert(10); - ksession.insert(11); - - int count = ksession.fireAllRules(); - assertThat(count).isEqualTo(1); - assertThat(result).hasSize(1); - assertThat(result.get(0)).isEqualTo("Hello World"); - } - - private String drl2yaml(String drl) { - try (StringWriter writer = new StringWriter()) { - PackageDescr pkgDescr = new DrlParser().parse(new StringReader(drl)); - DrlPackage model = DrlPackage.from(pkgDescr); - getYamlMapper().writeValue(writer, model); - return writer.toString(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - private String getDrlRule() { - return """ + private static Stream params() { + return Stream.of( + Arguments.of("org/drools/drlonyaml/integration/tests/rule.drl", + """ package org.drools.drlonyaml.integration.tests global java.util.List result; @@ -93,25 +47,49 @@ private String getDrlRule() { $m : Message( size == $i ) then result.add( $m.getText() ); - end"""; + end"""), + + Arguments.of("org/drools/drlonyaml/integration/tests/rule.drl.yaml", + """ + name: org.drools.drlonyaml.integration.tests + globals: + - type: java.util.List + id: result + rules: + - name: R + when: + - given: Integer + as: $i + - given: Message + as: $m + having: + - size == $i + then: | + result.add( $m.getText() );""") + ); } + + @ParameterizedTest + @MethodSource("params") + public void test1(String name, String content) { + KieSession ksession = new KieHelper() + .addContent(content, name) + .build(ExecutableModelProject.class) + .newKieSession(); - private String getYamlRule() { - return """ - name: org.drools.drlonyaml.integration.tests - globals: - - type: java.util.List - id: result - rules: - - name: R - when: - - given: Integer - as: $i - - given: Message - as: $m - having: - - size == $i - then: | - result.add( $m.getText() );"""; + List result = new ArrayList<>(); + ksession.setGlobal("result", result); + + ksession.insert(new Message("test")); + ksession.insert(new Message("Hello World")); + ksession.insert(10); + ksession.insert(11); + + int count = ksession.fireAllRules(); + assertThat(count).isEqualTo(1); + assertThat(result).hasSize(1); + assertThat(result.get(0)).isEqualTo("Hello World"); } + + } diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/pom.xml b/drools-drlonyaml-parent/drools-drlonyaml-model/pom.xml index 028ef1f3813..261bba95a2c 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/pom.xml +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/pom.xml @@ -48,8 +48,8 @@ test - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/java/org/drools/drlonyaml/model/SmokeTest.java b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/java/org/drools/drlonyaml/model/SmokeTest.java index 7834b23d941..72b9381c759 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/java/org/drools/drlonyaml/model/SmokeTest.java +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/java/org/drools/drlonyaml/model/SmokeTest.java @@ -26,11 +26,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; -import org.assertj.core.api.Assertions; import org.drools.drl.ast.descr.PackageDescr; import org.drools.drl.parser.DrlParser; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,91 +46,40 @@ public class SmokeTest { YAMLFactory yamlFactory = YAMLFactory.builder().enable(Feature.MINIMIZE_QUOTES).build(); mapper = new ObjectMapper(yamlFactory); } - - private void assertDrlToYamlAndBack(String filename) { - try { - String content = Files.readString(Paths.get(this.getClass().getResource(filename).toURI())); - assertThat(content).as("Failed to read test resource").isNotNull(); - - PackageDescr pkgDescr = drlParser.parse(new StringReader(content)); - assertThat(pkgDescr).as("Failed to parse DRL as a PackageDescr").isNotNull(); - - DrlPackage model = DrlPackage.from(pkgDescr); - assertThat(model).as("Failed to generate from a PackageDescr a valid model").isNotNull(); - - StringWriter writer = new StringWriter(); - mapper.writeValue(writer, model); - final String yaml = writer.toString(); - writer.close(); - LOG.debug("{}", yaml); - assertThat(yaml).as("resulting YAML shall not be null nor empty").isNotNull().isNotEmpty(); - - final DrlPackage deserPackage = mapper.readValue(yaml, DrlPackage.class); - assertThat(deserPackage).usingRecursiveComparison().isEqualTo(model); - } catch (Exception e) { - Assertions.fail("Failed to roundtrip from DRL to YAML and back to YAML", e); - } - } - - @Test - public void smokeTestFromDRL1() { - String filename = "/smoketests/smoke1.drl.txt"; - assertDrlToYamlAndBack(filename); - } - - @Test - public void smokeTestFromDRL2() { - String filename = "/smoketests/smoke2.drl.txt"; - assertDrlToYamlAndBack(filename); - } - - @Test - public void smokeTestFromDRL3() { - String filename = "/smoketests/smoke3.drl.txt"; - assertDrlToYamlAndBack(filename); - } - - @Test - public void smokeTestFromDRL4() { - String filename = "/smoketests/smoke4.drl.txt"; - assertDrlToYamlAndBack(filename); - } - - @Test - public void smokeTestFromDRL5() { - String filename = "/smoketests/smoke5.drl.txt"; - assertDrlToYamlAndBack(filename); - } - - @Test - public void smokeTestFromDRL6() { - String filename = "/smoketests/smoke6.drl.txt"; - assertDrlToYamlAndBack(filename); - } - - @Test - public void smokeTestFromDRL7() { - String filename = "/smoketests/smoke7.drl.txt"; - assertDrlToYamlAndBack(filename); - } - - @Test - public void smokeTestFromDRL8() { - String filename = "/smoketests/smoke8.drl.txt"; - assertDrlToYamlAndBack(filename); - } - @Test - public void smokeTestFromDRL9() { - String filename = "/smoketests/smoke9.drl.txt"; - assertDrlToYamlAndBack(filename); + @ParameterizedTest + @ValueSource(strings = {"/smoketests/smoke1.drl.txt", + "/smoketests/smoke2.drl.txt", + "/smoketests/smoke3.drl.txt", + "/smoketests/smoke4.drl.txt", + "/smoketests/smoke5.drl.txt", + "/smoketests/smoke6.drl.txt", + "/smoketests/smoke7.drl.txt", + "/smoketests/smoke8.drl.txt", + "/smoketests/smoke9.drl.txt", + "/smoketests/smoke10.drl.txt", + "/smoketests/ruleunit.drl.txt"}) + public void smokeTestFromDrl(String filename ) throws Exception { + String content = Files.readString(Paths.get(this.getClass().getResource(filename).toURI())); + assertThat(content).as("Failed to read test resource").isNotNull(); + + PackageDescr pkgDescr = drlParser.parse(new StringReader(content)); + assertThat(pkgDescr).as("Failed to parse DRL as a PackageDescr").isNotNull(); + + DrlPackage model = DrlPackage.from(pkgDescr); + assertThat(model).as("Failed to generate from a PackageDescr a valid model").isNotNull(); + + StringWriter writer = new StringWriter(); + mapper.writeValue(writer, model); + final String yaml = writer.toString(); + writer.close(); + LOG.debug("{}", yaml); + assertThat(yaml).as("resulting YAML shall not be null nor empty").isNotNull().isNotEmpty(); + + final DrlPackage deserPackage = mapper.readValue(yaml, DrlPackage.class); + assertThat(deserPackage).usingRecursiveComparison().isEqualTo(model); } - @Test - public void smokeTestFromDRL10() { - String filename = "/smoketests/smoke10.drl.txt"; - assertDrlToYamlAndBack(filename); - } @Test public void smokeTestFromYAML1() throws Exception { @@ -138,17 +88,11 @@ public void smokeTestFromYAML1() throws Exception { LOG.debug("{}", result); } - @Ignore("additional RHS types not supported at the moment.") + @Disabled("additional RHS types not supported at the moment.") @Test public void smokeTestFromYAML2() throws Exception { String content = Files.readString(Paths.get(this.getClass().getResource("/smoketests/yamlfirst_smoke2.yml").toURI())); DrlPackage result = mapper.readValue(content, DrlPackage.class); LOG.debug("{}", result); } - - @Test - public void smokeTestWithRuleUnit() { - String filename = "/smoketests/ruleunit.drl.txt"; - assertDrlToYamlAndBack(filename); - } } diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/ruleunit.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/ruleunit.drl.txt index f1b339c2923..05a31009864 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/ruleunit.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/ruleunit.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl package org.drools.unit; diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke1.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke1.drl.txt index b49f61129d2..a25ab8c7c08 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke1.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke1.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl package ciao; import java.lang.Number; diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke10.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke10.drl.txt index d77fe605710..2811602f686 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke10.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke10.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl rule "Fix the PersistentVolume Claim Pod PENDING" when diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke2.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke2.drl.txt index 4539cd23ba6..0c8bb96fd6f 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke2.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke2.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl rule "Relax the ResourceQuota limits Deployment PENDING" when diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke3.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke3.drl.txt index 61a4065193c..dfeb7e35e50 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke3.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke3.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl rule "Relax the ResourceQuota limits StatefulSet PENDING" when diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke4.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke4.drl.txt index b1ef8c16c4b..41282d20725 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke4.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke4.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl rule "Fix the Service targetPort and the containerPort" when diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke5.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke5.drl.txt index 4672fef44dd..074d2188c48 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke5.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke5.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl function boolean mapContains(Map left, Map right) { if (left == null) { diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke6.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke6.drl.txt index 87409c9bcb8..c76ac5b741a 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke6.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke6.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl rule "Fix the Service selector No Pod found for selector" when diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke7.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke7.drl.txt index 22c39107a70..bc06894a191 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke7.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke7.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl rule "Fix the Service selector matches Pod name, but other selectors don't" when diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke8.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke8.drl.txt index f7a5d2fcfad..78ee766b1bc 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke8.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke8.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl rule "Fix the Service selector sounds like Pod name but not an exact match" when diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke9.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke9.drl.txt index a486b710bc1..911857a3906 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke9.drl.txt +++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/test/resources/smoketests/smoke9.drl.txt @@ -1,3 +1,21 @@ +/** + * 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 + * + * 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. + */ // this is only syntactically valid DRL, so not ending with purely .drl rule "Relax the ResourceQuota limits Deployment PENDING" when diff --git a/drools-drlonyaml-parent/drools-drlonyaml-todrl/pom.xml b/drools-drlonyaml-parent/drools-drlonyaml-todrl/pom.xml index 809af59c402..6e370a93d64 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-todrl/pom.xml +++ b/drools-drlonyaml-parent/drools-drlonyaml-todrl/pom.xml @@ -51,8 +51,8 @@ test - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/drools-drlonyaml-parent/drools-drlonyaml-todrl/src/test/java/org/drools/drlonyaml/todrl/YAMLtoDRLTest.java b/drools-drlonyaml-parent/drools-drlonyaml-todrl/src/test/java/org/drools/drlonyaml/todrl/YAMLtoDRLTest.java index b412c07a3a1..ebdf16d646f 100644 --- a/drools-drlonyaml-parent/drools-drlonyaml-todrl/src/test/java/org/drools/drlonyaml/todrl/YAMLtoDRLTest.java +++ b/drools-drlonyaml-parent/drools-drlonyaml-todrl/src/test/java/org/drools/drlonyaml/todrl/YAMLtoDRLTest.java @@ -25,11 +25,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; -import org.assertj.core.api.Assertions; import org.drools.drl.ast.descr.PackageDescr; import org.drools.drl.parser.DrlParser; import org.drools.drlonyaml.model.DrlPackage; -import org.junit.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,77 +46,30 @@ public class YAMLtoDRLTest { mapper = new ObjectMapper(yamlFactory); } - private void assertDumpingYAMLtoDRLisValid(String filename) { - try { - final String yamlText = Files.readString(Paths.get(YAMLtoDRLTest.class.getResource(filename).toURI())); - assertThat(yamlText).as("Failed to read test resource").isNotNull(); - - DrlPackage readValue = mapper.readValue(yamlText, DrlPackage.class); - assertThat(readValue).as("Failed to parse YAML as model").isNotNull(); - - final String drlText = YAMLtoDrlDumper.dumpDRL(readValue); - LOG.debug(drlText); - assertThat(drlText).as("result of DRL dumper shall not be null or empty").isNotNull().isNotEmpty(); - - PackageDescr parseResult = drlParser.parse(new StringReader(drlText)); - assertThat(parseResult).as("The result of DRL dumper must be syntactically valid DRL").isNotNull(); - } catch (Exception e) { - Assertions.fail("Failed to generate a valid DRL while processing YAML", e); - } + @ParameterizedTest + @ValueSource(strings = {"/smoketests/yaml2.yml", + "/smoketests/yaml3.yml", + "/smoketests/yaml4.yml", + "/smoketests/yaml5.yml", + "/smoketests/yaml6.yml", + "/smoketests/yaml7.yml", + "/smoketests/yaml8.yml", + "/smoketests/yaml9.yml", + "/smoketests/yaml10.yml", + "/smoketests/yaml11.yml", + "/smoketests/ruleunit.yml"}) + public void smokeTestFromYAML2(String filename) throws Exception { + final String yamlText = Files.readString(Paths.get(YAMLtoDRLTest.class.getResource(filename).toURI())); + assertThat(yamlText).as("Failed to read test resource").isNotNull(); + + DrlPackage readValue = mapper.readValue(yamlText, DrlPackage.class); + assertThat(readValue).as("Failed to parse YAML as model").isNotNull(); + + final String drlText = YAMLtoDrlDumper.dumpDRL(readValue); + LOG.debug(drlText); + assertThat(drlText).as("result of DRL dumper shall not be null or empty").isNotNull().isNotEmpty(); + + PackageDescr parseResult = drlParser.parse(new StringReader(drlText)); + assertThat(parseResult).as("The result of DRL dumper must be syntactically valid DRL").isNotNull(); } - - @Test - public void smokeTestFromYAML2() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml2.yml"); - } - - @Test - public void smokeTestFromYAML3() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml3.yml"); - } - - @Test - public void smokeTestFromYAML4() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml4.yml"); - } - - @Test - public void smokeTestFromYAML5() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml5.yml"); - } - - @Test - public void smokeTestFromYAML6() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml6.yml"); - } - - @Test - public void smokeTestFromYAML7() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml7.yml"); - } - - @Test - public void smokeTestFromYAML8() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml8.yml"); - } - - @Test - public void smokeTestFromYAML9() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml9.yml"); - } - - @Test - public void smokeTestFromYAML10() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml10.yml"); - } - - @Test - public void smokeTestFromYAML11() { - assertDumpingYAMLtoDRLisValid("/smoketests/yaml11.yml"); - } - - @Test - public void smokeTestRuleUnit() { - assertDumpingYAMLtoDRLisValid("/smoketests/ruleunit.yml"); - } -} + } diff --git a/drools-drlonyaml-parent/pom.xml b/drools-drlonyaml-parent/pom.xml index dc5f742ac8e..9976e1ecbfe 100644 --- a/drools-drlonyaml-parent/pom.xml +++ b/drools-drlonyaml-parent/pom.xml @@ -30,12 +30,40 @@ drools-drlonyaml-parent Drools :: DRL on YAML pom - - drools-drlonyaml-schemagen - drools-drlonyaml-model - drools-drlonyaml-todrl - drools-drlonyaml-cli - drools-drlonyaml-cli-tests - drools-drlonyaml-integration-tests - + + + + allSubmodules + + + !only.reproducible + + + + drools-drlonyaml-schemagen + drools-drlonyaml-model + drools-drlonyaml-todrl + drools-drlonyaml-cli + drools-drlonyaml-cli-tests + drools-drlonyaml-integration-tests + + + + + onlyReproducible + + + only.reproducible + + + + drools-drlonyaml-schemagen + drools-drlonyaml-model + drools-drlonyaml-todrl + drools-drlonyaml-cli + drools-drlonyaml-cli-tests + + + + diff --git a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-common/pom.xml b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-common/pom.xml index 96f0e980d9c..1a94b1a4a38 100644 --- a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-common/pom.xml +++ b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-common/pom.xml @@ -48,11 +48,6 @@ slf4j-api - - junit - junit - test - diff --git a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-graphviz/pom.xml b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-graphviz/pom.xml index a9ef1f3f238..7d4e7e1aa6a 100644 --- a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-graphviz/pom.xml +++ b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-graphviz/pom.xml @@ -52,8 +52,8 @@ - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-graphviz/src/test/java/org/drools/impact/analysis/graph/graphviz/GraphvizOutputTest.java b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-graphviz/src/test/java/org/drools/impact/analysis/graph/graphviz/GraphvizOutputTest.java index 3400719c433..3430d1b0ce8 100644 --- a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-graphviz/src/test/java/org/drools/impact/analysis/graph/graphviz/GraphvizOutputTest.java +++ b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-graphviz/src/test/java/org/drools/impact/analysis/graph/graphviz/GraphvizOutputTest.java @@ -28,8 +28,8 @@ import org.drools.impact.analysis.graph.Node; import org.drools.impact.analysis.graph.ReactivityType; import org.drools.impact.analysis.model.Rule; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.linesOf; @@ -43,7 +43,7 @@ */ public class GraphvizOutputTest { - @After + @AfterEach public void tearDown() { Graphviz.releaseEngine(); } diff --git a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-json/pom.xml b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-json/pom.xml index 32de869fa02..45e84f50b9c 100644 --- a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-json/pom.xml +++ b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-json/pom.xml @@ -52,8 +52,8 @@ - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-json/src/test/java/org/drools/impact/analysis/graph/json/JsonOutputTest.java b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-json/src/test/java/org/drools/impact/analysis/graph/json/JsonOutputTest.java index 3a226e1c477..c2d3e671b3d 100644 --- a/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-json/src/test/java/org/drools/impact/analysis/graph/json/JsonOutputTest.java +++ b/drools-impact-analysis/drools-impact-analysis-graph/drools-impact-analysis-graph-json/src/test/java/org/drools/impact/analysis/graph/json/JsonOutputTest.java @@ -28,7 +28,7 @@ import org.drools.impact.analysis.graph.Node; import org.drools.impact.analysis.graph.ReactivityType; import org.drools.impact.analysis.model.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/drools-impact-analysis/drools-impact-analysis-itests/pom.xml b/drools-impact-analysis/drools-impact-analysis-itests/pom.xml index d9e9e08faa5..d92a6ec7365 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/pom.xml +++ b/drools-impact-analysis/drools-impact-analysis-itests/pom.xml @@ -67,13 +67,13 @@ test - org.assertj - assertj-core + org.junit.jupiter + junit-jupiter test - junit - junit + org.assertj + assertj-core test diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/example/ExampleUsageTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/example/ExampleUsageTest.java index fe6ff62228e..00092fb27b1 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/example/ExampleUsageTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/example/ExampleUsageTest.java @@ -34,7 +34,7 @@ import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.internal.ImpactAnalysisKieModule; import org.drools.impact.analysis.parser.internal.ImpactAnalysisProject; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/AbstractGraphTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/AbstractGraphTest.java index 8cddb8a7f9b..9a22cf5b085 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/AbstractGraphTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/AbstractGraphTest.java @@ -30,8 +30,7 @@ import org.drools.impact.analysis.graph.Node; import org.drools.impact.analysis.graph.ReactivityType; import org.drools.impact.analysis.graph.graphviz.GraphImageGenerator; -import org.junit.Rule; -import org.junit.rules.TestName; +import org.junit.jupiter.api.TestInfo; import org.kie.api.KieServices; import org.kie.api.builder.KieFileSystem; import org.kie.api.builder.ReleaseId; @@ -48,32 +47,26 @@ public class AbstractGraphTest { private static final Logger logger = LoggerFactory.getLogger(AbstractGraphTest.class); - @Rule - public TestName testName = new TestName(); - - protected String getTestMethodName() { - return testName.getMethodName(); - } // Keep this method for test convenience - protected void generatePng(Graph graph) { - generatePng(graph, ""); + protected void generatePng(TestInfo testInfo, Graph graph) { + generatePng(testInfo, graph, ""); } // Keep this method for test convenience - protected void generateSvg(Graph graph) { - generateSvg(graph, ""); + protected void generateSvg(TestInfo testInfo, Graph graph) { + generateSvg(testInfo, graph, ""); } // Keep this method for test convenience - protected void generatePng(Graph graph, String suffix) { - GraphImageGenerator generator = new GraphImageGenerator(getTestMethodName() + suffix); + protected void generatePng(TestInfo testInfo, Graph graph, String suffix) { + GraphImageGenerator generator = new GraphImageGenerator(testInfo.getDisplayName() + suffix); generator.generatePng(graph); } // Keep this method for test convenience - protected void generateSvg(Graph graph, String suffix) { - GraphImageGenerator generator = new GraphImageGenerator(getTestMethodName() + suffix); + protected void generateSvg(TestInfo testInfo, Graph graph, String suffix) { + GraphImageGenerator generator = new GraphImageGenerator(testInfo.getDisplayName() + suffix); generator.generateSvg(graph); } diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/BasicGraphTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/BasicGraphTest.java index 5ad4a7d68a0..76078d75f2a 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/BasicGraphTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/BasicGraphTest.java @@ -25,7 +25,9 @@ import org.drools.impact.analysis.integrationtests.domain.Person; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; + + public class BasicGraphTest extends AbstractGraphTest { diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/DeleteSpecificFactActionTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/DeleteSpecificFactActionTest.java index c87723be523..56025337e7e 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/DeleteSpecificFactActionTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/DeleteSpecificFactActionTest.java @@ -30,7 +30,7 @@ import org.drools.impact.analysis.model.right.DeleteSpecificFactAction; import org.drools.impact.analysis.model.right.SpecificProperty; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * This test is to verify that DeleteSpecificFactAction can be handled correctly. diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/DrlSyntaxTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/DrlSyntaxTest.java index bc7909ff720..8f7e15bd177 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/DrlSyntaxTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/DrlSyntaxTest.java @@ -28,7 +28,7 @@ import org.drools.impact.analysis.integrationtests.domain.Person; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/GraphCollapsionTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/GraphCollapsionTest.java index fb2d95d3212..1dc087ce247 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/GraphCollapsionTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/GraphCollapsionTest.java @@ -32,7 +32,7 @@ import org.drools.impact.analysis.parser.ModelBuilder; import org.drools.impact.analysis.parser.internal.ImpactAnalysisKieModule; import org.drools.impact.analysis.parser.internal.ImpactAnalysisProject; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/ImpactAnalysisTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/ImpactAnalysisTest.java index 261621473c3..5abbb975c99 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/ImpactAnalysisTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/ImpactAnalysisTest.java @@ -29,7 +29,7 @@ import org.drools.impact.analysis.integrationtests.domain.Order; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.drools.impact.analysis.graph.TextReporter.INDENT; diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/LinkFilterTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/LinkFilterTest.java index 7f8d1e51e58..a1cf2f3bf7b 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/LinkFilterTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/LinkFilterTest.java @@ -28,7 +28,7 @@ import org.drools.impact.analysis.integrationtests.domain.Person; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/PropertyTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/PropertyTest.java index 19fa869b432..e47b62f9990 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/PropertyTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/PropertyTest.java @@ -24,7 +24,7 @@ import org.drools.impact.analysis.integrationtests.domain.Person; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/RhsTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/RhsTest.java index c1c626bad73..00395a92f28 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/RhsTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/RhsTest.java @@ -27,7 +27,7 @@ import org.drools.impact.analysis.integrationtests.domain.Person; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/SpecialUsageTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/SpecialUsageTest.java index 9177ca88fbc..6e27334a11d 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/SpecialUsageTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/SpecialUsageTest.java @@ -28,7 +28,7 @@ import org.drools.impact.analysis.integrationtests.domain.ProductItem; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/TypeTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/TypeTest.java index b88407b7e39..c90063b7ee7 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/TypeTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/TypeTest.java @@ -22,13 +22,13 @@ import java.math.BigInteger; import org.drools.util.StringUtils; +import org.junit.jupiter.api.Test; import org.drools.impact.analysis.graph.Graph; import org.drools.impact.analysis.graph.ModelToGraphConverter; import org.drools.impact.analysis.graph.ReactivityType; import org.drools.impact.analysis.integrationtests.domain.PropHolder; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; public class TypeTest extends AbstractGraphTest { diff --git a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/kogito/KogitoDrlSyntaxTest.java b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/kogito/KogitoDrlSyntaxTest.java index 1a5285da180..f189bf64246 100644 --- a/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/kogito/KogitoDrlSyntaxTest.java +++ b/drools-impact-analysis/drools-impact-analysis-itests/src/test/java/org/drools/impact/analysis/integrationtests/kogito/KogitoDrlSyntaxTest.java @@ -25,7 +25,7 @@ import org.drools.impact.analysis.integrationtests.kogito.domain.LoanApplication; import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.ModelBuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * diff --git a/drools-impact-analysis/drools-impact-analysis-parser/pom.xml b/drools-impact-analysis/drools-impact-analysis-parser/pom.xml index ca8d52cecd4..10741f33879 100644 --- a/drools-impact-analysis/drools-impact-analysis-parser/pom.xml +++ b/drools-impact-analysis/drools-impact-analysis-parser/pom.xml @@ -48,8 +48,8 @@ - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/drools-impact-analysis/drools-impact-analysis-parser/src/test/java/org/drools/impact/analysis/parser/ParserTest.java b/drools-impact-analysis/drools-impact-analysis-parser/src/test/java/org/drools/impact/analysis/parser/ParserTest.java index b78559ce267..d507763ed1c 100644 --- a/drools-impact-analysis/drools-impact-analysis-parser/src/test/java/org/drools/impact/analysis/parser/ParserTest.java +++ b/drools-impact-analysis/drools-impact-analysis-parser/src/test/java/org/drools/impact/analysis/parser/ParserTest.java @@ -20,7 +20,7 @@ import org.drools.impact.analysis.model.AnalysisModel; import org.drools.impact.analysis.parser.domain.Person; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class ParserTest { diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/ConstraintOperator.java b/drools-model/drools-canonical-model/src/main/java/org/drools/model/ConstraintOperator.java index 6f216edd448..dd96c929fa7 100644 --- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/ConstraintOperator.java +++ b/drools-model/drools-canonical-model/src/main/java/org/drools/model/ConstraintOperator.java @@ -22,4 +22,12 @@ public interface ConstraintOperator { BiPredicate asPredicate(); + + default boolean hasIndex() { + return false; + } + + default Index.ConstraintType getIndexType() { + throw new UnsupportedOperationException(); + } } diff --git a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/DroolsModelBuildContext.java b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/DroolsModelBuildContext.java index f7537ca464a..34ebf684070 100644 --- a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/DroolsModelBuildContext.java +++ b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/DroolsModelBuildContext.java @@ -31,7 +31,16 @@ public interface DroolsModelBuildContext { String APPLICATION_PROPERTIES_FILE_NAME = "application.properties"; String DEFAULT_PACKAGE_NAME = "org.kie.kogito.app"; + /** + * (boolean) enable/disable global rest endpoint generation (default true) + * + * kogito.generate.rest.(engine_name) -> (boolean) enable/disable engine rest endpoint generation (default true) + * + */ String KOGITO_GENERATE_REST = "kogito.generate.rest"; + /** + * (boolean) dependency injection is available and enabled (default true) + */ String KOGITO_GENERATE_DI = "kogito.generate.di"; Optional getApplicationProperty(String property); diff --git a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/DependencyInjectionAnnotator.java b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/DependencyInjectionAnnotator.java index 133e55e4334..1446895fe55 100644 --- a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/DependencyInjectionAnnotator.java +++ b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/DependencyInjectionAnnotator.java @@ -160,6 +160,18 @@ default > T withInjection(T node) { */ > T withConfigInjection(T node, String configKey, String defaultValue); + /** + * Annotates given node with Transactional annotation + * + * @param node node to be annotated + */ + default > T withTransactional(T node) { + node.addAnnotation(getTransactionalAnnotation()); + return node; + } + + String getTransactionalAnnotation(); + /** * Annotates and enhances method used to produce messages * diff --git a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/impl/CDIDependencyInjectionAnnotator.java b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/impl/CDIDependencyInjectionAnnotator.java index 0631364e819..b4398bfbd7a 100644 --- a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/impl/CDIDependencyInjectionAnnotator.java +++ b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/impl/CDIDependencyInjectionAnnotator.java @@ -178,6 +178,11 @@ public > T withFactoryMethod(T node) { return node; } + @Override + public String getTransactionalAnnotation() { + return "jakarta.transaction.Transactional"; + } + @Override public > T withTagAnnotation(T node, NodeList attributes) { node.addAnnotation(new NormalAnnotationExpr(new Name("org.eclipse.microprofile.openapi.annotations.tags.Tag"), attributes)); diff --git a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/impl/SpringDependencyInjectionAnnotator.java b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/impl/SpringDependencyInjectionAnnotator.java index d9a5edf7f52..b54a1b517dc 100644 --- a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/impl/SpringDependencyInjectionAnnotator.java +++ b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/di/impl/SpringDependencyInjectionAnnotator.java @@ -18,6 +18,10 @@ */ package org.drools.codegen.common.di.impl; +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; + import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.expr.BinaryExpr; import com.github.javaparser.ast.expr.BooleanLiteralExpr; @@ -36,10 +40,6 @@ import com.github.javaparser.ast.type.ClassOrInterfaceType; import org.drools.codegen.common.di.DependencyInjectionAnnotator; -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; - public class SpringDependencyInjectionAnnotator implements DependencyInjectionAnnotator { @Override @@ -181,6 +181,11 @@ public > T withFactoryClass(T node) { return node; } + @Override + public String getTransactionalAnnotation() { + return "org.springframework.transaction.annotation.Transactional"; + } + @Override public > T withFactoryMethod(T node) { node.addAnnotation("org.springframework.context.annotation.Bean"); diff --git a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/rest/impl/CDIRestAnnotator.java b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/rest/impl/CDIRestAnnotator.java index 600eff5f833..7ce162e5854 100644 --- a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/rest/impl/CDIRestAnnotator.java +++ b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/rest/impl/CDIRestAnnotator.java @@ -29,7 +29,7 @@ public class CDIRestAnnotator implements RestAnnotator { @Override public > boolean isRestAnnotated(T node) { - return Stream.of("POST", "GET", "PUT", "DELETE") + return Stream.of("POST", "GET", "PUT", "DELETE", "PATCH") .map(node::getAnnotationByName) .anyMatch(Optional::isPresent); } diff --git a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/rest/impl/SpringRestAnnotator.java b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/rest/impl/SpringRestAnnotator.java index 1258b4d9d5c..7d480c5f321 100644 --- a/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/rest/impl/SpringRestAnnotator.java +++ b/drools-model/drools-codegen-common/src/main/java/org/drools/codegen/common/rest/impl/SpringRestAnnotator.java @@ -29,7 +29,7 @@ public class SpringRestAnnotator implements RestAnnotator { @Override public > boolean isRestAnnotated(T node) { - return Stream.of("PostMapping", "GetMapping", "PutMapping", "DeleteMapping") + return Stream.of("PostMapping", "GetMapping", "PutMapping", "DeleteMapping", "PatchMapping") .map(node::getAnnotationByName) .anyMatch(Optional::isPresent); } diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/ModelSourceClass.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/ModelSourceClass.java index 164eb57f9e7..d5fd40b2e35 100644 --- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/ModelSourceClass.java +++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/ModelSourceClass.java @@ -211,6 +211,10 @@ public String getDefaultKieSessionName() { return defaultKieSessionName; } + public String getDefaultKieStatelessSessionName() { + return defaultKieStatelessSessionName; + } + public Map getkSessionConfs() { return kSessionConfs; } diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpression.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpression.java index 4bbd12d9630..e26c1332734 100644 --- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpression.java +++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpression.java @@ -52,6 +52,8 @@ import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.toJavaParserType; import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.toStringLiteral; import static org.drools.util.ClassUtils.toNonPrimitiveType; +import static org.drools.util.CoercionUtil.areComparisonCompatible; +import static org.drools.util.CoercionUtil.areEqualityCompatible; public class CoercedExpression { @@ -151,9 +153,22 @@ public CoercedExpressionResult coerce() { coercedLeft = left; } + checkCoercion(coercedLeft, coercedRight, leftClass, rightClass); return new CoercedExpressionResult(coercedLeft, coercedRight, rightAsStaticField); } + private void checkCoercion(TypedExpression coercedLeft, TypedExpression coercedRight, Class leftClass, Class rightClass) { + if (equalityExpr) { + if (!areEqualityCompatible(coercedLeft.getRawClass(), coercedRight.getRawClass())) { + throw new CoercedExpressionException(new InvalidExpressionErrorResult("Equality operation requires compatible types. Found " + leftClass + " and " + rightClass)); + } + } else { + if (!areComparisonCompatible(coercedLeft.getRawClass(), coercedRight.getRawClass())) { + throw new CoercedExpressionException(new InvalidExpressionErrorResult("Comparison operation requires compatible types. Found " + leftClass + " and " + rightClass)); + } + } + } + private boolean isBoolean(Class leftClass) { return Boolean.class.isAssignableFrom(leftClass) || boolean.class.isAssignableFrom(leftClass); } @@ -163,12 +178,14 @@ private boolean shouldCoerceBToMap() { } private boolean canCoerce() { - final Class leftClass = left.getRawClass(); + return canCoerce(left.getRawClass(), right.getRawClass()); + } + + private static boolean canCoerce(Class leftClass, Class rightClass) { if (!leftClass.isPrimitive() || !canCoerceLiteralNumberExpr(leftClass)) { return true; } - final Class rightClass = right.getRawClass(); return rightClass.isPrimitive() || Number.class.isAssignableFrom(rightClass) || Boolean.class == rightClass diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/project/ProjectRuntimeGenerator.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/project/ProjectRuntimeGenerator.java index 053a3161c39..5bb12d525e8 100644 --- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/project/ProjectRuntimeGenerator.java +++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/project/ProjectRuntimeGenerator.java @@ -90,31 +90,33 @@ private void writeInitKieBasesMethod(ClassOrInterfaceDeclaration clazz) { } private void writeGetDefaultKieBaseMethod(ClassOrInterfaceDeclaration clazz) { - MethodDeclaration getDefaultKieBaseMethod = clazz.findAll(MethodDeclaration.class).stream() - .filter(m -> m.getNameAsString().equals("getKieBase")) - .filter(m -> m.getParameters().isEmpty()) - .findFirst() - .orElseThrow(() -> new InvalidTemplateException(generator, "Cannot find getKieBase method")); - if (modelMethod.getDefaultKieBaseName() != null) { - getDefaultKieBaseMethod.findFirst(StringLiteralExpr.class) + findDefaultKieMethod(clazz, "getKieBase").findFirst(StringLiteralExpr.class) .orElseThrow(() -> new InvalidTemplateException(generator, "Cannot find string inside getKieBase method")) .setString(modelMethod.getDefaultKieBaseName()); } } private void writeNewDefaultKieSessionMethod(ClassOrInterfaceDeclaration clazz) { - MethodDeclaration newDefaultKieSessionMethod = clazz.findAll(MethodDeclaration.class).stream() - .filter(m -> m.getNameAsString().equals("newKieSession")) - .filter(m -> m.getParameters().isEmpty()) - .findFirst() - .orElseThrow(() -> new InvalidTemplateException(generator, "Cannot find newKieSession method")); - if (modelMethod.getDefaultKieSessionName() != null) { - newDefaultKieSessionMethod.findFirst(StringLiteralExpr.class) + findDefaultKieMethod(clazz, "newKieSession").findFirst(StringLiteralExpr.class) .orElseThrow(() -> new InvalidTemplateException(generator, "Cannot find string inside newKieSession method")) .setString(modelMethod.getDefaultKieSessionName()); } + + if (modelMethod.getDefaultKieStatelessSessionName() != null) { + findDefaultKieMethod(clazz, "newStatelessKieSession").findFirst(StringLiteralExpr.class) + .orElseThrow(() -> new InvalidTemplateException(generator, "Cannot find string inside newStatelessKieSession method")) + .setString(modelMethod.getDefaultKieStatelessSessionName()); + } + } + + private MethodDeclaration findDefaultKieMethod(ClassOrInterfaceDeclaration clazz, String methodName) { + return clazz.findAll(MethodDeclaration.class).stream() + .filter(m -> m.getNameAsString().equals(methodName)) + .filter(m -> m.getParameters().isEmpty()) + .findFirst() + .orElseThrow(() -> new InvalidTemplateException(generator, "Cannot find " + methodName + " method")); } private void writeGetKieBaseForSessionMethod(ClassOrInterfaceDeclaration clazz) { diff --git a/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeJavaTemplate.java b/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeJavaTemplate.java index 90edc28323a..f6363b63c40 100644 --- a/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeJavaTemplate.java +++ b/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeJavaTemplate.java @@ -25,6 +25,7 @@ import org.kie.api.KieBase; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.KieRuntimeBuilder; +import org.kie.api.runtime.StatelessKieSession; import org.drools.modelcompiler.KieBaseBuilder; public class ProjectRuntime implements KieRuntimeBuilder { @@ -62,8 +63,21 @@ public KieSession newKieSession(String sessionName) { if (kbase == null) { throw new RuntimeException("Unknown KieSession with name '" + sessionName + "'"); } - KieSession ksession = kbase.newKieSession(getConfForSession(sessionName), null); - return ksession; + return kbase.newKieSession(getConfForSession(sessionName), null); + } + + @Override + public StatelessKieSession newStatelessKieSession() { + return newStatelessKieSession("$defaultStatelessKieSession$"); + } + + @Override + public StatelessKieSession newStatelessKieSession(String sessionName) { + KieBase kbase = getKieBaseForSession(sessionName); + if (kbase == null) { + throw new RuntimeException("Unknown StatelessKieSession with name '" + sessionName + "'"); + } + return kbase.newStatelessKieSession(getConfForSession(sessionName)); } private KieBase getKieBaseForSession(String sessionName) { diff --git a/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeQuarkusTemplate.java b/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeQuarkusTemplate.java index ee69deb295e..5f4da3847b9 100644 --- a/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeQuarkusTemplate.java +++ b/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeQuarkusTemplate.java @@ -25,6 +25,7 @@ import org.kie.api.KieBase; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.KieRuntimeBuilder; +import org.kie.api.runtime.StatelessKieSession; import org.drools.modelcompiler.KieBaseBuilder; @jakarta.enterprise.context.ApplicationScoped @@ -63,8 +64,21 @@ public KieSession newKieSession(String sessionName) { if (kbase == null) { throw new RuntimeException("Unknown KieSession with name '" + sessionName + "'"); } - KieSession ksession = kbase.newKieSession(getConfForSession(sessionName), null); - return ksession; + return kbase.newKieSession(getConfForSession(sessionName), null); + } + + @Override + public StatelessKieSession newStatelessKieSession() { + return newStatelessKieSession("$defaultStatelessKieSession$"); + } + + @Override + public StatelessKieSession newStatelessKieSession(String sessionName) { + KieBase kbase = getKieBaseForSession(sessionName); + if (kbase == null) { + throw new RuntimeException("Unknown StatelessKieSession with name '" + sessionName + "'"); + } + return kbase.newStatelessKieSession(getConfForSession(sessionName)); } private KieBase getKieBaseForSession(String sessionName) { diff --git a/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeSpringTemplate.java b/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeSpringTemplate.java index 3bb8b500842..13ac7e0e26e 100644 --- a/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeSpringTemplate.java +++ b/drools-model/drools-model-codegen/src/main/resources/class-templates/rules/ProjectRuntimeSpringTemplate.java @@ -25,6 +25,7 @@ import org.kie.api.KieBase; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.KieRuntimeBuilder; +import org.kie.api.runtime.StatelessKieSession; import org.drools.modelcompiler.KieBaseBuilder; @org.springframework.stereotype.Component @@ -63,8 +64,21 @@ public KieSession newKieSession(String sessionName) { if (kbase == null) { throw new RuntimeException("Unknown KieSession with name '" + sessionName + "'"); } - KieSession ksession = kbase.newKieSession(getConfForSession(sessionName), null); - return ksession; + return kbase.newKieSession(getConfForSession(sessionName), null); + } + + @Override + public StatelessKieSession newStatelessKieSession() { + return newStatelessKieSession("$defaultStatelessKieSession$"); + } + + @Override + public StatelessKieSession newStatelessKieSession(String sessionName) { + KieBase kbase = getKieBaseForSession(sessionName); + if (kbase == null) { + throw new RuntimeException("Unknown StatelessKieSession with name '" + sessionName + "'"); + } + return kbase.newStatelessKieSession(getConfForSession(sessionName)); } private KieBase getKieBaseForSession(String sessionName) { diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/CustomConstraintOperatorTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/CustomConstraintOperatorTest.java new file mode 100644 index 00000000000..d1b5c6f7768 --- /dev/null +++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/CustomConstraintOperatorTest.java @@ -0,0 +1,254 @@ +/** + * 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 + *

+ * 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.model.codegen.execmodel; + +import java.util.function.BiPredicate; + +import org.drools.base.common.NetworkNode; +import org.drools.base.prototype.PrototypeObjectType; +import org.drools.base.rule.IndexableConstraint; +import org.drools.core.reteoo.AlphaNode; +import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.EntryPointNode; +import org.drools.core.reteoo.ObjectTypeNode; +import org.drools.kiesession.rulebase.InternalKnowledgeBase; +import org.drools.model.ConstraintOperator; +import org.drools.model.Index; +import org.drools.model.Model; +import org.drools.model.Rule; +import org.drools.model.codegen.execmodel.domain.Result; +import org.drools.model.impl.ModelImpl; +import org.drools.model.prototype.PrototypeVariable; +import org.drools.modelcompiler.KieBaseBuilder; +import org.drools.modelcompiler.constraints.LambdaConstraint; +import org.junit.Test; +import org.kie.api.KieBase; +import org.kie.api.prototype.PrototypeFact; +import org.kie.api.prototype.PrototypeFactInstance; +import org.kie.api.runtime.KieSession; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.drools.model.DSL.on; +import static org.drools.model.PatternDSL.rule; +import static org.drools.model.prototype.PrototypeDSL.protoPattern; +import static org.drools.model.prototype.PrototypeDSL.variable; +import static org.drools.model.prototype.PrototypeExpression.fixedValue; +import static org.drools.model.prototype.PrototypeExpression.prototypeField; +import static org.kie.api.prototype.PrototypeBuilder.prototype; + +public class CustomConstraintOperatorTest { + + static class CustomConstraintOperator implements ConstraintOperator { + + public int counter = 0; + + @Override + public BiPredicate asPredicate() { + return (t, v) -> { + counter++; + return t.equals(v); + }; + } + + @Override + public boolean hasIndex() { + return true; + } + + @Override + public Index.ConstraintType getIndexType() { + return Index.ConstraintType.EQUAL; + } + + @Override + public String toString() { + return Index.ConstraintType.EQUAL.toString(); + } + } + + @Test + public void alphaIndexIneffective() { + CustomConstraintOperator customConstraintOperator = new CustomConstraintOperator(); + + PrototypeFact testPrototype = prototype("test").asFact(); + PrototypeVariable testV = variable(testPrototype); + + Rule rule1 = rule("alpha1") + .build( + protoPattern(testV) + .expr(prototypeField("fieldA"), customConstraintOperator, fixedValue(1)), + on(testV).execute((drools, x) -> + drools.insert(new Result("Found")) + ) + ); + + Model model = new ModelImpl().addRule(rule1); + KieBase kieBase = KieBaseBuilder.createKieBaseFromModel(model); + KieSession ksession = kieBase.newKieSession(); + + PrototypeFactInstance testFact = testPrototype.newInstance(); + testFact.put("fieldA", 1); + + ksession.insert(testFact); + assertThat(ksession.fireAllRules()).isEqualTo(1); + + // Index is created, but actual alpha index hashing works only with more than 3 nodes + Index index = getFirstAlphaNodeIndex((InternalKnowledgeBase) kieBase, testPrototype); + assertThat(index.getIndexType()).isEqualTo(Index.IndexType.ALPHA); + assertThat(index.getConstraintType()).isEqualTo(Index.ConstraintType.EQUAL); + + // alpha index hashing is not effective, so the predicated is called + assertThat(customConstraintOperator.counter).isEqualTo(1); + } + + @Test + public void alphaIndexEffective() { + CustomConstraintOperator customConstraintOperator = new CustomConstraintOperator(); + + PrototypeFact testPrototype = prototype("test").asFact(); + PrototypeVariable testV = variable(testPrototype); + + Rule rule1 = rule("alpha1") + .build( + protoPattern(testV) + .expr(prototypeField("fieldA"), customConstraintOperator, fixedValue(1)), + on(testV).execute((drools, x) -> + drools.insert(new Result("Found")) + ) + ); + Rule rule2 = rule("alpha2") + .build( + protoPattern(testV) + .expr(prototypeField("fieldA"), customConstraintOperator, fixedValue(2)), + on(testV).execute((drools, x) -> + drools.insert(new Result("Found")) + ) + ); + Rule rule3 = rule("alpha3") + .build( + protoPattern(testV) + .expr(prototypeField("fieldA"), customConstraintOperator, fixedValue(3)), + on(testV).execute((drools, x) -> + drools.insert(new Result("Found")) + ) + ); + + Model model = new ModelImpl().addRule(rule1).addRule(rule2).addRule(rule3); + KieBase kieBase = KieBaseBuilder.createKieBaseFromModel(model); + KieSession ksession = kieBase.newKieSession(); + + PrototypeFactInstance testFact = testPrototype.newInstance(); + testFact.put("fieldA", 1); + + ksession.insert(testFact); + assertThat(ksession.fireAllRules()).isEqualTo(1); + + Index index = getFirstAlphaNodeIndex((InternalKnowledgeBase) kieBase, testPrototype); + assertThat(index.getIndexType()).isEqualTo(Index.IndexType.ALPHA); + assertThat(index.getConstraintType()).isEqualTo(Index.ConstraintType.EQUAL); + + // alpha index hashing is effective, so the predicated is not called + assertThat(customConstraintOperator.counter).isZero(); + } + + private static Index getFirstAlphaNodeIndex(InternalKnowledgeBase kieBase, PrototypeFact testPrototype) { + EntryPointNode epn = kieBase.getRete().getEntryPointNodes().values().iterator().next(); + ObjectTypeNode otn = epn.getObjectTypeNodes().get(new PrototypeObjectType(testPrototype)); + AlphaNode alphaNode = (AlphaNode) otn.getObjectSinkPropagator().getSinks()[0]; + IndexableConstraint constraint = (IndexableConstraint) alphaNode.getConstraint(); + return ((LambdaConstraint) constraint).getEvaluator().getIndex(); + } + + @Test + public void betaIndex() { + CustomConstraintOperator customConstraintOperator = new CustomConstraintOperator(); + + Result result = new Result(); + + PrototypeFact personFact = prototype("org.drools.Person").withField("name").withField("age").asFact(); + + PrototypeVariable markV = variable(personFact); + PrototypeVariable ageMateV = variable(personFact); + + Rule rule = rule("beta") + .build( + protoPattern(markV) + .expr("name", Index.ConstraintType.EQUAL, "Mark"), + protoPattern(ageMateV) + .expr("name", Index.ConstraintType.NOT_EQUAL, "Mark") + .expr("age", customConstraintOperator, markV, "age"), + on(ageMateV, markV).execute((p1, p2) -> result.setValue(p1.get("name") + " is the same age as " + p2.get("name"))) + ); + + Model model = new ModelImpl().addRule(rule); + KieBase kieBase = KieBaseBuilder.createKieBaseFromModel(model); + + KieSession ksession = kieBase.newKieSession(); + + PrototypeFactInstance mark = personFact.newInstance(); + mark.put("name", "Mark"); + mark.put("age", 37); + + PrototypeFactInstance john = personFact.newInstance(); + john.put("name", "John"); + john.put("age", 39); + + PrototypeFactInstance paul = personFact.newInstance(); + paul.put("name", "Paul"); + paul.put("age", 37); + + ksession.insert(mark); + ksession.insert(john); + ksession.insert(paul); + + ksession.fireAllRules(); + assertThat(result.getValue()).isEqualTo("Paul is the same age as Mark"); + + Index index = getFirstBetaNodeIndex((InternalKnowledgeBase) kieBase, personFact); + assertThat(index.getIndexType()).isEqualTo(Index.IndexType.BETA); + assertThat(index.getConstraintType()).isEqualTo(Index.ConstraintType.EQUAL); + + // When beta index is used, the predicate in the custom operator is not actually called + assertThat(customConstraintOperator.counter).isZero(); + } + + private static Index getFirstBetaNodeIndex(InternalKnowledgeBase kieBase, PrototypeFact testPrototype) { + EntryPointNode epn = kieBase.getRete().getEntryPointNodes().values().iterator().next(); + ObjectTypeNode otn = epn.getObjectTypeNodes().get(new PrototypeObjectType(testPrototype)); + NetworkNode[] sinks = otn.getObjectSinkPropagator().getSinks(); + BetaNode betaNode = findBetaNode(sinks); + + IndexableConstraint constraint = (IndexableConstraint) betaNode.getConstraints()[0]; + return ((LambdaConstraint) constraint).getEvaluator().getIndex(); + } + + private static BetaNode findBetaNode(NetworkNode[] sinks) { + for (NetworkNode sink : sinks) { + if (sink instanceof BetaNode) { + return (BetaNode) sink; + } else { + BetaNode betaNode = findBetaNode(sink.getSinks()); + if (betaNode != null) { + return betaNode; + } + } + } + return null; + } +} diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpressionTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpressionTest.java index 1264a096981..83e1a2c3a6d 100644 --- a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpressionTest.java +++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpressionTest.java @@ -127,9 +127,9 @@ public void castToShort() { @Test public void castMaps() { final TypedExpression left = expr(THIS_PLACEHOLDER + ".getAge()", Integer.class); - final TypedExpression right = expr("$m.get(\"age\")", java.util.Map.class); + final TypedExpression right = expr("$m.get(\"age\")", Object.class); final CoercedExpression.CoercedExpressionResult coerce = new CoercedExpression(left, right, false).coerce(); - assertThat(coerce.getCoercedRight()).isEqualTo(expr("(java.lang.Integer)$m.get(\"age\")", Map.class)); + assertThat(coerce.getCoercedRight()).isEqualTo(expr("$m.get(\"age\")", Object.class)); } @Test diff --git a/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeDSL.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeDSL.java index 1952375d118..265a4304297 100644 --- a/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeDSL.java +++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeDSL.java @@ -127,16 +127,22 @@ public PrototypePatternDef expr(PrototypeExpression left, ConstraintOperator ope reactOnFields.addAll(left.getImpactedFields()); reactOnFields.addAll(right.getImpactedFields()); + // If operator is not Index.ConstraintType, it may contain Index.ConstraintType internally for indexing purposes + ConstraintOperator operatorAsIndexType = operator; + if (operator.hasIndex()) { + operatorAsIndexType = operator.getIndexType(); + } + expr(createExprId(left, operator, right), asPredicate1(leftExtractor, operator, right.asFunction(prototype)), - createAlphaIndex(left, operator, right, prototype, leftExtractor), + createAlphaIndex(left, operatorAsIndexType, right, prototype, leftExtractor), reactOn( reactOnFields.toArray(new String[reactOnFields.size()])) ); return this; } - private static AlphaIndex createAlphaIndex(PrototypeExpression left, ConstraintOperator operator, PrototypeExpression right, Prototype prototype, Function1 leftExtractor) { - if (left.getIndexingKey().isPresent() && right instanceof PrototypeExpression.FixedValue && operator instanceof Index.ConstraintType constraintType) { + private static AlphaIndex createAlphaIndex(PrototypeExpression left, ConstraintOperator operatorAsIndexType, PrototypeExpression right, Prototype prototype, Function1 leftExtractor) { + if (left.getIndexingKey().isPresent() && right instanceof PrototypeExpression.FixedValue && operatorAsIndexType instanceof Index.ConstraintType constraintType) { String fieldName = left.getIndexingKey().get(); Prototype.Field field = prototype.getField(fieldName); Object value = ((PrototypeExpression.FixedValue) right).getValue(); @@ -167,9 +173,15 @@ public PrototypePatternDef expr(PrototypeExpression left, ConstraintOperator ope reactOnFields.addAll(left.getImpactedFields()); reactOnFields.addAll(right.getImpactedFields()); + // If operator is not Index.ConstraintType, it may contain Index.ConstraintType internally for indexing purposes + ConstraintOperator operatorAsIndexType = operator; + if (operator.hasIndex()) { + operatorAsIndexType = operator.getIndexType(); + } + expr(createExprId(left, operator, right), other, asPredicate2(left.asFunction(prototype), operator, right.asFunction(otherPrototype)), - createBetaIndex(left, operator, right, prototype, otherPrototype), + createBetaIndex(left, operatorAsIndexType, right, prototype, otherPrototype), reactOn( reactOnFields.toArray(new String[reactOnFields.size()])) ); return this; @@ -181,8 +193,8 @@ private static String createExprId(PrototypeExpression left, ConstraintOperator return "expr:" + leftId + ":" + operator + ":" + rightId; } - private BetaIndex createBetaIndex(PrototypeExpression left, ConstraintOperator operator, PrototypeExpression right, Prototype prototype, Prototype otherPrototype) { - if (left.getIndexingKey().isPresent() && operator instanceof Index.ConstraintType constraintType && right.getIndexingKey().isPresent()) { + private BetaIndex createBetaIndex(PrototypeExpression left, ConstraintOperator operatorAsIndexType, PrototypeExpression right, Prototype prototype, Prototype otherPrototype) { + if (left.getIndexingKey().isPresent() && operatorAsIndexType instanceof Index.ConstraintType constraintType && right.getIndexingKey().isPresent()) { String fieldName = left.getIndexingKey().get(); Prototype.Field field = prototype.getField(fieldName); Function1 extractor = left.asFunction(prototype); diff --git a/drools-mvel/src/main/java/org/drools/mvel/MVELConstraintBuilder.java b/drools-mvel/src/main/java/org/drools/mvel/MVELConstraintBuilder.java index 38809896b71..2b9fb57ed10 100644 --- a/drools-mvel/src/main/java/org/drools/mvel/MVELConstraintBuilder.java +++ b/drools-mvel/src/main/java/org/drools/mvel/MVELConstraintBuilder.java @@ -97,6 +97,8 @@ import org.drools.mvel.expr.MVELObjectExpression; import org.drools.mvel.expr.MvelEvaluator; import org.drools.mvel.java.JavaForMvelDialectConfiguration; +import org.drools.util.CoercionUtil; +import org.drools.util.MethodUtils; import org.kie.api.definition.rule.Rule; import org.mvel2.ConversionHandler; import org.mvel2.DataConversion; @@ -426,8 +428,6 @@ private MVELCompilationUnit buildCompilationUnit( final RuleBuildContext context } } - MVELDialect dialect = (MVELDialect) context.getDialect( "mvel" ); - MVELCompilationUnit unit = null; try { @@ -439,16 +439,8 @@ private MVELCompilationUnit buildCompilationUnit( final RuleBuildContext context ((ClassObjectType) p.getObjectType()).getClassType() ); } - unit = dialect.getMVELCompilationUnit( (String) predicateDescr.getContent(), - analysis, - previousDeclarations, - localDeclarations, - null, - context, - "drools", - KnowledgeHelper.class, - context.isInXpath(), - MVELCompilationUnit.Scope.CONSTRAINT ); + unit = MVELDialect.getMVELCompilationUnit( (String) predicateDescr.getContent(), analysis, previousDeclarations, localDeclarations, + null, context, "drools", KnowledgeHelper.class, context.isInXpath(), MVELCompilationUnit.Scope.CONSTRAINT ); } catch ( final Exception e ) { copyErrorLocation(e, predicateDescr); context.addError( new DescrBuildError( context.getParentDescr(), @@ -486,48 +478,14 @@ private StringCoercionCompatibilityEvaluator() { } @Override public boolean areEqualityCompatible(Class c1, Class c2) { - if (c1 == NullType.class || c2 == NullType.class) { - return true; - } - if (c1 == String.class || c2 == String.class) { - return true; - } - Class boxed1 = convertFromPrimitiveType(c1); - Class boxed2 = convertFromPrimitiveType(c2); - if (boxed1.isAssignableFrom(boxed2) || boxed2.isAssignableFrom(boxed1)) { - return true; - } - if (Number.class.isAssignableFrom(boxed1) && Number.class.isAssignableFrom(boxed2)) { - return true; - } - if (areEqualityCompatibleEnums(boxed1, boxed2)) { - return true; - } - return !Modifier.isFinal(c1.getModifiers()) && !Modifier.isFinal(c2.getModifiers()); - } - - protected boolean areEqualityCompatibleEnums(final Class boxed1, - final Class boxed2) { - return boxed1.isEnum() && boxed2.isEnum() && boxed1.getName().equals(boxed2.getName()) - && equalEnumConstants(boxed1.getEnumConstants(), boxed2.getEnumConstants()); - } - - private boolean equalEnumConstants(final Object[] aa, - final Object[] bb) { - if (aa.length != bb.length) { - return false; - } - for (int i = 0; i < aa.length; i++) { - if (!Objects.equals(aa[i].getClass().getName(), bb[i].getClass().getName())) { - return false; - } - } - return true; + return CoercionUtil.areEqualityCompatible(c1 == NullType.class ? MethodUtils.NullType.class : c1, + c2 == NullType.class ? MethodUtils.NullType.class : c2); } @Override public boolean areComparisonCompatible(Class c1, Class c2) { - return areEqualityCompatible(c1, c2); + return CoercionUtil.areComparisonCompatible(c1 == NullType.class ? MethodUtils.NullType.class : c1, + c2 == NullType.class ? MethodUtils.NullType.class : c2); } } @@ -558,16 +516,8 @@ public TimerExpression buildTimerExpression( String expression, RuleBuildContext } Arrays.sort(previousDeclarations, SortDeclarations.instance); - MVELCompilationUnit unit = dialect.getMVELCompilationUnit( expression, - analysis, - previousDeclarations, - null, - null, - context, - "drools", - KnowledgeHelper.class, - false, - MVELCompilationUnit.Scope.EXPRESSION ); + MVELCompilationUnit unit = MVELDialect.getMVELCompilationUnit( expression, analysis, previousDeclarations, null, null, + context, "drools", KnowledgeHelper.class, false, MVELCompilationUnit.Scope.EXPRESSION ); MVELObjectExpression expr = new MVELObjectExpression( unit, dialect.getId() ); @@ -578,9 +528,7 @@ public TimerExpression buildTimerExpression( String expression, RuleBuildContext return expr; } catch ( final Exception e ) { AsmUtil.copyErrorLocation(e, context.getRuleDescr()); - context.addError( new DescrBuildError( context.getParentDescr(), - context.getRuleDescr(), - null, + context.addError( new DescrBuildError( context.getParentDescr(), context.getRuleDescr(), null, "Unable to build expression : " + e.getMessage() + "'" + expression + "'" ) ); return null; } finally { @@ -595,10 +543,8 @@ public AnalysisResult analyzeExpression(Class thisClass, String expr) { return analyzeExpression( expr, conf, new BoundIdentifiers( thisClass ) ); } - private static MVELAnalysisResult analyzeExpression(String expr, - ParserConfiguration conf, - BoundIdentifiers availableIdentifiers) { - if (expr.trim().length() == 0) { + private static MVELAnalysisResult analyzeExpression(String expr, ParserConfiguration conf, BoundIdentifiers availableIdentifiers) { + if (expr.trim().isEmpty()) { MVELAnalysisResult result = analyze( (Set ) Collections.EMPTY_SET, availableIdentifiers ); result.setMvelVariables( new HashMap<>() ); result.setTypesafe( true ); diff --git a/drools-quarkus-extension/drools-quarkus-deployment/src/main/java/org/drools/quarkus/deployment/DroolsAssetsProcessor.java b/drools-quarkus-extension/drools-quarkus-deployment/src/main/java/org/drools/quarkus/deployment/DroolsAssetsProcessor.java index 08c68ad06de..32022f63891 100644 --- a/drools-quarkus-extension/drools-quarkus-deployment/src/main/java/org/drools/quarkus/deployment/DroolsAssetsProcessor.java +++ b/drools-quarkus-extension/drools-quarkus-deployment/src/main/java/org/drools/quarkus/deployment/DroolsAssetsProcessor.java @@ -205,6 +205,9 @@ private Map readKieBaseModels() { case "default": kieSessionModel.setDefault( config.getValue(propertyName, Boolean.class) ); break; + case "stateless": + kieSessionModel.setType( config.getValue(propertyName, Boolean.class) ? KieSessionModel.KieSessionType.STATELESS : KieSessionModel.KieSessionType.STATEFUL ); + break; case "clockType": kieSessionModel.setClockType( ClockTypeOption.get(config.getValue(propertyName, String.class) ) ); break; diff --git a/drools-quarkus-extension/drools-quarkus-examples/drools-quarkus-examples-multiunit/src/test/java/org/drools/quarkus/ruleunit/examples/multiunit/RuntimeTest.java b/drools-quarkus-extension/drools-quarkus-examples/drools-quarkus-examples-multiunit/src/test/java/org/drools/quarkus/ruleunit/examples/multiunit/RuntimeTest.java index 4122df9325f..322207cea27 100644 --- a/drools-quarkus-extension/drools-quarkus-examples/drools-quarkus-examples-multiunit/src/test/java/org/drools/quarkus/ruleunit/examples/multiunit/RuntimeTest.java +++ b/drools-quarkus-extension/drools-quarkus-examples/drools-quarkus-examples-multiunit/src/test/java/org/drools/quarkus/ruleunit/examples/multiunit/RuntimeTest.java @@ -29,7 +29,7 @@ import org.junit.jupiter.api.Test; import org.kie.api.runtime.rule.FactHandle; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; @QuarkusTest public class RuntimeTest { @@ -69,7 +69,7 @@ public void delete(DataHandle handle) { instance.fire(); - assertEquals("Hi 1", output.get().getText()); + assertThat(output.get().getText()).isEqualTo("Hi 1"); } @Test @@ -101,6 +101,6 @@ public void delete(DataHandle handle) { instance.fire(); - assertEquals("Hi 2", output.get().getText()); + assertThat(output.get().getText()).isEqualTo("Hi 2"); } } diff --git a/drools-quarkus-extension/drools-quarkus-integration-test-hotreload/pom.xml b/drools-quarkus-extension/drools-quarkus-integration-test-hotreload/pom.xml index e06d5791feb..7b406c931dc 100644 --- a/drools-quarkus-extension/drools-quarkus-integration-test-hotreload/pom.xml +++ b/drools-quarkus-extension/drools-quarkus-integration-test-hotreload/pom.xml @@ -54,6 +54,10 @@ io.quarkus quarkus-resteasy-jackson + + org.assertj + assertj-core + io.quarkus diff --git a/drools-quarkus-extension/drools-quarkus-integration-test-hotreload/src/test/java/org/drools/quarkus/test/hotreload/HotReloadIT.java b/drools-quarkus-extension/drools-quarkus-integration-test-hotreload/src/test/java/org/drools/quarkus/test/hotreload/HotReloadIT.java index 5e5de51d846..1d5bb063a0a 100644 --- a/drools-quarkus-extension/drools-quarkus-integration-test-hotreload/src/test/java/org/drools/quarkus/test/hotreload/HotReloadIT.java +++ b/drools-quarkus-extension/drools-quarkus-integration-test-hotreload/src/test/java/org/drools/quarkus/test/hotreload/HotReloadIT.java @@ -28,8 +28,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import static io.restassured.RestAssured.given; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; public class HotReloadIT { @@ -50,7 +49,7 @@ public class HotReloadIT { public void testServletChange() throws InterruptedException { String personsPayload = "[{\"name\":\"Mario\",\"age\":45,\"adult\":false},{\"name\":\"Sofia\",\"age\":17,\"adult\":false}]"; - List names = given() + List names = given() .baseUri("http://localhost:" + HTTP_TEST_PORT) .contentType(ContentType.JSON) .accept(ContentType.JSON) @@ -60,10 +59,9 @@ public void testServletChange() throws InterruptedException { .then() .statusCode(200) .extract() - .as(List.class); + .>as(List.class); - assertEquals(1, names.size()); - assertEquals("Mario", names.get(0)); + assertThat(names).hasSize(1).containsExactly("Mario"); test.modifyResourceFile(RESOURCE_FILE, s -> s.replaceAll("18", "16")); @@ -75,10 +73,8 @@ public void testServletChange() throws InterruptedException { .post("/find-adult") .then() .statusCode(200) - .extract().as(List.class); + .extract().>as(List.class); - assertEquals(2, names.size()); - assertTrue(names.contains("Mario")); - assertTrue(names.contains("Sofia")); + assertThat(names).hasSize(2).containsExactlyInAnyOrder("Mario", "Sofia"); } } diff --git a/drools-quarkus-extension/drools-quarkus-integration-test/pom.xml b/drools-quarkus-extension/drools-quarkus-integration-test/pom.xml index 77e1fb06d06..1a4e3e16452 100644 --- a/drools-quarkus-extension/drools-quarkus-integration-test/pom.xml +++ b/drools-quarkus-extension/drools-quarkus-integration-test/pom.xml @@ -41,6 +41,10 @@ org.drools drools-quarkus + + org.drools + drools-commands + org.drools drools-decisiontables diff --git a/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/application.properties b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/application.properties index b26fc31a187..e7193773be4 100644 --- a/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/application.properties +++ b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/application.properties @@ -21,12 +21,16 @@ drools.prototypes=allowed drools.kbase.canDrinkKB.packages=org.drools.drl drools.kbase.canDrinkKB.ksession.canDrinkKS.default=true +drools.kbase.canDrinkKB.ksession.statelessCanDrinkKS.stateless=true +drools.kbase.canDrinkKB.ksession.statelessCanDrinkKS.default=true drools.kbase.canDrinkKBDTable.packages=org.drools.dtable -drools.kbase.canDrinkKBDTable.ksession=canDrinkKSDTable +drools.kbase.canDrinkKBDTable.ksession.canDrinkKSDTable.stateless=false +drools.kbase.canDrinkKBDTable.ksession.statelessCanDrinkKSDTable.stateless=true drools.kbase.canDrinkKBYaml.packages=org.drools.yaml drools.kbase.canDrinkKBYaml.ksession=canDrinkKSYaml +drools.kbase.canDrinkKBYaml.ksession.statelessCanDrinkKSYaml.stateless=true drools.kbase.canDrinkKBPrototype.packages=org.drools.prototype drools.kbase.canDrinkKBPrototype.prototypes=allowed diff --git a/drools-quarkus-extension/drools-quarkus-integration-test/src/test/java/org/drools/quarkus/test/RuntimeTest.java b/drools-quarkus-extension/drools-quarkus-integration-test/src/test/java/org/drools/quarkus/test/RuntimeTest.java index 96c380dd554..1ac971dafd9 100644 --- a/drools-quarkus-extension/drools-quarkus-integration-test/src/test/java/org/drools/quarkus/test/RuntimeTest.java +++ b/drools-quarkus-extension/drools-quarkus-integration-test/src/test/java/org/drools/quarkus/test/RuntimeTest.java @@ -24,14 +24,18 @@ import io.quarkus.test.junit.QuarkusTest; import jakarta.inject.Inject; import org.junit.jupiter.api.Test; +import org.kie.api.KieServices; +import org.kie.api.command.KieCommands; import org.kie.api.definition.KiePackage; +import org.kie.api.internal.utils.KieService; import org.kie.api.prototype.PrototypeFact; import org.kie.api.prototype.PrototypeFactInstance; import org.kie.api.runtime.KieRuntimeBuilder; import org.kie.api.runtime.KieSession; +import org.kie.api.runtime.RuntimeSession; +import org.kie.api.runtime.StatelessKieSession; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.kie.api.prototype.PrototypeBuilder.prototype; @QuarkusTest @@ -43,31 +47,59 @@ public class RuntimeTest { @Test public void testDrlEvaluation() { // canDrinkKS is the default session - testSimpleDrl(runtimeBuilder.newKieSession(), "org.drools.drl"); + testSimpleDrl(runtimeBuilder.newKieSession(), "org.drools.drl", true); } @Test public void testDTableEvaluation() { - testSimpleDrl(runtimeBuilder.newKieSession("canDrinkKSDTable"), "org.drools.dtable"); + testSimpleDrl(runtimeBuilder.newKieSession("canDrinkKSDTable"), "org.drools.dtable", true); } @Test public void testYamlEvaluation() { - testSimpleDrl(runtimeBuilder.newKieSession("canDrinkKSYaml"), "org.drools.yaml"); + testSimpleDrl(runtimeBuilder.newKieSession("canDrinkKSYaml"), "org.drools.yaml", true); } - private void testSimpleDrl(KieSession ksession, String assetPackage) { - List pkgNames = ksession.getKieBase().getKiePackages().stream().map(KiePackage::getName).collect(Collectors.toList()); - assertEquals(2, pkgNames.size()); - assertTrue(pkgNames.contains("org.drools.quarkus.test")); - assertTrue(pkgNames.contains(assetPackage)); + @Test + public void testStatelessDrlEvaluation() { + // statelessCanDrinkKS is the default stateless session + testSimpleDrl(runtimeBuilder.newStatelessKieSession(), "org.drools.drl", false); + } + + @Test + public void testStatelessDTableEvaluation() { + testSimpleDrl(runtimeBuilder.newStatelessKieSession("statelessCanDrinkKSDTable"), "org.drools.dtable", false); + } + + @Test + public void testStatelessYamlEvaluation() { + testSimpleDrl(runtimeBuilder.newStatelessKieSession("statelessCanDrinkKSYaml"), "org.drools.yaml", false); + } + + private void testSimpleDrl(RuntimeSession session, String assetPackage, boolean stateful) { + if (stateful) { + assertThat(session).isInstanceOf(KieSession.class); + } else { + assertThat(session).isInstanceOf(StatelessKieSession.class); + } + + List pkgNames = session.getKieBase().getKiePackages().stream().map(KiePackage::getName).collect(Collectors.toList()); + + assertThat(pkgNames).hasSize(2).containsExactlyInAnyOrder("org.drools.quarkus.test", assetPackage); + + KieCommands kieCommands = KieServices.get().getCommands(); Result result = new Result(); - ksession.insert(result); - ksession.insert(new Person("Mark", 17)); - ksession.fireAllRules(); + session.execute( kieCommands.newBatchExecution( + kieCommands.newInsert(result), + kieCommands.newInsert(new Person("Mark", 17)), + kieCommands.newFireAllRules() ) ); + + assertThat(result.toString()).isEqualTo("Mark can NOT drink"); - assertEquals("Mark can NOT drink", result.toString()); + if (stateful) { + ((KieSession) session).dispose(); + } } @Test @@ -85,7 +117,6 @@ public void testPrototypeEvaluation() { ksession.insert(result); ksession.fireAllRules(); - - assertEquals("Mark can NOT drink", result.get("value")); + assertThat(result.get("value")).isEqualTo("Mark can NOT drink"); } } diff --git a/drools-quarkus-extension/drools-quarkus-ruleunit-integration-test/src/test/java/org/drools/quarkus/ruleunit/test/RuntimeTest.java b/drools-quarkus-extension/drools-quarkus-ruleunit-integration-test/src/test/java/org/drools/quarkus/ruleunit/test/RuntimeTest.java index 873e112e293..1ac86e8100d 100644 --- a/drools-quarkus-extension/drools-quarkus-ruleunit-integration-test/src/test/java/org/drools/quarkus/ruleunit/test/RuntimeTest.java +++ b/drools-quarkus-extension/drools-quarkus-ruleunit-integration-test/src/test/java/org/drools/quarkus/ruleunit/test/RuntimeTest.java @@ -25,7 +25,7 @@ import jakarta.inject.Inject; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; @QuarkusTest public class RuntimeTest { @@ -42,7 +42,6 @@ public void testRuleUnit() { instance.fire(); } - assertEquals(1, unit.getResults().size()); - assertEquals("Hello Mario", unit.getResults().get(0)); + assertThat(unit.getResults()).hasSize(1).containsExactly("Hello Mario"); } } diff --git a/drools-quarkus-extension/drools-quarkus-util-deployment/src/main/java/org/drools/quarkus/util/deployment/KmoduleKieBaseModelsBuiltItem.java b/drools-quarkus-extension/drools-quarkus-util-deployment/src/main/java/org/drools/quarkus/util/deployment/KmoduleKieBaseModelsBuiltItem.java index d437bc3dc8a..797b46ab81d 100644 --- a/drools-quarkus-extension/drools-quarkus-util-deployment/src/main/java/org/drools/quarkus/util/deployment/KmoduleKieBaseModelsBuiltItem.java +++ b/drools-quarkus-extension/drools-quarkus-util-deployment/src/main/java/org/drools/quarkus/util/deployment/KmoduleKieBaseModelsBuiltItem.java @@ -19,8 +19,6 @@ package org.drools.quarkus.util.deployment; import java.util.Collection; -import java.util.Map; -import java.util.Set; import org.kie.api.builder.model.KieBaseModel; diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/TimerAndCalendarFireUntilHaltTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/TimerAndCalendarFireUntilHaltTest.java index c36fac63bc9..5022ae79916 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/TimerAndCalendarFireUntilHaltTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/TimerAndCalendarFireUntilHaltTest.java @@ -109,9 +109,12 @@ public void testTimerRuleFires() throws Exception { startEngine(); activateRule(); - advanceTimerOneSecond(); - await().until(ruleHasFired("TimerRule", 1)); + + advanceTimerOneSecond(); + await().until(ruleHasFired("TimerRule", 2)); + + stopEngine(); } @Test(timeout = 10000) @@ -126,14 +129,17 @@ public void testTimerRuleHaltStopsFiring() throws Exception { "end"; setupKSessionFor(drl); startEngine(); + activateRule(); - advanceTimerOneSecond(); await().until(ruleHasFired("TimerRule", 1)); + + advanceTimerOneSecond(); + await().until(ruleHasFired("TimerRule", 2)); stopEngine(); advanceTimerOneSecond(); - await().during(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(2)).until(ruleHasFired("TimerRule", 1)); + await().during(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(2)).until(ruleHasFired("TimerRule", 2)); } @Test(timeout = 10000) @@ -148,15 +154,20 @@ public void testTimerRuleRestartsAfterStop() throws Exception { "end"; setupKSessionFor(drl); startEngine(); + activateRule(); - advanceTimerOneSecond(); await().until(ruleHasFired("TimerRule", 1)); + + advanceTimerOneSecond(); + await().until(ruleHasFired("TimerRule", 2)); stopEngine(); startEngine(); advanceTimerOneSecond(); - await().during(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(2)).until(ruleHasFired("TimerRule", 2)); + await().during(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(2)).until(ruleHasFired("TimerRule", 3)); + + stopEngine(); } @Test(timeout = 10000) @@ -171,18 +182,21 @@ public void testTimerRuleDoesRestartsIfNoLongerHolds() throws Exception { "end"; setupKSessionFor(drl); startEngine(); + activateRule(); - advanceTimerOneSecond(); - await().until(ruleHasFired("TimerRule", 1)); + + advanceTimerOneSecond(); + await().until(ruleHasFired("TimerRule", 2)); stopEngine(); disactivateRule(); startEngine(); advanceTimerOneSecond(); + await().during(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(2)).until(ruleHasFired("TimerRule", 2)); - await().during(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(2)).until(ruleHasFired("TimerRule", 1)); + stopEngine(); } diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/DateCoercionTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/DateCoercionTest.java index 5d6a7157042..1dd24026b54 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/DateCoercionTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/DateCoercionTest.java @@ -25,11 +25,14 @@ import org.drools.testcoverage.common.util.KieBaseTestConfiguration; import org.drools.testcoverage.common.util.KieBaseUtil; +import org.drools.testcoverage.common.util.KieUtil; 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.builder.KieBuilder; +import org.kie.api.builder.Message; import org.kie.api.runtime.KieSession; import static org.assertj.core.api.Assertions.assertThat; @@ -176,4 +179,37 @@ public void testDateCoercionWithNestedOr() { assertThat(list.size()).isEqualTo(1); assertThat(list.get(0)).isEqualTo("working"); } + + @Test + public void testLocalDateTimeCoercion() { + // DROOLS-7631 + String drl = "import java.util.Date\n" + + "import java.time.LocalDateTime\n" + + "global java.util.List list\n" + + "declare DateContainer\n" + + " date: Date\n" + + "end\n" + + "declare LocalDateTimeContainer\n" + + " date: LocalDateTime\n" + + "end\n" + + "\n" + + "rule Init when\n" + + "then\n" + + " insert(new DateContainer(new Date( 1439882189744L )));" + + " insert(new LocalDateTimeContainer( LocalDateTime.now() ));" + + "end\n" + + "\n" + + "rule \"Test rule\"\n" + + "when\n" + + " DateContainer( $date: date )\n" + + " LocalDateTimeContainer( date > $date )\n" + + "then\n" + + " list.add(\"working\");\n" + + "end\n"; + + KieBuilder kieBuilder = KieUtil.getKieBuilderFromDrls(kieBaseTestConfiguration, false, drl); + List errors = kieBuilder.getResults().getMessages(Message.Level.ERROR); + assertThat(errors).hasSize(1); + assertThat(errors.get(0).getText()).contains("Comparison operation requires compatible types"); + } } diff --git a/drools-util/src/main/java/org/drools/util/CoercionUtil.java b/drools-util/src/main/java/org/drools/util/CoercionUtil.java index f91b2bd2358..bb7d5ac0e73 100644 --- a/drools-util/src/main/java/org/drools/util/CoercionUtil.java +++ b/drools-util/src/main/java/org/drools/util/CoercionUtil.java @@ -19,10 +19,14 @@ package org.drools.util; +import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; +import java.time.chrono.ChronoLocalDateTime; +import java.time.temporal.Temporal; +import java.util.Objects; -import org.drools.util.MathUtils; +import static org.drools.util.ClassUtils.convertFromPrimitiveType; public class CoercionUtil { @@ -194,4 +198,49 @@ public static Number coerceToNumber(Number value, Class toClass) { } return ret; } + + public static boolean areEqualityCompatible(Class c1, Class c2) { + if (c1 == MethodUtils.NullType.class || c2 == MethodUtils.NullType.class) { + return true; + } + if (c1 == String.class || c2 == String.class) { + return true; + } + if (Temporal.class.isAssignableFrom(c1) && Temporal.class.isAssignableFrom(c2)) { + return true; + } + Class boxed1 = convertFromPrimitiveType(c1); + Class boxed2 = convertFromPrimitiveType(c2); + if (boxed1.isAssignableFrom(boxed2) || boxed2.isAssignableFrom(boxed1)) { + return true; + } + if (Number.class.isAssignableFrom(boxed1) && Number.class.isAssignableFrom(boxed2)) { + return true; + } + if (areEqualityCompatibleEnums(boxed1, boxed2)) { + return true; + } + return !Modifier.isFinal(c1.getModifiers()) && !Modifier.isFinal(c2.getModifiers()); + } + + protected static boolean areEqualityCompatibleEnums(Class boxed1, Class boxed2) { + return boxed1.isEnum() && boxed2.isEnum() && boxed1.getName().equals(boxed2.getName()) + && equalEnumConstants(boxed1.getEnumConstants(), boxed2.getEnumConstants()); + } + + private static boolean equalEnumConstants(Object[] aa, Object[] bb) { + if (aa.length != bb.length) { + return false; + } + for (int i = 0; i < aa.length; i++) { + if (!Objects.equals(aa[i].getClass().getName(), bb[i].getClass().getName())) { + return false; + } + } + return true; + } + + public static boolean areComparisonCompatible(Class c1, Class c2) { + return areEqualityCompatible(c1, c2); + } } diff --git a/kie-api/src/main/java/org/kie/api/command/KieCommands.java b/kie-api/src/main/java/org/kie/api/command/KieCommands.java index afb5d8d2bbd..9cb50473ad2 100644 --- a/kie-api/src/main/java/org/kie/api/command/KieCommands.java +++ b/kie-api/src/main/java/org/kie/api/command/KieCommands.java @@ -29,6 +29,8 @@ import org.kie.api.runtime.process.WorkItemHandler; import org.kie.api.runtime.rule.FactHandle; +import static java.util.Arrays.asList; + /** * KieCommands is a factory for Commands that can be used by classes that implement CommandExecutor. Typically more than one Command * will want to be executed, where is where the BatchExecution comes in, which takes a List of commands, think of it as CompositeCommand. @@ -115,6 +117,10 @@ Command newQuery(String identifier, String name, Object[] arguments); + default BatchExecutionCommand newBatchExecution(Command... commands) { + return newBatchExecution( asList(commands) ); + } + BatchExecutionCommand newBatchExecution(List< ? extends Command> commands); BatchExecutionCommand newBatchExecution(List< ? extends Command> commands, String lookup); diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/Attachment.java b/kie-api/src/main/java/org/kie/api/event/usertask/Attachment.java deleted file mode 100644 index ded0ce0df24..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/Attachment.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -import java.net.URI; -import java.util.Date; - -public interface Attachment { - - String getAttachmentId(); - - String getAttachmentName(); - - URI getAttachmentURI(); - - String getUpdatedBy(); - - Date getUpdatedAt(); - -} diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/Comment.java b/kie-api/src/main/java/org/kie/api/event/usertask/Comment.java deleted file mode 100644 index 004d3e7d6ee..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/Comment.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -import java.util.Date; - -public interface Comment { - - String getCommentId(); - - String getCommentContent(); - - String getUpdatedBy(); - - Date getUpdatedAt(); - -} diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskAssignmentEvent.java b/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskAssignmentEvent.java deleted file mode 100644 index 01d460e0ddb..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskAssignmentEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -public interface UserTaskAssignmentEvent extends UserTaskEvent { - - String getAssignmentType(); - - String[] getNewUsersId(); - - String[] getOldUsersId(); - -} diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskAttachmentEvent.java b/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskAttachmentEvent.java deleted file mode 100644 index 9f82c73605e..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskAttachmentEvent.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -public interface UserTaskAttachmentEvent extends UserTaskEvent { - - Attachment getOldAttachment(); - - Attachment getNewAttachment(); - -} diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskCommentEvent.java b/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskCommentEvent.java deleted file mode 100644 index b51eb3e6bd6..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskCommentEvent.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -public interface UserTaskCommentEvent extends UserTaskEvent { - - Comment getOldComment(); - - Comment getNewComment(); - -} diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskDeadlineEvent.java b/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskDeadlineEvent.java deleted file mode 100644 index c1c46b7a1d0..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskDeadlineEvent.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -import java.util.Map; - -import org.kie.api.runtime.process.WorkItem; - -/** - * An event when a dealine for task has expired - */ -public interface UserTaskDeadlineEvent extends UserTaskEvent { - - enum DeadlineType { - Started, - Completed - } - - /** - * Returns work item which timeout expires - * - * @return work item - */ - WorkItem getWorkItem(); - - /** - * Returns notification data - * - * @return key-value pair list - */ - Map getNotification(); - - /** - * Returns dealine type - * - * @return not started or not completed - */ - DeadlineType getType(); -} \ No newline at end of file diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskEvent.java b/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskEvent.java deleted file mode 100644 index 8f45c48b905..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskEvent.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -import java.util.Date; - -import org.kie.api.event.KieRuntimeEvent; -import org.kie.api.runtime.process.NodeInstance; -import org.kie.api.runtime.process.ProcessInstance; -import org.kie.api.runtime.process.WorkItem; - -/** - * A runtime event related to the execution of process instances. - */ -public interface UserTaskEvent - extends - KieRuntimeEvent { - - /** - * The ProcessInstance this event relates to. - * - * @return the process instance - */ - ProcessInstance getProcessInstance(); - - NodeInstance getNodeInstance(); - - WorkItem getWorkItem(); - - String getUserTaskId(); - - String getUserTaskDefinitionId(); - - /** - * Returns exact date when the event was created - * @return time when event was created - */ - Date getEventDate(); - - /** - * @return associated identity that performed the event - */ - String getEventUser(); - -} diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskStateEvent.java b/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskStateEvent.java deleted file mode 100644 index 7ed47cc4d37..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskStateEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -public interface UserTaskStateEvent extends UserTaskEvent { - - String getNewStatus(); - - String getOldStatus(); - - - -} diff --git a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskVariableEvent.java b/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskVariableEvent.java deleted file mode 100644 index a7dab82d79f..00000000000 --- a/kie-api/src/main/java/org/kie/api/event/usertask/UserTaskVariableEvent.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 - * - * 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.kie.api.event.usertask; - -public interface UserTaskVariableEvent extends UserTaskEvent { - - enum VariableEventType { - INPUT, OUTPUT - } - - String getVariableName(); - - Object getOldValue(); - - Object getNewValue(); - - VariableEventType getVariableType(); -} diff --git a/kie-api/src/main/java/org/kie/api/runtime/KieRuntime.java b/kie-api/src/main/java/org/kie/api/runtime/KieRuntime.java index 1ea1669fc18..d8495f069c2 100644 --- a/kie-api/src/main/java/org/kie/api/runtime/KieRuntime.java +++ b/kie-api/src/main/java/org/kie/api/runtime/KieRuntime.java @@ -18,53 +18,23 @@ */ package org.kie.api.runtime; -import java.util.Map; - -import org.kie.api.KieBase; import org.kie.api.event.KieRuntimeEventManager; -import org.kie.api.runtime.KieSessionConfiguration; import org.kie.api.runtime.process.ProcessRuntime; import org.kie.api.runtime.rule.RuleRuntime; import org.kie.api.time.SessionClock; -public interface KieRuntime - extends - RuleRuntime, - ProcessRuntime, - KieRuntimeEventManager { +public interface KieRuntime extends RuntimeSession, RuleRuntime, ProcessRuntime, KieRuntimeEventManager { /** * @return the session clock instance assigned to this session */ T getSessionClock(); - /** - * Sets a global value in this session - * @param identifier the global identifier - * @param value the value assigned to the global identifier - */ - void setGlobal(String identifier, - Object value); - Object getGlobal(String identifier); - Globals getGlobals(); - Calendars getCalendars(); Environment getEnvironment(); - /** - * @return the KieBase reference from which this stateful session was created. - */ - KieBase getKieBase(); - - void registerChannel(String name, - Channel channel); - - void unregisterChannel(String name); - - Map< String, Channel> getChannels(); - KieSessionConfiguration getSessionConfiguration(); } diff --git a/kie-api/src/main/java/org/kie/api/runtime/KieRuntimeBuilder.java b/kie-api/src/main/java/org/kie/api/runtime/KieRuntimeBuilder.java index 4628f816bbe..9f4868fa105 100644 --- a/kie-api/src/main/java/org/kie/api/runtime/KieRuntimeBuilder.java +++ b/kie-api/src/main/java/org/kie/api/runtime/KieRuntimeBuilder.java @@ -27,6 +27,9 @@ public interface KieRuntimeBuilder { KieSession newKieSession(); KieSession newKieSession(String sessionName); + StatelessKieSession newStatelessKieSession(); + StatelessKieSession newStatelessKieSession(String sessionName); + default KieSession newKieSession(KieSessionConfiguration conf) { return getKieBase().newKieSession(conf, null); } diff --git a/kie-api/src/main/java/org/kie/api/runtime/RuntimeSession.java b/kie-api/src/main/java/org/kie/api/runtime/RuntimeSession.java new file mode 100644 index 00000000000..60ddf5a957d --- /dev/null +++ b/kie-api/src/main/java/org/kie/api/runtime/RuntimeSession.java @@ -0,0 +1,67 @@ +/** + * 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 + * + * 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.kie.api.runtime; + +import org.kie.api.KieBase; + +import java.util.Map; + +public interface RuntimeSession extends CommandExecutor { + + /** + * @return the Globals store + */ + Globals getGlobals(); + + /** + * Sets a global value on the globals store + * + * @param identifier the global identifier + * @param value the value assigned to the global identifier + */ + void setGlobal(String identifier, + Object value); + + + /** + * Registers a channel with the given name + * + * @param name the name of the channel + * @param channel the channel instance. It has to be thread safe. + */ + void registerChannel(String name, + Channel channel); + + /** + * Unregisters the channel with the given name + * + * @param name + */ + void unregisterChannel(String name); + + /** + * @return a map with all registered channels. + */ + Map getChannels(); + + /** + * @return the KieBase reference from which this stateless session was created. + */ + KieBase getKieBase(); +} diff --git a/kie-api/src/main/java/org/kie/api/runtime/StatelessKieSession.java b/kie-api/src/main/java/org/kie/api/runtime/StatelessKieSession.java index 4c7869eb1e6..5f8460d6bb4 100644 --- a/kie-api/src/main/java/org/kie/api/runtime/StatelessKieSession.java +++ b/kie-api/src/main/java/org/kie/api/runtime/StatelessKieSession.java @@ -18,9 +18,6 @@ */ package org.kie.api.runtime; -import java.util.Map; - -import org.kie.api.KieBase; import org.kie.api.event.KieRuntimeEventManager; import org.kie.api.runtime.process.StatelessProcessSession; import org.kie.api.runtime.rule.StatelessRuleSession; @@ -106,51 +103,6 @@ * results.getValue( "Get People" );// returns the query as a QueryResults instance. * */ -public interface StatelessKieSession - extends - StatelessRuleSession, - StatelessProcessSession, - CommandExecutor, - KieRuntimeEventManager { - - /** - * @return the Globals store - */ - Globals getGlobals(); - - /** - * Sets a global value on the globals store - * - * @param identifier the global identifier - * @param value the value assigned to the global identifier - */ - void setGlobal(String identifier, - Object value); - - - /** - * Registers a channel with the given name - * - * @param name the name of the channel - * @param channel the channel instance. It has to be thread safe. - */ - void registerChannel(String name, - Channel channel); - - /** - * Unregisters the channel with the given name - * - * @param name - */ - void unregisterChannel(String name); - - /** - * @return a map with all registered channels. - */ - Map getChannels(); +public interface StatelessKieSession extends StatelessRuleSession, StatelessProcessSession, RuntimeSession, KieRuntimeEventManager { - /** - * @return the KieBase reference from which this stateless session was created. - */ - KieBase getKieBase(); } diff --git a/kie-dmn/Developer_Guide.md b/kie-dmn/Developer_Guide.md index 7dee4a57417..33fc6c8933c 100644 --- a/kie-dmn/Developer_Guide.md +++ b/kie-dmn/Developer_Guide.md @@ -1,3 +1,22 @@ + + # kie-dmn - Developer Guide This module (and all its submodules) contains the code that make up the DMN engine. diff --git a/kie-dmn/kie-dmn-core-jsr223/pom.xml b/kie-dmn/kie-dmn-core-jsr223/pom.xml index b0f93bc3ac2..42c9feff4fa 100644 --- a/kie-dmn/kie-dmn-core-jsr223/pom.xml +++ b/kie-dmn/kie-dmn-core-jsr223/pom.xml @@ -112,21 +112,10 @@ kie-dmn-core-jsr223-jq test + + org.openjdk.nashorn + nashorn-core + test + - - - - add-jdk15plus-dependencies - - [15,) - - - - org.openjdk.nashorn - nashorn-core - test - - - - \ No newline at end of file diff --git a/kie-dmn/kie-dmn-core/src/test/resources/org/kie/dmn/core/0089-nested-inputdata-imports.dmn b/kie-dmn/kie-dmn-core/src/test/resources/org/kie/dmn/core/0089-nested-inputdata-imports.dmn index e158a086470..feafc13302d 100644 --- a/kie-dmn/kie-dmn-core/src/test/resources/org/kie/dmn/core/0089-nested-inputdata-imports.dmn +++ b/kie-dmn/kie-dmn-core/src/test/resources/org/kie/dmn/core/0089-nested-inputdata-imports.dmn @@ -1,4 +1,23 @@ + + + + + + + + org.kie.dmn.feel 2 true + 12.5 + + + + net.sf.saxon + Saxon-HE + ${version.net.sf.saxon.Saxon-HE} + + + + @@ -52,6 +63,10 @@ + + net.sf.saxon + Saxon-HE + org.antlr antlr4-runtime diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/MatchesFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/MatchesFunction.java index 79ff2a01368..2acb38ad269 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/MatchesFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/MatchesFunction.java @@ -18,15 +18,9 @@ */ package org.kie.dmn.feel.runtime.functions; -import java.security.InvalidParameterException; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; -import java.util.stream.Collectors; - import org.kie.dmn.api.feel.runtime.events.FEELEvent.Severity; import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; +import org.kie.dmn.feel.util.XQueryImplUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,58 +38,23 @@ public FEELFnResult invoke(@ParameterName("input") String input, @Param } public FEELFnResult invoke(@ParameterName("input") String input, @ParameterName("pattern") String pattern, @ParameterName("flags") String flags) { - try { - return matchFunctionWithFlags(input,pattern,flags); - } catch ( PatternSyntaxException t ) { - return FEELFnResult.ofError( new InvalidParametersEvent( Severity.ERROR, "pattern", "is invalid and can not be compiled", t ) ); - } catch (InvalidParameterException t ) { - return FEELFnResult.ofError( new InvalidParametersEvent( Severity.ERROR, t.getMessage(), "cannot be null", t ) ); - } catch (IllegalArgumentException t ) { - return FEELFnResult.ofError( new InvalidParametersEvent( Severity.ERROR, "flags", "contains unknown flags", t ) ); - } catch (Throwable t) { - return FEELFnResult.ofError( new InvalidParametersEvent( Severity.ERROR, "pattern", "is invalid and can not be compiled", t ) ); - } - } - - static FEELFnResult matchFunctionWithFlags(String input, String pattern, String flags) { log.debug("Input: {} , Pattern: {}, Flags: {}", input, pattern, flags); + if ( input == null ) { - throw new InvalidParameterException("input"); + return FEELFnResult.ofError( new InvalidParametersEvent( Severity.ERROR, "input", "cannot be null" ) ); } if ( pattern == null ) { - throw new InvalidParameterException("pattern"); + return FEELFnResult.ofError( new InvalidParametersEvent( Severity.ERROR, "pattern", "cannot be null" ) ); } - final String flagsString; - if (flags != null && !flags.isEmpty()) { - checkFlags(flags); - if(!flags.contains("U")){ - flags += "U"; - } - flagsString = String.format("(?%s)", flags); - } else { - flagsString = ""; - } - log.debug("flagsString: {}", flagsString); - String stringToBeMatched = flagsString + pattern; - log.debug("stringToBeMatched: {}", stringToBeMatched); - Pattern p=Pattern.compile(stringToBeMatched); - Matcher m = p.matcher( input ); - boolean matchFound=m.find(); - log.debug("matchFound: {}", matchFound); - return FEELFnResult.ofResult(matchFound); - } - static void checkFlags(String flags) { - Set allowedChars = Set.of('s','i','x','m'); - boolean isValidFlag= flags.chars() - .mapToObj(c -> (char) c) - .allMatch(allowedChars::contains) - && flags.chars() - .mapToObj(c -> (char) c) - .collect(Collectors.toSet()) - .size() == flags.length(); - if(!isValidFlag){ - throw new IllegalArgumentException("Not a valid flag parameter " +flags); - } + try { + return FEELFnResult.ofResult(XQueryImplUtil.executeMatchesFunction(input, pattern, flags)); + } catch (Exception e) { + String errorMessage = String.format("Provided parameters lead to an error. Input: '%s', Pattern: '%s', Flags: '%s'. ", input, pattern, flags); + if (e.getMessage() != null && !e.getMessage().isEmpty()) { + errorMessage += e.getMessage(); + } + return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, errorMessage, e)); + } } } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ReplaceFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ReplaceFunction.java index 723efcbdd36..a7ae497870a 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ReplaceFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ReplaceFunction.java @@ -20,6 +20,7 @@ import org.kie.dmn.api.feel.runtime.events.FEELEvent.Severity; import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; +import org.kie.dmn.feel.util.XQueryImplUtil; public class ReplaceFunction extends BaseFEELFunction { @@ -30,12 +31,12 @@ private ReplaceFunction() { super( "replace" ); } - public FEELFnResult invoke(@ParameterName("input") String input, @ParameterName("pattern") String pattern, + public FEELFnResult invoke(@ParameterName("input") String input, @ParameterName("pattern") String pattern, @ParameterName( "replacement" ) String replacement ) { return invoke(input, pattern, replacement, null); } - public FEELFnResult invoke(@ParameterName("input") String input, @ParameterName("pattern") String pattern, + public FEELFnResult invoke(@ParameterName("input") String input, @ParameterName("pattern") String pattern, @ParameterName( "replacement" ) String replacement, @ParameterName("flags") String flags) { if ( input == null ) { return FEELFnResult.ofError( new InvalidParametersEvent( Severity.ERROR, "input", "cannot be null" ) ); @@ -47,14 +48,16 @@ public FEELFnResult invoke(@ParameterName("input") String input, @Parame return FEELFnResult.ofError( new InvalidParametersEvent( Severity.ERROR, "replacement", "cannot be null" ) ); } - final String flagsString; - if (flags != null && !flags.isEmpty()) { - flagsString = "(?" + flags + ")"; - } else { - flagsString = ""; + try { + return FEELFnResult.ofResult(XQueryImplUtil.executeReplaceFunction(input, pattern, replacement, flags)); + } catch (Exception e) { + String errorMessage = String.format("Provided parameters lead to an error. Input: '%s', Pattern: '%s', Replacement: '%s', Flags: '%s'. ", + input, pattern, replacement, flags); + if (e.getMessage() != null && !e.getMessage().isEmpty()) { + errorMessage += e.getMessage(); + } + return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, errorMessage, e)); } - - return FEELFnResult.ofResult( input.replaceAll( flagsString + pattern, replacement ) ); } } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/XQueryImplUtil.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/XQueryImplUtil.java new file mode 100644 index 00000000000..a3ae1c6e53a --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/XQueryImplUtil.java @@ -0,0 +1,62 @@ +/** + * 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 + * + * 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.kie.dmn.feel.util; + +import net.sf.saxon.s9api.Processor; +import net.sf.saxon.s9api.XdmAtomicValue; +import net.sf.saxon.s9api.XdmItem; +import net.sf.saxon.s9api.XQueryCompiler; +import net.sf.saxon.s9api.XQueryEvaluator; +import net.sf.saxon.s9api.XQueryExecutable; +import net.sf.saxon.s9api.SaxonApiException; + +public class XQueryImplUtil { + + public static Boolean executeMatchesFunction(String input, String pattern, String flags) { + flags = flags == null ? "" : flags; + String xQueryExpression = String.format("matches('%s', '%s', '%s')", input, pattern, flags); + return evaluateXQueryExpression(xQueryExpression, Boolean.class); + } + + public static String executeReplaceFunction(String input, String pattern, String replacement, String flags) { + flags = flags == null ? "" : flags; + String xQueryExpression = String.format("replace('%s', '%s', '%s', '%s')", input, pattern, replacement, flags); + return evaluateXQueryExpression(xQueryExpression, String.class); + } + + static T evaluateXQueryExpression(String expression, Class expectedTypeResult) { + try { + Processor processor = new Processor(false); + XQueryCompiler compiler = processor.newXQueryCompiler(); + XQueryExecutable executable = compiler.compile(expression); + XQueryEvaluator queryEvaluator = executable.load(); + XdmItem resultItem = queryEvaluator.evaluateSingle(); + + Object value = switch (expectedTypeResult.getSimpleName()) { + case "Boolean" -> ((XdmAtomicValue) resultItem).getBooleanValue(); + case "String" -> resultItem.getStringValue(); + default -> throw new UnsupportedOperationException("Type " + expectedTypeResult.getSimpleName() + " is not managed."); + }; + + return expectedTypeResult.cast(value); + } catch (SaxonApiException e) { + throw new IllegalArgumentException(e); + } + } +} diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/FEELFunctionsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/FEELFunctionsTest.java index 3707929e3bd..a199e8f1f6f 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/FEELFunctionsTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/FEELFunctionsTest.java @@ -43,7 +43,6 @@ private static Collection data() { final Object[][] cases = new Object[][] { // constants { "string(1.1)", "1.1" , null}, - { "replace( \" foo bar zed \", \"^(\\s)+|(\\s)+$|\\s+(?=\\s)\", \"\" )", "foo bar zed", null }, { "string(null)", null, null}, { "string(date(\"2016-08-14\"))", "2016-08-14" , null}, { "string(\"Happy %.0fth birthday, Mr %s!\", 38, \"Doe\")", "Happy 38th birthday, Mr Doe!", null}, @@ -85,6 +84,14 @@ private static Collection data() { { "matches(\"one\\ntwo\\nthree\", \"^two$\", \"m\")", Boolean.TRUE , null}, // MULTILINE flag set by "m" { "matches(\"FoO\", \"foo\")", Boolean.FALSE , null}, { "matches(\"FoO\", \"foo\", \"i\")", Boolean.TRUE , null}, // CASE_INSENSITIVE flag set by "i" + { "matches(\"\\u212A\", \"k\", \"i\")", Boolean.TRUE , null}, + { "matches(\"O\", \"[A-Z-[OI]]\", \"i\")", Boolean.FALSE , null}, + { "matches(\"i\", \"[A-Z-[OI]]\", \"i\")", Boolean.FALSE , null}, + { "matches(\"hello world\", \"hello\\ sworld\", \"x\")", Boolean.TRUE , null}, + { "matches(\"abracadabra\", \"bra\", \"p\")", null , FEELEvent.Severity.ERROR}, + { "matches(\"input\", \"pattern\", \" \")", null , FEELEvent.Severity.ERROR}, + { "matches(\"input\", \"pattern\", \"X\")", null , FEELEvent.Severity.ERROR}, + { "matches(\"h\", \"(.)\\2\")", null , FEELEvent.Severity.ERROR}, { "replace(\"banana\",\"a\",\"o\")", "bonono" , null}, { "replace(\"banana\",\"(an)+\", \"**\")", "b**a" , null}, { "replace(\"banana\",\"[aeiouy]\",\"[$0]\")", "b[a]n[a]n[a]" , null}, diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/MatchesFunctionTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/MatchesFunctionTest.java index b12612bb04a..589f37e3d2d 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/MatchesFunctionTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/MatchesFunctionTest.java @@ -19,116 +19,146 @@ package org.kie.dmn.feel.runtime.functions; import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; -import java.security.InvalidParameterException; -import java.util.regex.PatternSyntaxException; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatNoException; -import static org.mockito.Mockito.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; class MatchesFunctionTest { - @Test - void invokeNull() { - assertThatExceptionOfType(InvalidParameterException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags(null, null, null)); - assertThatExceptionOfType(InvalidParameterException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags(null, "test", null)); - assertThatExceptionOfType(InvalidParameterException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags("test", null, null)); + private static final MatchesFunction matchesFunction = MatchesFunction.INSTANCE; + + @ParameterizedTest + @MethodSource("invokeNullTestData") + void invokeNullTest(String input, String pattern) { + FunctionTestUtil.assertResultError(matchesFunction.invoke(input, pattern), InvalidParametersEvent.class); } - @Test - void invokeUnsupportedFlags() { - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags("foobar", "fo.bar", "g")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags("abracadabra", "bra", "p")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags("abracadabra", "bra", "X")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags("abracadabra", "bra", " ")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags("abracadabra", "bra", "iU")); + private static Object[][] invokeNullTestData() { + return new Object[][] { + { null, null }, + { null, "test" }, + { "test", null }, + }; } - @Test - void invokeWithoutFlagsMatch() { - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("test", "test",null), true); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("foobar", "^fo*b",null), true); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("abracadabra", "bra", ""), true); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("abracadabra", "bra",null), true); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("(?xi)[hello world()]", "hello",null), true); + @ParameterizedTest + @MethodSource("invokeUnsupportedFlagsTestData") + void invokeUnsupportedFlagsTest(String input, String pattern, String flags) { + FunctionTestUtil.assertResultError(matchesFunction.invoke(input, pattern, flags), InvalidParametersEvent.class); + } + + private static Object[][] invokeUnsupportedFlagsTestData() { + return new Object[][] { + { "foobar", "fo.bar", "g" }, + { "abracadabra", "bra", "p" }, + { "abracadabra", "bra", "X" }, + { "abracadabra", "bra", "iU" }, + { "abracadabra", "bra", "iU asd" }, + }; } - @Test - void invokeWithoutFlagsNotMatch() { - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("test", "testt",null), false); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("foobar", "^fo*bb",null), false); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("fo\nbar", "fo.bar",null), false); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("h", "(.)\3",null), false); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("h", "(.)\2",null), false); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("input", "\3",null), false); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("fo\nbar", "(?iU)(?iU)(ab)[|cd]",null), false); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("fo\nbar", "(?x)(?i)hello world","i"), false); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("fo\nbar", "(?xi)hello world",null), false); + @ParameterizedTest + @MethodSource("invokeWithoutFlagsMatchTestData") + void invokeWithoutFlagsMatchTest(String input, String pattern, Boolean expectedResult) { + FunctionTestUtil.assertResult(matchesFunction.invoke(input, pattern), expectedResult); } - @Test - void invokeWithFlagDotAll() { - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("fo\nbar", "fo.bar", "s"), true); + private static Object[][] invokeWithoutFlagsMatchTestData() { + return new Object[][] { + { "test", "test", true }, + { "foobar", "^fo*b", true }, + { "abracadabra", "bra", true }, + { "abracadabra", "bra", true }, + { "(?xi)[hello world()]", "hello", true } + }; } - @Test - void invokeWithFlagMultiline() { - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("fo\nbar", "^bar", "m"), true); + @ParameterizedTest + @MethodSource("invokeNullOrEmptyFlagsMatchTestData") + void invokeNullOrEmptyFlagsMatchTest(String input, String pattern, String flags, Boolean expectedResult) { + FunctionTestUtil.assertResult(matchesFunction.invoke(input, pattern, flags), expectedResult); } - @Test - void invokeWithFlagCaseInsensitive() { - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("foobar", "^Fo*bar", "i"), true); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("foobar", "^Fo*bar", "i"), true); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("\u212A", "k","i"), true); - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("\u212A", "K","i"), true); + private static Object[][] invokeNullOrEmptyFlagsMatchTestData() { + return new Object[][] { + { "test", "test", null, true }, + { "foobar", "^fo*b", null, true }, + { "abracadabra", "bra", null, true }, + { "abracadabra", "bra", "", true }, + { "(?xi)[hello world()]", "hello", null, true } + }; + } + + @ParameterizedTest + @MethodSource("invokeInvalidRegexTestData") + void invokeInvalidRegexTest(String input, String pattern, String flags) { + FunctionTestUtil.assertResultError(matchesFunction.invoke(input, pattern, flags), InvalidParametersEvent.class); + } + + private static Object[][] invokeInvalidRegexTestData() { + return new Object[][] { + { "testString", "(?=\\\\s)", null }, + { "fo\nbar", "(?iU)(?iU)(ab)[|cd]", null }, + { "fo\nbar", "(?x)(?i)hello world", "i" }, + { "fo\nbar", "(?xi)hello world", null }, + }; + } + + @ParameterizedTest + @MethodSource("invokeWithoutFlagsNotMatchTestData") + void invokeWithoutFlagsNotMatchTest(String input, String pattern, String flags, Boolean expectedResult) { + FunctionTestUtil.assertResult(matchesFunction.invoke(input, pattern, flags), expectedResult); + } + + private static Object[][] invokeWithoutFlagsNotMatchTestData() { + return new Object[][] { + { "test", "testt", null, false }, + { "foobar", "^fo*bb", null, false }, + { "h", "(.)\3", null, false }, + { "h", "(.)\2", null, false }, + { "input", "\3", null, false } + }; + } + + @ParameterizedTest + @MethodSource("invokeWithFlagCaseInsensitiveTestData") + void invokeWithoutFlagsPatternTest(String input, String pattern, String flags, Boolean expectedResult) { + FunctionTestUtil.assertResult(matchesFunction.invoke(input, pattern, flags), expectedResult); + } + + private static Object[][] invokeWithFlagCaseInsensitiveTestData() { + return new Object[][] { + { "foobar", "^Fo*bar", "i", true }, + { "foobar", "^Fo*bar", "i", true }, + { "\u212A", "k", "i", true }, + { "\u212A", "K", "i", true } + }; } @Test - void invokeWithFlagComments() { - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("hello world", "hello"+"\"+ sworld", "x"), false); + void invokeWithFlagDotAll() { + FunctionTestUtil.assertResult(matchesFunction.invoke("fo\nbar", "fo.bar", "s"), true); } @Test - void invokeWithAllFlags() { - FunctionTestUtil.assertResult(MatchesFunction.matchFunctionWithFlags("fo\nbar", "Fo.^bar", "smi"), true); + void invokeWithFlagMultiline() { + FunctionTestUtil.assertResult(matchesFunction.invoke("fo\nbar", "^bar", "m"), true); } @Test - void checkForPatternTest() { - assertThatExceptionOfType(PatternSyntaxException.class).isThrownBy(() -> MatchesFunction.matchFunctionWithFlags("foobar", "(abc|def(ghi", "i")); + void invokeWithFlagComments() { + FunctionTestUtil.assertResult(matchesFunction.invoke("hello world", "hello"+"\"+ sworld", "x"), false); } @Test - void checkFlagsTest() { - assertThatNoException().isThrownBy(() -> MatchesFunction.checkFlags("s")); - assertThatNoException().isThrownBy(() -> MatchesFunction.checkFlags("i")); - assertThatNoException().isThrownBy(() -> MatchesFunction.checkFlags("sx")); - assertThatNoException().isThrownBy(() -> MatchesFunction.checkFlags("six")); - assertThatNoException().isThrownBy(() -> MatchesFunction.checkFlags("sixm")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.checkFlags("a")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.checkFlags("sa")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.checkFlags("siU@")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.checkFlags("siUxU")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.checkFlags("ss")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.checkFlags("siiU")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.checkFlags("si U")); - assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> MatchesFunction.checkFlags("U")); + void invokeWithAllFlags() { + FunctionTestUtil.assertResult(matchesFunction.invoke("fo\nbar", "Fo.^bar", "smi"), true); } @Test - void checkMatchFunctionWithFlagsInvocation() { - MatchesFunction matchesFunctionSpied = spy(MatchesFunction.INSTANCE); - matchesFunctionSpied.invoke("input", "pattern"); - verify(matchesFunctionSpied, times(1)).invoke("input", "pattern", null); - try (MockedStatic matchesFunctionMocked = mockStatic(MatchesFunction.class)) { - matchesFunctionSpied.invoke("input", "pattern"); - matchesFunctionMocked.verify(() -> MatchesFunction.matchFunctionWithFlags("input", "pattern", null)); - matchesFunctionSpied.invoke("input", "pattern", "flags"); - matchesFunctionMocked.verify(() -> MatchesFunction.matchFunctionWithFlags("input", "pattern", "flags")); - } + void checkForPatternTest() { + FunctionTestUtil.assertResultError(matchesFunction.invoke("foobar", "(abc|def(ghi", "i"), InvalidParametersEvent.class); } } \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/ReplaceFunctionTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/ReplaceFunctionTest.java index 06e1bc4da0e..45d1334f358 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/ReplaceFunctionTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/ReplaceFunctionTest.java @@ -19,62 +19,88 @@ package org.kie.dmn.feel.runtime.functions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; class ReplaceFunctionTest { private static final ReplaceFunction replaceFunction = ReplaceFunction.INSTANCE; - @Test - void invokeNull() { - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, null, null), InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke("testString", null, null), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke("testString", "test", null), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, "test", null), InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, "test", "ttt"), InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, null, "ttt"), InvalidParametersEvent.class); + @ParameterizedTest + @MethodSource("invokeNullTestData") + void invokeNullTest(String input, String pattern, String replacement) { + FunctionTestUtil.assertResultError(replaceFunction.invoke(input, pattern, replacement), InvalidParametersEvent.class); } - @Test - void invokeNullWithFlags() { - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, null, null, null), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke("testString", null, null, null), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke("testString", "test", null, null), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, "test", null, null), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, "test", "ttt", null), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, null, "ttt", null), - InvalidParametersEvent.class); - - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, null, null, "s"), InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke("testString", null, null, "s"), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke("testString", "test", null, "s"), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, "test", null, "s"), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, "test", "ttt", "s"), - InvalidParametersEvent.class); - FunctionTestUtil.assertResultError(replaceFunction.invoke(null, null, "ttt", "s"), - InvalidParametersEvent.class); + private static Object[][] invokeNullTestData() { + return new Object[][] { + { null, null, null }, + { "testString", null, null }, + { "testString", "test", null }, + { null, "test", null }, + { null, "test", "ttt" }, + { null, null, "ttt" } + }; } - @Test - void invokeWithoutFlagsPatternMatches() { - FunctionTestUtil.assertResult(replaceFunction.invoke("testString", "^test", "ttt"), "tttString"); - FunctionTestUtil.assertResult(replaceFunction.invoke("testStringtest", "^test", "ttt"), "tttStringtest"); + @ParameterizedTest + @MethodSource("invokeNullWithFlagsTestData") + void invokeNullWithFlagsTest(String input, String pattern, String replacement, String flags) { + FunctionTestUtil.assertResultError(replaceFunction.invoke(input, pattern, replacement, flags), InvalidParametersEvent.class); + } + + private static Object[][] invokeNullWithFlagsTestData() { + return new Object[][] { + { null, null, null, null }, + { "testString", null, null, null }, + { "testString", "test", null, null }, + { null, "test", null, null }, + { null, "test", "ttt", null }, + { null, null, "ttt", null }, + { null, null, null, "s" }, + { "testString", null, null, "s" }, + { "testString", "test", null, "s" }, + { null, "test", null, "s" }, + { null, "test", "ttt", "s" }, + { null, null, "ttt", "s" }, + }; + } + + @ParameterizedTest + @MethodSource("invokeUnsupportedFlagsTestData") + void invokeUnsupportedFlagsTest(String input, String pattern, String replacement, String flags) { + FunctionTestUtil.assertResultError(replaceFunction.invoke(input, pattern, replacement, flags), InvalidParametersEvent.class); + } + + private static Object[][] invokeUnsupportedFlagsTestData() { + return new Object[][] { + { "testString", "^test", "ttt", "g" }, + { "testString", "^test", "ttt", "p" }, + { "testString", "^test", "ttt", "X" }, + { "testString", "^test", "ttt", "iU" }, + { "testString", "^test", "ttt", "iU asd" }, + }; + } + + @ParameterizedTest + @MethodSource("invokeWithoutFlagsPatternTestData") + void invokeWithoutFlagsPatternTest(String input, String pattern, String replacement, String expectedResult) { + FunctionTestUtil.assertResult(replaceFunction.invoke(input, pattern, replacement), expectedResult); + } + + private static Object[][] invokeWithoutFlagsPatternTestData() { + return new Object[][] { + { "testString", "^test", "ttt", "tttString" }, + { "testStringtest", "^test", "ttt", "tttStringtest" }, + { "testString", "ttest", "ttt", "testString" }, + { "testString", "$test", "ttt", "testString" } + }; } @Test - void invokeWithoutFlagsPatternNotMatches() { - FunctionTestUtil.assertResult(replaceFunction.invoke("testString", "ttest", "ttt"), "testString"); - FunctionTestUtil.assertResult(replaceFunction.invoke("testString", "$test", "ttt"), "testString"); + void invokeInvalidRegExPattern() { + FunctionTestUtil.assertResultError(replaceFunction.invoke("testString", "(?=\\s)", "ttt"), InvalidParametersEvent.class); } @Test diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/XQueryImplUtilTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/XQueryImplUtilTest.java new file mode 100644 index 00000000000..6cc71d38a6a --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/XQueryImplUtilTest.java @@ -0,0 +1,117 @@ +/** + * 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 + * + * 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.kie.dmn.feel.util; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class XQueryImplUtilTest { + + @ParameterizedTest + @MethodSource("executeMatchesFunctionTestData") + void executeMatchesFunctionTest(String input, String pattern, String flags, boolean expected) { + assertThat(XQueryImplUtil.executeMatchesFunction(input, pattern, flags)).isEqualTo(expected); + } + + private static Object[][] executeMatchesFunctionTestData() { + return new Object[][] { + { "test", "^test", "i", true }, + { "fo\nbar", "o.b", null, false }, + { "TEST", "test", "i", true }, + }; + } + + @ParameterizedTest + @MethodSource("executeMatchesFunctionInvokingExceptionTestData") + void executeMatchesFunctionInvokingExceptionTest(String input, String pattern, String flags, + String exceptionMessage) { + assertThatThrownBy(() -> XQueryImplUtil.executeMatchesFunction(input, pattern, flags)) + .isInstanceOf(IllegalArgumentException.class).hasMessageContaining(exceptionMessage); + } + + private static Object[][] executeMatchesFunctionInvokingExceptionTestData() { + return new Object[][] { + { "test", "^test", "g", "Unrecognized flag" }, + { "test", "(?=\\s)", null, "No expression before quantifier" }, + { "test", "(.)\\2", "i", "invalid backreference \\2" }, + }; + } + + @ParameterizedTest + @MethodSource("executeReplaceFunctionTestData") + void executeReplaceFunctionTest(String input, String pattern, String replacement, String flags, String expected) { + assertThat(XQueryImplUtil.executeReplaceFunction(input, pattern, replacement, flags)).isEqualTo(expected); + } + + private static Object[][] executeReplaceFunctionTestData() { + return new Object[][] { + { "testString", "^test", "ttt", "", "tttString" }, + { "fo\nbar", "o.b", "ttt", "s", "ftttar" }, + }; + } + + @ParameterizedTest + @MethodSource("executeReplaceFunctionInvokingExceptionTestData") + void executeReplaceFunctionInvokingExceptionTest(String input, String pattern, String replacement, String flags, + Class expectedException, String exceptionMessage) { + assertThatThrownBy(() -> XQueryImplUtil.executeReplaceFunction(input, pattern, replacement, flags)) + .isInstanceOf(expectedException).hasMessageContaining(exceptionMessage); + } + + private static Object[][] executeReplaceFunctionInvokingExceptionTestData() { + return new Object[][] { + { "fo\nbar", "o.b", "ttt", "g", IllegalArgumentException.class, "Unrecognized flag" }, + { "test", "(?=\\s)", "ttt", null, IllegalArgumentException.class, "No expression before quantifier" }, + { "test", "(.)\\2", "ttt", null, IllegalArgumentException.class, "invalid backreference \\2" }, + }; + } + + @ParameterizedTest + @MethodSource("evaluateXQueryExpressionValidParametersTestData") + void evaluateXQueryExpressionValidParametersTest(String expression, Class returnTypeClass, Object expectedResult) { + assertThat(XQueryImplUtil.evaluateXQueryExpression(expression, returnTypeClass)).isEqualTo(expectedResult); + + } + + private static Object[][] evaluateXQueryExpressionValidParametersTestData() { + return new Object[][] { + { "matches('test', '^test', 'i')", Boolean.class, true }, + { "matches('fo\\nbar', 'o.b', '')", Boolean.class, false }, + { "replace('testString', '^test', 'ttt', '')", String.class, "tttString" } + }; + } + + @ParameterizedTest + @MethodSource("evaluateXQueryExpressionInvalidParametersTestData") + void evaluateXQueryExpressionInvalidParametersTest(String expression, Class returnTypeClass) { + assertThatThrownBy(() -> XQueryImplUtil.evaluateXQueryExpression(expression, returnTypeClass)) + .isInstanceOf(UnsupportedOperationException.class); + } + + private static Object[][] evaluateXQueryExpressionInvalidParametersTestData() { + return new Object[][] { + { "matches('test', '^test', 'i')", Integer.class }, + { "replace('testString', '^test', 'ttt', '')", Double.class }, + }; + } + +} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-pmml-tests-parent/kie-dmn-pmml-tests-trusty/pom.xml b/kie-dmn/kie-dmn-pmml-tests-parent/kie-dmn-pmml-tests-trusty/pom.xml index 8861992393d..126cfd4e4bf 100644 --- a/kie-dmn/kie-dmn-pmml-tests-parent/kie-dmn-pmml-tests-trusty/pom.xml +++ b/kie-dmn/kie-dmn-pmml-tests-parent/kie-dmn-pmml-tests-trusty/pom.xml @@ -152,6 +152,11 @@ test + + org.glassfish.jaxb + jaxb-runtime + + org.kie kie-dmn-validation @@ -188,19 +193,4 @@ - - - - jdk11 - - [11,) - - - - org.glassfish.jaxb - jaxb-runtime - - - - diff --git a/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/MultiInstanceDecisionLogic.java b/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/MultiInstanceDecisionLogic.java index d9a11187fc1..542b7c3ff91 100644 --- a/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/MultiInstanceDecisionLogic.java +++ b/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/MultiInstanceDecisionLogic.java @@ -55,6 +55,8 @@ import org.kie.dmn.feel.runtime.functions.SumFunction; import org.kie.dmn.feel.util.NumberEvalHelper; import org.kie.dmn.model.api.DMNElement.ExtensionElements; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static java.util.Collections.emptySet; import static java.util.Collections.singleton; @@ -63,6 +65,8 @@ @XStreamAlias("MultiInstanceDecisionLogic") public class MultiInstanceDecisionLogic { + private static Logger logger = LoggerFactory.getLogger(MultiInstanceDecisionLogic.class); + @XStreamAlias("iterationExpression") private String iterationExpression; @@ -132,6 +136,12 @@ public void compileEvaluator(DMNNode node, DMNCompilerImpl compiler, DMNCompiler di.setEvaluator(miEvaluator); compiler.addCallback((cCompiler, cCtx, cModel) -> { + if (cModel != model) { + if (logger.isDebugEnabled()) { + logger.debug("Skipping MID processing for imported model: {}", cModel.getName()); + } + return; + } MIDDependenciesProcessor processor = new MIDDependenciesProcessor(midl, cModel); addRequiredDecisions(miEvaluator, processor); removeChildElementsFromIndex(cModel, processor); diff --git a/kie-dmn/kie-dmn-signavio/src/test/java/org/kie/dmn/signavio/SignavioTest.java b/kie-dmn/kie-dmn-signavio/src/test/java/org/kie/dmn/signavio/SignavioTest.java index c9e77a9ab6e..e1088266a48 100644 --- a/kie-dmn/kie-dmn-signavio/src/test/java/org/kie/dmn/signavio/SignavioTest.java +++ b/kie-dmn/kie-dmn-signavio/src/test/java/org/kie/dmn/signavio/SignavioTest.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; @@ -37,6 +38,7 @@ import org.kie.dmn.api.core.DMNModel; import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.DMNRuntime; +import org.kie.dmn.api.core.ast.DMNNode; import org.kie.dmn.model.api.DRGElement; import org.kie.dmn.model.api.Definitions; import org.slf4j.Logger; @@ -50,17 +52,17 @@ public class SignavioTest { @Test void test() { DMNRuntime runtime = createRuntime("Test_Signavio_multiple.dmn"); - + List models = runtime.getModels(); - + DMNContext context = runtime.newContext(); context.set("persons", Arrays.asList("p1", "p2")); - + DMNModel model0 = models.get(0); LOG.info("EVALUATE ALL:"); DMNResult evaluateAll = runtime.evaluateAll(model0, context); LOG.info("{}", evaluateAll); - + assertThat((List) evaluateAll.getContext().get("Greeting for each Person in Persons")).contains("Hello p1", "Hello p2"); } @@ -142,14 +144,14 @@ private void checkSurveryMID(DMNRuntime runtime, Object numbers, Object iteratin assertThat(evaluateAll.getDecisionResultByName("iterating").getResult()).isEqualTo(iterating); } - private DMNRuntime createRuntime(String modelFileName) { - final KieServices ks = KieServices.Factory.get(); + private DMNRuntime createRuntime(String... modelFileNames) { + final KieServices ks = KieServices.get(); final KieFileSystem kfs = ks.newKieFileSystem(); KieModuleModel kmm = ks.newKieModuleModel(); kmm.setConfigurationProperty("org.kie.dmn.profiles.signavio", "org.kie.dmn.signavio.KieDMNSignavioProfile"); kfs.writeKModuleXML(kmm.toXML()); - kfs.write(ks.getResources().newClassPathResource(modelFileName, this.getClass())); + Arrays.stream(modelFileNames).forEachOrdered(f -> kfs.write(ks.getResources().newClassPathResource(f, getClass()))); KieBuilder kieBuilder = ks.newKieBuilder(kfs).buildAll(); Results results = kieBuilder.getResults(); @@ -214,21 +216,21 @@ void zipFunctions() { @SuppressWarnings("unchecked") void midTakesCareOfRequirements() { DMNRuntime runtime = createRuntime("Test_SignavioMID.dmn"); - + List models = runtime.getModels(); - + DMNContext context = runtime.newContext(); context.set("numbers1", Arrays.asList(1,2)); context.set("numbers2", Arrays.asList(2,3)); - + DMNModel model0 = models.get(0); LOG.info("EVALUATE ALL:"); DMNResult evaluateAll = runtime.evaluateAll(model0, context); LOG.info("{}", evaluateAll); - + List result = (List) evaluateAll.getDecisionResultByName("calculate").getResult(); assertThat(result).hasSize(6); - + assertThat(result).doesNotContainNull(); } @@ -236,12 +238,12 @@ void midTakesCareOfRequirements() { @Test void signavioConcatFunction() { DMNRuntime runtime = createRuntime("Signavio_Concat.dmn"); - + List models = runtime.getModels(); - + DMNContext context = runtime.newContext(); context.set("listOfNames", Arrays.asList("John", "Jane", "Doe")); - + DMNModel model0 = models.get(0); LOG.info("EVALUATE ALL:"); DMNResult evaluateAll = runtime.evaluateAll(model0, context); @@ -249,20 +251,20 @@ void signavioConcatFunction() { assertThat(evaluateAll.getDecisionResultByName("concatNames").getResult()).isEqualTo("JohnJaneDoe"); } - - + + private void checkBothFunctionsAreWorking(DMNRuntime runtime) { List models = runtime.getModels(); - + DMNContext context = runtime.newContext(); context.set("names", Arrays.asList("John Doe", "Jane Doe")); context.set("ages", Arrays.asList(37, 35)); - + DMNModel model0 = models.get(0); LOG.info("EVALUATE ALL:"); DMNResult evaluateAll = runtime.evaluateAll(model0, context); LOG.info("{}", evaluateAll); - + assertThat((List) evaluateAll.getDecisionResultByName("zipvararg").getResult()).hasSize(2); assertThat((List) evaluateAll.getDecisionResultByName("zipsinglelist").getResult()).hasSize(2); } @@ -270,7 +272,7 @@ private void checkBothFunctionsAreWorking(DMNRuntime runtime) { @Test void signavioIterateMultiinstanceWithComplexInputs() { DMNRuntime runtime = createRuntime("Iterate Complex List.dmn"); - + DMNContext context = runtime.newContext(); Map johnDoe = new HashMap<>(); johnDoe.put("iD", "id-john"); @@ -279,7 +281,7 @@ void signavioIterateMultiinstanceWithComplexInputs() { alice.put("iD", "id-alice"); alice.put("name", "Alice"); context.set("customer", Collections.singletonMap("persons", Arrays.asList(johnDoe, alice))); - + DMNModel model0 = runtime.getModels().get(0); LOG.info("EVALUATE ALL:"); DMNResult evaluateAll = runtime.evaluateAll(model0, context); @@ -291,31 +293,41 @@ void signavioIterateMultiinstanceWithComplexInputs() { @Test void signavioIterateMultiinstanceMultipleDecisions() { DMNRuntime runtime = createRuntime("MID with multiple inside decisions.dmn"); - + DMNContext context = runtime.newContext(); context.set("names", Arrays.asList("John", "Alice")); - + DMNModel model0 = runtime.getModels().get(0); LOG.info("EVALUATE ALL:"); DMNResult evaluateAll = runtime.evaluateAll(model0, context); LOG.info("{}", evaluateAll); - + assertThat(evaluateAll.getDecisionResultByName("overallage").getResult()).isEqualTo(new BigDecimal("18")); } @Test void signavioIterateMultiinstanceMultipleDecisionsOutside() { DMNRuntime runtime = createRuntime("MID with outside requirement.dmn"); - + DMNContext context = runtime.newContext(); context.set("numbers", Arrays.asList(1,2,3)); context.set("operand", "PLUS"); - + DMNModel model0 = runtime.getModels().get(0); LOG.info("EVALUATE ALL:"); DMNResult evaluateAll = runtime.evaluateAll(model0, context); LOG.info("{}", evaluateAll); - + assertThat(evaluateAll.getDecisionResultByName("sumUp").getResult()).isEqualTo(new BigDecimal("6")); } + + @Test + void signavioMultiInstanceDecisionTableWithinMultipleFiles() { + DMNRuntime dmnRuntime = createRuntime("MID with outside requirement.dmn", "survey MID SUM.dmn", "Signavio_Concat.dmn"); + + assertThat(dmnRuntime.getModels()) + .flatExtracting(DMNModel::getDecisions) + .extracting(DMNNode::getName) + .containsOnly("sumUp", "iterating", "determineModifier", "concatNames"); + } } diff --git a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/LocalHrefs.dmn b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/LocalHrefs.dmn index 33542ce25c3..dfc483e8c73 100644 --- a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/LocalHrefs.dmn +++ b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/LocalHrefs.dmn @@ -1,4 +1,23 @@ + + diff --git a/kie-pmml-trusty/kie-pmml-compiler/kie-pmml-compiler-api/pom.xml b/kie-pmml-trusty/kie-pmml-compiler/kie-pmml-compiler-api/pom.xml index bdbd389a054..e7921b7ce0e 100644 --- a/kie-pmml-trusty/kie-pmml-compiler/kie-pmml-compiler-api/pom.xml +++ b/kie-pmml-trusty/kie-pmml-compiler/kie-pmml-compiler-api/pom.xml @@ -53,6 +53,10 @@ org.jpmml pmml-model + + org.glassfish.jaxb + jaxb-runtime + org.kie @@ -74,20 +78,4 @@ - - - - java11-pmml - - [11,) - - - - org.glassfish.jaxb - jaxb-runtime - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index c23c483f355..5fae74ed325 100644 --- a/pom.xml +++ b/pom.xml @@ -136,7 +136,11 @@ .git-blame-ignore-revs + **/dependency-reduced-pom.xml **/lunr-2.3.9.min.js + **/search-ui.js + **/branch.yaml + **/main.yaml **/mvel.jj **/*.csv **/*.sdo @@ -159,7 +163,6 @@ **/*.log **/*.lst **/checkstyle-cachefile - **/smoke*.drl.txt **/test*.txt **/test*.yml **/drl.ftl