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]

Reply via email to