This is an automated email from the ASF dual-hosted git repository.
tkobayas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new 23ff9dc9ff [incubator-kie-drools-6007] Executable model doesn't report
an error when duplicated (#6013)
23ff9dc9ff is described below
commit 23ff9dc9ffc3c0bd7a8e91fd65af5ffc2d0d3d5f
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Wed Jul 10 10:10:35 2024 +0900
[incubator-kie-drools-6007] Executable model doesn't report an error when
duplicated (#6013)
* removing kie-ci from dependency, because it causes a test failure in
KieBaseIncludeTest
* Use canonicalKieModule.getKiePackages() rather than getKieBase()
* null check for kiePackage
* move populateIncludedRuleNameMap out of packages loop
* removed unused FileManager
* performance improvement. Use getModelForKBase instead of getKiePackages
* Fit into build phases
* clean up
---
.../kie/builder/impl/AbstractKieProject.java | 8 +-
.../compiler/kie/builder/impl/BuildContext.java | 13 ++
.../execmodel/CanonicalModelBuildContext.java | 14 ++
.../model/codegen/execmodel/ModelBuilderImpl.java | 3 +-
.../processors/ModelMainCompilationPhase.java | 18 +-
.../execmodel/processors/ModelRuleValidator.java | 64 +++++++
.../PopulateIncludedRuleNameMapPhase.java | 63 +++++++
.../drools/modelcompiler/CanonicalKieModule.java | 7 +-
.../mvel/integrationtests/KieBaseIncludesTest.java | 196 +++++++++++++++++++++
9 files changed, 380 insertions(+), 6 deletions(-)
diff --git
a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieProject.java
b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieProject.java
index 7d8c399bea..7775abacc4 100644
---
a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieProject.java
+++
b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieProject.java
@@ -225,6 +225,8 @@ public abstract class AbstractKieProject implements
KieProject {
Set<Asset> assets = new LinkedHashSet<>();
+ InternalKieModule kModule = getKieModuleForKBase(kBaseModel.getName());
+
boolean allIncludesAreValid = true;
for (String include : getTransitiveIncludes(kBaseModel)) {
if ( StringUtils.isEmpty( include )) {
@@ -240,6 +242,11 @@ public abstract class AbstractKieProject implements
KieProject {
}
if (compileIncludedKieBases()) {
addFiles( buildFilter, assets, getKieBaseModel( include ),
includeModule, useFolders );
+ } else {
+ if (kModule != includeModule) {
+ // includeModule is not part of the current kModule
+ buildContext.addIncludeModule(getKieBaseModel(include),
includeModule);
+ }
}
}
@@ -247,7 +254,6 @@ public abstract class AbstractKieProject implements
KieProject {
return null;
}
- InternalKieModule kModule = getKieModuleForKBase(kBaseModel.getName());
addFiles( buildFilter, assets, kBaseModel, kModule, useFolders );
KnowledgeBuilder kbuilder;
diff --git
a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/BuildContext.java
b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/BuildContext.java
index f9b564d774..2d731956ab 100644
---
a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/BuildContext.java
+++
b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/BuildContext.java
@@ -18,6 +18,11 @@
*/
package org.drools.compiler.kie.builder.impl;
+import java.util.Collections;
+import java.util.Map;
+
+import org.kie.api.builder.model.KieBaseModel;
+
public class BuildContext {
private final ResultsImpl messages;
@@ -36,4 +41,12 @@ public class BuildContext {
public boolean registerResourceToBuild(String kBaseName, String resource) {
return true;
}
+
+ public void addIncludeModule(KieBaseModel kieBaseModel, InternalKieModule
includeModule) {
+ // no op
+ }
+
+ public Map<KieBaseModel, InternalKieModule> getIncludeModules() {
+ return Collections.emptyMap();
+ }
}
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/CanonicalModelBuildContext.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/CanonicalModelBuildContext.java
index ddf51f164a..3b019df967 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/CanonicalModelBuildContext.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/CanonicalModelBuildContext.java
@@ -26,7 +26,9 @@ import java.util.Map;
import java.util.Set;
import org.drools.compiler.kie.builder.impl.BuildContext;
+import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.drools.compiler.kie.builder.impl.ResultsImpl;
+import org.kie.api.builder.model.KieBaseModel;
public class CanonicalModelBuildContext extends BuildContext {
@@ -36,6 +38,8 @@ public class CanonicalModelBuildContext extends BuildContext {
private final Collection<GeneratedClassWithPackage> allGeneratedPojos =
new HashSet<>();
private final Map<String, Class<?>> allCompiledClasses = new HashMap<>();
+ private final Map<KieBaseModel, InternalKieModule> includeModules = new
HashMap<>();
+
public CanonicalModelBuildContext() { }
public CanonicalModelBuildContext(ResultsImpl messages) {
@@ -84,4 +88,14 @@ public class CanonicalModelBuildContext extends BuildContext
{
int pathEndPos = resource.lastIndexOf('/');
return pathEndPos <= 0 ? "" :resource.substring(0,
pathEndPos).replace('/', '.');
}
+
+ @Override
+ public void addIncludeModule(KieBaseModel kieBaseModel, InternalKieModule
includeModule) {
+ includeModules.put(kieBaseModel, includeModule);
+ }
+
+ @Override
+ public Map<KieBaseModel, InternalKieModule> getIncludeModules() {
+ return includeModules;
+ }
}
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/ModelBuilderImpl.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/ModelBuilderImpl.java
index 6c9df9af3f..a962272417 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/ModelBuilderImpl.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/ModelBuilderImpl.java
@@ -108,7 +108,8 @@ public class ModelBuilderImpl<T extends PackageSources>
extends KnowledgeBuilder
this.getGlobalVariableContext(),
this.sourcesGenerator,
this.packageSources,
- oneClassPerRule));
+ oneClassPerRule,
+ this.getBuildContext()));
for (CompilationPhase phase : phases) {
phase.process();
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelMainCompilationPhase.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelMainCompilationPhase.java
index c66d6e2fc0..8485df83da 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelMainCompilationPhase.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelMainCompilationPhase.java
@@ -20,7 +20,10 @@ package org.drools.model.codegen.execmodel.processors;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.function.Function;
import org.drools.compiler.builder.PackageRegistryManager;
@@ -33,9 +36,9 @@ import
org.drools.compiler.builder.impl.processors.CompilationPhase;
import org.drools.compiler.builder.impl.processors.FunctionCompilationPhase;
import org.drools.compiler.builder.impl.processors.GlobalCompilationPhase;
import org.drools.compiler.builder.impl.processors.IteratingPhase;
-import org.drools.compiler.builder.impl.processors.RuleValidator;
import org.drools.compiler.builder.impl.processors.SinglePackagePhaseFactory;
import
org.drools.compiler.builder.impl.processors.WindowDeclarationCompilationPhase;
+import org.drools.compiler.kie.builder.impl.BuildContext;
import org.drools.compiler.lang.descr.CompositePackageDescr;
import org.drools.kiesession.rulebase.InternalKnowledgeBase;
import org.drools.model.codegen.execmodel.PackageModel;
@@ -61,6 +64,8 @@ public class ModelMainCompilationPhase<T> implements
CompilationPhase {
private final PackageSourceManager<T> packageSourceManager;
private final boolean oneClassPerRule;
+ private final BuildContext buildContext;
+
public ModelMainCompilationPhase(
PackageModelManager packageModels,
PackageRegistryManager pkgRegistryManager,
@@ -69,7 +74,11 @@ public class ModelMainCompilationPhase<T> implements
CompilationPhase {
boolean hasMvel,
InternalKnowledgeBase kBase,
TypeDeclarationContext typeDeclarationContext,
- GlobalVariableContext globalVariableContext,
Function<PackageModel, T> sourceGenerator, PackageSourceManager<T>
packageSourceManager, boolean oneClassPerRule) {
+ GlobalVariableContext globalVariableContext,
+ Function<PackageModel, T> sourceGenerator,
+ PackageSourceManager<T> packageSourceManager,
+ boolean oneClassPerRule,
+ BuildContext buildContext) {
this.packageModels = packageModels;
this.pkgRegistryManager = pkgRegistryManager;
this.packages = packages;
@@ -81,6 +90,7 @@ public class ModelMainCompilationPhase<T> implements
CompilationPhase {
this.sourceGenerator = sourceGenerator;
this.packageSourceManager = packageSourceManager;
this.oneClassPerRule = oneClassPerRule;
+ this.buildContext = buildContext;
}
@Override
@@ -94,7 +104,9 @@ public class ModelMainCompilationPhase<T> implements
CompilationPhase {
phases.add(iteratingPhase((reg, acc) -> GlobalCompilationPhase.of(reg,
acc, kBase, globalVariableContext, acc.getFilter())));
phases.add(new DeclaredTypeDeregistrationPhase(packages,
pkgRegistryManager));
- phases.add(iteratingPhase((reg, acc) -> new RuleValidator(reg, acc,
configuration))); // validateUniqueRuleNames
+ Map<String, Set<String>> includedRuleNameMap = new HashMap<>();
+ phases.add(new
PopulateIncludedRuleNameMapPhase(buildContext.getIncludeModules(),
includedRuleNameMap));
+ phases.add(iteratingPhase((reg, acc) -> new ModelRuleValidator(reg,
acc, configuration, includedRuleNameMap))); // validateUniqueRuleNames
phases.add(iteratingPhase((reg, acc) -> new ModelGeneratorPhase(reg,
acc, packageModels.getPackageModel(acc, reg, acc.getName()),
typeDeclarationContext))); // validateUniqueRuleNames
phases.add(iteratingPhase((reg, acc) -> new
SourceCodeGenerationPhase<>(
packageModels.getPackageModel(acc, reg, acc.getName()),
packageSourceManager, sourceGenerator, oneClassPerRule))); //
validateUniqueRuleNames
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelRuleValidator.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelRuleValidator.java
new file mode 100644
index 0000000000..b4bc7a9ce7
--- /dev/null
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelRuleValidator.java
@@ -0,0 +1,64 @@
+/**
+ * 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.processors;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.drools.compiler.builder.impl.processors.RuleValidator;
+import org.drools.compiler.compiler.PackageRegistry;
+import org.drools.drl.ast.descr.PackageDescr;
+import org.drools.drl.ast.descr.RuleDescr;
+import org.drools.drl.parser.ParserError;
+import org.kie.internal.builder.KnowledgeBuilderConfiguration;
+
+public class ModelRuleValidator extends RuleValidator {
+
+ // extra rule names which need to be checked for duplicates.
+ // Non-executable model doesn't need this because included kbase assets
are added to the packageDescr
+ // Executable model requires this because included kbase assets are
modeled as separated kjar, so not added to the packageDescr
+ private final Map<String, Set<String>> includedRuleNameMap;
+
+ public ModelRuleValidator(PackageRegistry pkgRegistry, PackageDescr
packageDescr, KnowledgeBuilderConfiguration configuration, Map<String,
Set<String>> includedRuleNameMap) {
+ super(pkgRegistry, packageDescr, configuration);
+ this.includedRuleNameMap = includedRuleNameMap;
+ }
+
+ @Override
+ public void process() {
+ super.process();
+
+ // Check with included rule names, because exec-model doesn't add
assets of included kbase to the packageDescr
+ String packageName = packageDescr.getNamespace();
+ if (includedRuleNameMap.containsKey(packageName)) {
+ Set<String> ruleNames = includedRuleNameMap.get(packageName);
+ for (final RuleDescr rule : packageDescr.getRules()) {
+ final String name = rule.getUnitQualifiedName();
+ if (ruleNames.contains(name)) {
+ this.results.add(new ParserError(rule.getResource(),
+ "Duplicate rule name: " + name,
+ rule.getLine(),
+ rule.getColumn(),
+ packageName));
+ }
+ }
+ }
+ }
+}
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/PopulateIncludedRuleNameMapPhase.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/PopulateIncludedRuleNameMapPhase.java
new file mode 100644
index 0000000000..ea66ed29ec
--- /dev/null
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/PopulateIncludedRuleNameMapPhase.java
@@ -0,0 +1,63 @@
+/**
+ * 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.processors;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.drools.compiler.builder.impl.processors.CompilationPhase;
+import org.drools.compiler.kie.builder.impl.InternalKieModule;
+import org.drools.compiler.kproject.models.KieBaseModelImpl;
+import org.drools.model.Model;
+import org.drools.modelcompiler.CanonicalKieModule;
+import org.kie.api.builder.model.KieBaseModel;
+import org.kie.internal.builder.KnowledgeBuilderResult;
+
+public class PopulateIncludedRuleNameMapPhase implements CompilationPhase {
+
+ private final Map<KieBaseModel, InternalKieModule> includeModules;
+ private final Map<String, Set<String>> includedRuleNameMap;
+
+ public PopulateIncludedRuleNameMapPhase(Map<KieBaseModel,
InternalKieModule> includeModules, Map<String, Set<String>>
includedRuleNameMap) {
+ this.includeModules = includeModules;
+ this.includedRuleNameMap = includedRuleNameMap;
+ }
+
+ @Override
+ public void process() {
+ for (Map.Entry<KieBaseModel, InternalKieModule> entry :
includeModules.entrySet()) {
+ KieBaseModel kieBaseModel = entry.getKey();
+ InternalKieModule includeModule = entry.getValue();
+ if ((includeModule instanceof CanonicalKieModule
canonicalKieModule) && canonicalKieModule.hasModelFile()) {
+ Collection<Model> includeModels =
canonicalKieModule.getModelForKBase((KieBaseModelImpl)kieBaseModel);
+ for (Model includeModel : includeModels) {
+ includeModel.getRules().forEach(rule ->
includedRuleNameMap.computeIfAbsent(includeModel.getPackageName(), k -> new
HashSet<>()).add(rule.getName()));
+ }
+ }
+ }
+ }
+
+ @Override
+ public Collection<? extends KnowledgeBuilderResult> getResults() {
+ return Collections.emptyList();
+ }
+}
diff --git
a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/CanonicalKieModule.java
b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/CanonicalKieModule.java
index f5c4ddb66f..f64be9e425 100644
---
a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/CanonicalKieModule.java
+++
b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/CanonicalKieModule.java
@@ -466,7 +466,7 @@ public class CanonicalKieModule implements
InternalKieModule {
return ruleClassesNames;
}
- private Collection<Model> getModelForKBase(KieBaseModelImpl kBaseModel) {
+ public Collection<Model> getModelForKBase(KieBaseModelImpl kBaseModel) {
Map<String, Model> modelsMap = getModels();
if (kBaseModel.getPackages().isEmpty()) {
return modelsMap.values();
@@ -484,6 +484,11 @@ public class CanonicalKieModule implements
InternalKieModule {
return models;
}
+ // This method indicates if the kjar was already compiled with the
executable model
+ public boolean hasModelFile() {
+ return
resourceFileExists(getModelFileWithGAV(internalKieModule.getReleaseId()));
+ }
+
private Collection<String> findRuleClassesNames() {
ReleaseId releaseId = internalKieModule.getReleaseId();
String modelFiles =
readExistingResourceWithName(getModelFileWithGAV(releaseId));
diff --git
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/KieBaseIncludesTest.java
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/KieBaseIncludesTest.java
index e9b358f02d..f68ac7bcfa 100644
---
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/KieBaseIncludesTest.java
+++
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/KieBaseIncludesTest.java
@@ -18,7 +18,9 @@
*/
package org.drools.mvel.integrationtests;
+import java.io.IOException;
import java.util.Collection;
+import java.util.List;
import org.drools.testcoverage.common.util.KieBaseTestConfiguration;
import org.drools.testcoverage.common.util.KieUtil;
@@ -28,11 +30,14 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
+import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
+import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.definition.KiePackage;
import org.kie.api.definition.rule.Rule;
import org.kie.api.runtime.KieContainer;
+import org.kie.api.runtime.KieSession;
import static org.assertj.core.api.Assertions.assertThat;
@@ -243,4 +248,195 @@ public class KieBaseIncludesTest {
}
return nrOfRules;
}
+
+ /**
+ * Test the inclusion of a KieBase defined in one KJAR into the KieBase of
another KJAR.
+ * <p/>
+ * The 2 KieBases use the duplicate rule names, so an error should be
reported
+ */
+ @Test
+ public void kieBaseIncludesCrossKJarDuplicateRuleNames_shouldReportError()
throws IOException {
+
+ String pomContentMain = "<project
xmlns=\"http://maven.apache.org/POM/4.0.0\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
+ "<modelVersion>4.0.0</modelVersion>\n" +
+ "<groupId>org.kie</groupId>\n" +
+ "<artifactId>rules-main</artifactId>\n" +
+ "<version>1.0.0</version>\n" +
+ "<packaging>jar</packaging>\n" +
+ "<dependencies>\n" +
+ "<dependency>\n" +
+ "<groupId>org.kie</groupId>\n" +
+ "<artifactId>rules-sub</artifactId>\n" +
+ "<version>1.0.0</version>\n" +
+ "</dependency>\n" +
+ "</dependencies>\n" +
+ "</project>\n";
+
+ String kmoduleContentMain = "<?xml version=\"1.0\"
encoding=\"UTF-8\"?>\n" +
+ "<kmodule xmlns=\"http://jboss.org/kie/6.0.0/kmodule\">\n" +
+ "<kbase name=\"kbaseMain\" equalsBehavior=\"equality\"
default=\"true\" packages=\"rules\" includes=\"kbaseSub\">\n" +
+ "<ksession name=\"ksessionMain\" default=\"true\"
type=\"stateful\"/>\n" +
+ "</kbase>\n" +
+ "</kmodule>";
+
+ String drlMain = "package rules\n" +
+ "\n" +
+ "rule \"RuleA\"\n" +
+ "when\n" +
+ "then\n" +
+ "System.out.println(\"Rule in KieBaseMain\");\n" +
+ "end";
+
+ String kmoduleContentSub = "<?xml version=\"1.0\"
encoding=\"UTF-8\"?>\n" +
+ "<kmodule xmlns=\"http://jboss.org/kie/6.0.0/kmodule\">\n" +
+ "<kbase name=\"kbaseSub\" equalsBehavior=\"equality\"
default=\"false\" packages=\"rules\">\n" +
+ "<ksession name=\"ksessionSub\" default=\"false\"
type=\"stateful\"/>\n" +
+ "</kbase>\n" +
+ "</kmodule>";
+
+ String drlSub = "package rules\n" +
+ "\n" +
+ "rule \"RuleA\"\n" +
+ "when\n" +
+ "then\n" +
+ "System.out.println(\"Rule in KieBaseSub\");\n" +
+ "end";
+
+ KieServices ks = KieServices.Factory.get();
+ ReleaseId releaseIdSub = ks.newReleaseId("org.kie", "rules-sub",
"1.0.0");
+
+ //First deploy the second KJAR on which the first one depends.
+ KieFileSystem kfsSub = ks.newKieFileSystem()
+ .generateAndWritePomXML(releaseIdSub)
+ .write("src/main/resources/rules/rules.drl", drlSub)
+ .writeKModuleXML(kmoduleContentSub);
+
+ KieUtil.getKieBuilderFromKieFileSystem(kieBaseTestConfiguration,
kfsSub, true);
+
+ KieFileSystem kfsMain = ks.newKieFileSystem()
+ .writePomXML(pomContentMain)
+ .write("src/main/resources/rules/rules.drl", drlMain)
+ .writeKModuleXML(kmoduleContentMain);
+
+ KieBuilder kieBuilderMain =
KieUtil.getKieBuilderFromKieFileSystem(kieBaseTestConfiguration, kfsMain,
false);
+ List<Message> messages =
kieBuilderMain.getResults().getMessages(Message.Level.ERROR);
+
+ assertThat(messages).as("Duplication error should be reported")
+ .extracting(Message::getText).anyMatch(text ->
text.contains("Duplicate rule name"));
+ }
+
+ /**
+ * One KieBase that includes another KieBase from the same KJAR. Not
duplicate names.
+ */
+ @Test
+ public void kieBaseIncludesSameKJar() {
+
+ String pomContent = "<project
xmlns=\"http://maven.apache.org/POM/4.0.0\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
+ "<modelVersion>4.0.0</modelVersion>\n" +
+ "<groupId>org.kie</groupId>\n" +
+ "<artifactId>rules-main-sub</artifactId>\n" +
+ "<version>1.0.0</version>\n" +
+ "<packaging>jar</packaging>\n" +
+ "</project>\n";
+
+ String kmoduleContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+
+ "<kmodule xmlns=\"http://jboss.org/kie/6.0.0/kmodule\">\n" +
+ "<kbase name=\"kbaseSub\" equalsBehavior=\"equality\"
default=\"false\" packages=\"rules.sub\">\n" +
+ "</kbase>\n" +
+ "<kbase name=\"kbaseMain\" equalsBehavior=\"equality\"
default=\"true\" packages=\"rules.main\" includes=\"kbaseSub\">\n" +
+ "<ksession name=\"ksessionMain\" default=\"true\"
type=\"stateful\"/>\n" +
+ "</kbase>\n" +
+ "</kmodule>";
+
+ String drlMain = "package rules.main\n" +
+ "\n" +
+ "rule \"RuleA\"\n" +
+ "when\n" +
+ " $s : String()\n" +
+ "then\n" +
+ " System.out.println(\"Rule in KieBaseMain\");\n" +
+ "end";
+
+ String drlSub = "package rules.sub\n" +
+ "\n" +
+ "rule \"RuleB\"\n" +
+ "when\n" +
+ " $s : String()\n" +
+ "then\n" +
+ " System.out.println(\"Rule in KieBaseSub\");\n" +
+ "end";
+
+ KieServices ks = KieServices.Factory.get();
+
+ KieFileSystem kfsMain = ks.newKieFileSystem()
+ .writePomXML(pomContent)
+ .write("src/main/resources/rules/main/ruleMain.drl", drlMain)
+ .write("src/main/resources/rules/sub/ruleSub.drl", drlSub)
+ .writeKModuleXML(kmoduleContent);
+
+ KieUtil.getKieBuilderFromKieFileSystem(kieBaseTestConfiguration,
kfsMain, true);
+ ReleaseId releaseId = ks.newReleaseId("org.kie", "rules-main-sub",
"1.0.0");
+ KieContainer kieContainer = ks.newKieContainer(releaseId);
+ KieSession kieSession = kieContainer.newKieSession("ksessionMain");
+ kieSession.insert("test");
+ int fired = kieSession.fireAllRules();
+ assertThat(fired).as("fire rules in main and sub").isEqualTo(2);
+ kieSession.dispose();
+ }
+
+ /**
+ * One KieBase that includes another KieBase from the same KJAR. Duplicate
rule names.
+ */
+ @Test
+ public void kieBaseIncludesSameKJarDuplicateRuleNames_shouldReportError() {
+
+ String pomContent = "<project
xmlns=\"http://maven.apache.org/POM/4.0.0\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
+ "<modelVersion>4.0.0</modelVersion>\n" +
+ "<groupId>org.kie</groupId>\n" +
+ "<artifactId>rules-main-sub</artifactId>\n" +
+ "<version>1.0.0</version>\n" +
+ "<packaging>jar</packaging>\n" +
+ "</project>\n";
+
+ String kmoduleContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+
+ "<kmodule xmlns=\"http://jboss.org/kie/6.0.0/kmodule\">\n" +
+ "<kbase name=\"kbaseSub\" equalsBehavior=\"equality\"
default=\"false\" packages=\"rules\">\n" +
+ "</kbase>\n" +
+ "<kbase name=\"kbaseMain\" equalsBehavior=\"equality\"
default=\"true\" packages=\"rules\" includes=\"kbaseSub\">\n" +
+ "<ksession name=\"ksessionMain\" default=\"true\"
type=\"stateful\"/>\n" +
+ "</kbase>\n" +
+ "</kmodule>";
+
+ String drlMain = "package rules\n" +
+ "\n" +
+ "rule \"RuleA\"\n" +
+ "when\n" +
+ " $s : String()\n" +
+ "then\n" +
+ " System.out.println(\"Rule in KieBaseMain\");\n" +
+ "end";
+
+ String drlSub = "package rules\n" + // same package, same rule name
+ "\n" +
+ "rule \"RuleA\"\n" +
+ "when\n" +
+ " $s : String()\n" +
+ "then\n" +
+ " System.out.println(\"Rule in KieBaseSub\");\n" +
+ "end";
+
+ KieServices ks = KieServices.Factory.get();
+
+ KieFileSystem kfsMain = ks.newKieFileSystem()
+ .writePomXML(pomContent)
+ .write("src/main/resources/rules/main/ruleMain.drl", drlMain)
+ .write("src/main/resources/rules/sub/ruleSub.drl", drlSub)
+ .writeKModuleXML(kmoduleContent);
+
+ KieBuilder kieBuilderMain =
KieUtil.getKieBuilderFromKieFileSystem(kieBaseTestConfiguration, kfsMain,
false);
+ List<Message> messages =
kieBuilderMain.getResults().getMessages(Message.Level.ERROR);
+
+ assertThat(messages).as("Duplication error should be reported")
+ .extracting(Message::getText).anyMatch(text ->
text.contains("Duplicate rule name"));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]