[[_kieexamplessection]]
= Build, Deploy and Utilize Examples


The best way to learn the new build system is by example.
The source project "drools-examples-api" contains a number of examples, and can be found at GitHub:

https://github.com/kiegroup/drools/tree/main/drools-examples-api

Each example is described below, the order starts with the simplest (most of the options are defaulted) and working its way up to more complex use cases.

The Deploy use cases shown below all involve ``mvn install``.
Remote deployment of JARs in Maven is well covered in Maven literature.
Utilize refers to the initial act of loading the resources and providing access to the KIE runtimes.
Whereas Run refers to the act of interacting with those runtimes.

== Default KieSession

* Project: default-kesession.
* Summary: Empty kmodule.xml KieModule on the classpath that includes all resources in a single default KieBase. The example shows the retrieval of the default KieSession from the classpath.


An empty kmodule.xml will produce a single KieBase that includes all files found under resources path, be it DRL, BPMN2, XLS etc.
That single KieBase is the default and also includes a single default KieSession.
Default means they can be created without knowing their names.

.Author - kmodule.xml
====
[source,xml]
----

<kmodule xmlns="http://www.drools.org/xsd/kmodule"> </kmodule>
----
====

.Build and Install - Maven
====
[source]
----
mvn install
----
====


ks.getKieClasspathContainer() returns the KieContainer that contains the KieBases deployed onto the environment classpath.
kContainer.newKieSession() creates the default KieSession.
Notice that you no longer need to look up the KieBase, in order to create the KieSession.
The KieSession knows which KieBase it's associated with, and use that, which in this case is the default KieBase.

.Utilize and Run - Java
====
[source,java]
----

KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();

KieSession kSession = kContainer.newKieSession();
kSession.setGlobal("out", out);
kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();
----
====




== Named KieSession

* Project: named-kiesession.
* Summary: kmodule.xml that has one named KieBase and one named KieSession. The examples shows the retrieval of the named KieSession from the classpath.


kmodule.xml will produce a single named KieBase, 'kbase1' that includes all files found under resources path, be it DRL, BPMN2, XLS etc.
KieSession 'ksession1' is associated with that KieBase and can be created by name.

.Author - kmodule.xml
====
[source,xml]
----
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="kbase1">
        <ksession name="ksession1"/>
    </kbase>
</kmodule>
----
====

.Build and Install - Maven
====
[source]
----
mvn install
----
====


ks.getKieClasspathContainer() returns the KieContainer that contains the KieBases deployed onto the environment classpath.
This time the KieSession uses the name 'ksession1'. You do not need to lookup the KieBase first, as it knows which KieBase 'ksession1' is assocaited with.

.Utilize and Run - Java
====
[source,java]
----
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();

KieSession kSession = kContainer.newKieSession("ksession1");
kSession.setGlobal("out", out);
kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();
----
====

== KieBase Inheritance

* Project: kiebase-inclusion.
* Summary: 'kmodule.xml' demonstrates that one KieBase can include the resources from another KieBase, from another KieModule. In this case it inherits the named KieBase from the 'name-kiesession' example. The included KieBase can be from the current KieModule or any other KieModule that is in the pom.xml dependency list.


kmodule.xml will produce a single named KieBase, 'kbase2' that includes all files found under resources path, be it DRL, BPMN2, XLS etc.
Further it will include all the resources found from the KieBase 'kbase1', due to the use of the 'includes' attribute.
KieSession 'ksession2' is associated with that KieBase and can be created by name.

.Author - kmodule.xml
====
[source,xml]
----
<kbase name="kbase2" includes="kbase1">
    <ksession name="ksession2"/>
</kbase>
----
====


This example requires that the previous example, 'named-kiesession', is built and installed to the local Maven repository first.
Once installed it can be included as a dependency, using the standard Maven <dependencies> element.

.Author - pom.xml
====
[source,xml]
----
<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">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.drools</groupId>
    <artifactId>drools-examples-api</artifactId>
    <version>6.0.0/version>
  </parent>

  <artifactId>kiebase-inclusion</artifactId>
  <name>Drools API examples - KieBase Inclusion</name>

  <dependencies>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-compiler</artifactId>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>named-kiesession</artifactId>
      <version>6.0.0</version>
    </dependency>
  </dependencies>

</project>
----
====


Once 'named-kiesession' is built and installed this example can be built and installed as normal.
Again the act of installing, will force the unit tests to run, demonstrating the use case.

.Build and Install - Maven
====
[source]
----
mvn install
----
====


ks.getKieClasspathContainer() returns the KieContainer that contains the KieBases deployed onto the environment classpath.
This time the KieSession uses the name 'ksession2'. You do not need to lookup the KieBase first, as it knows which KieBase 'ksession1' is assocaited with.
Notice two rules fire this time, showing that KieBase 'kbase2' has included the resources from the dependency KieBase 'kbase1'.

.Utilize and Run - Java
====
[source,java]
----
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession2");
kSession.setGlobal("out", out);

kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();

kSession.insert(new Message("Dave", "Open the pod bay doors, HAL."));
kSession.fireAllRules();
----
====

== Multiple KieBases

* Project: 'multiple-kbases.
* Summary: Demonstrates that the 'kmodule.xml'  can contain any number of KieBase or KieSession declarations. Introduces the 'packages' attribute to select the folders for the resources to be included in the KieBase.


kmodule.xml produces 6 different named KieBases.
'kbase1' includes all resources from the KieModule.
The other KieBases include resources from other selected folders, via the 'packages' attribute.
Note the use of wildcard '*', to select this package and all packages below it. 

.Author - kmodule.xml
====
[source,xml]
----
<kmodule xmlns="http://www.drools.org/xsd/kmodule">

  <kbase name="kbase1">
    <ksession name="ksession1"/>
  </kbase>

  <kbase name="kbase2" packages="org.some.pkg">
    <ksession name="ksession2"/>
  </kbase>

  <kbase name="kbase3" includes="kbase2" packages="org.some.pkg2">
    <ksession name="ksession3"/>
  </kbase>

  <kbase name="kbase4" packages="org.some.pkg, org.other.pkg">
    <ksession name="ksession4"/>
  </kbase>

  <kbase name="kbase5" packages="org.*">
    <ksession name="ksession5"/>
  </kbase>

  <kbase name="kbase6" packages="org.some.*">
    <ksession name="ksession6"/>
  </kbase>
</kmodule>
----
====

.Build and Install - Maven
====
[source]
----
mvn install
----
====


Only part of the example is included below, as there is a test method per KieSession, but each one is a repetition of the other, with different list expectations.

.Utilize and Run - Java
====
[source,java]
----
@Test
public void testSimpleKieBase() {
    List<Integer> list = useKieSession("ksession1");
    // no packages imported means import everything
    assertEquals(4, list.size());
    assertTrue( list.containsAll( asList(0, 1, 2, 3) ) );
}

//.. other tests for ksession2 to ksession6 here

private List<Integer> useKieSession(String name) {
    KieServices ks = KieServices.Factory.get();
    KieContainer kContainer = ks.getKieClasspathContainer();
    KieSession kSession = kContainer.newKieSession(name);

    List<Integer> list = new ArrayList<Integer>();
    kSession.setGlobal("list", list);
    kSession.insert(1);
    kSession.fireAllRules();

    return list;
}
----
====

== KieContainer from KieRepository

* Project: kcontainer-from-repository
* Summary: The project does not contain a kmodule.xml, nor does the pom.xml have any dependencies for other KieModules. Instead the Java code demonstrates the loading of a dynamic KieModule from a Maven repository. 


The pom.xml must include kie-ci as a dependency, to ensure Maven is available at runtime.
As this uses Maven under the hood you can also use the standard Maven settings.xml file.

.Author - pom.xml
====
[source,xml]
----
<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">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.drools</groupId>
    <artifactId>drools-examples-api</artifactId>
    <version>6.0.0</version>
  </parent>

  <artifactId>kiecontainer-from-kierepo</artifactId>
  <name>Drools API examples - KieContainer from KieRepo</name>

  <dependencies>
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-ci</artifactId>
    </dependency>
  </dependencies>

</project>
----
====

.Build and Install - Maven
====
[source]
----
mvn install
----
====


In the previous examples the classpath KieContainer used.
This example creates a dynamic KieContainer as specified by the  ReleaseId.
The ReleaseId uses Maven conventions for group id, artifact id and version.
It also obeys LATEST and SNAPSHOT for versions.

.Utilize and Run - Java
====
[source,java]
----
KieServices ks = KieServices.Factory.get();

// Install example1 in the local Maven repo before to do this
KieContainer kContainer = ks.newKieContainer(ks.newReleaseId("org.drools", "named-kiesession", "6.0.0-SNAPSHOT"));

KieSession kSession = kContainer.newKieSession("ksession1");
kSession.setGlobal("out", out);

Object msg1 = createMessage(kContainer, "Dave", "Hello, HAL. Do you read me, HAL?");
kSession.insert(msg1);
kSession.fireAllRules();
----
====

== Default KieSession from File

* Project: default-kiesession-from-file
* Summary: Dynamic KieModules can also be loaded from any Resource location. The loaded KieModule provides default KieBase and KieSession definitions.


No kmodue.xml file exists.
The project 'default-kiesession' must be built first, so that the resulting JAR, in the target folder, can be referenced as a File.

.Build and Install - Maven
====
[source]
----
mvn install
----
====


Any KieModule can be loaded from a Resource location and added to the KieRepository.
Once deployed in the KieRepository it can be resolved via its ReleaseId.
Note neither Maven or kie-ci are needed here.
It will not set up a transitive dependency parent classloader.

.Utilize and Run - Java
====
[source,java]
----
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();

KieModule kModule = kr.addKieModule(ks.getResources().newFileSystemResource(getFile("default-kiesession")));

KieContainer kContainer = ks.newKieContainer(kModule.getReleaseId());

KieSession kSession = kContainer.newKieSession();
kSession.setGlobal("out", out);

Object msg1 = createMessage(kContainer, "Dave", "Hello, HAL. Do you read me, HAL?");
kSession.insert(msg1);
kSession.fireAllRules();
----
====

== Named KieSession from File

* Project: named-kiesession-from-file
* Summary: Dynamic KieModules can also be loaded from any Resource location. The loaded KieModule provides named KieBase and KieSession definitions.


No kmodue.xml file exists.
The project 'named-kiesession' must be built first, so that the resulting JAR, in the target folder, can be referenced as a File.

.Build and Install - Maven
====
[source]
----
mvn install
----
====


Any KieModule can be loaded from a Resource location and added to the KieRepository.
Once in the KieRepository it can be resolved via its ReleaseId.
Note neither Maven or kie-ci are needed here.
It will not setup a transitive dependency parent classloader.

.Utilize and Run - Java
====
[source,java]
----
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();

KieModule kModule = kr.addKieModule(ks.getResources().newFileSystemResource(getFile("named-kiesession")));

KieContainer kContainer = ks.newKieContainer(kModule.getReleaseId());

KieSession kSession = kContainer.newKieSession("ksession1");
kSession.setGlobal("out", out);

Object msg1 = createMessage(kContainer, "Dave", "Hello, HAL. Do you read me, HAL?");
kSession.insert(msg1);
kSession.fireAllRules();
----
====

== KieModule with Dependent KieModule

* Project: kie-module-form-multiple-files
* Summary: Programmatically provide the list of dependant KieModules, without using Maven to resolve anything.


No kmodue.xml file exists.
The projects 'named-kiesession' and 'kiebase-include' must be built first, so that the resulting JARs, in the target folders, can be referenced as Files.

.Build and Install - Maven
====
[source]
----
mvn install
----
====


Creates two resources.
One is for the main KieModule 'exRes1' the other is for the dependency 'exRes2'. Even though kie-ci is not present and thus Maven is not available to resolve the dependencies, this shows how you can manually specify the dependent KieModules, for the vararg.

.Utilize and Run - Java
====
[source,java]
----
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();

Resource ex1Res = ks.getResources().newFileSystemResource(getFile("kiebase-inclusion"));
Resource ex2Res = ks.getResources().newFileSystemResource(getFile("named-kiesession"));

KieModule kModule = kr.addKieModule(ex1Res, ex2Res);
KieContainer kContainer = ks.newKieContainer(kModule.getReleaseId());

KieSession kSession = kContainer.newKieSession("ksession2");
kSession.setGlobal("out", out);

Object msg1 = createMessage(kContainer, "Dave", "Hello, HAL. Do you read me, HAL?");
kSession.insert(msg1);
kSession.fireAllRules();

Object msg2 = createMessage(kContainer, "Dave", "Open the pod bay doors, HAL.");
kSession.insert(msg2);
kSession.fireAllRules();
----
====

== Programmatically build a Simple KieModule with Defaults

* Project: kiemoduelmodel-example
* Summary: Programmatically build a KieModule from just a single file. The POM and models are all defaulted. This is the quickest out of the box approach, but should not be added to a Maven repository.


.Build and Install - Maven
====
[source]
----
mvn install
----
====


This programmatically builds a KieModule.
It populates the model that represents the ReleaseId and  kmodule.xml, and it adds the relevant resources.
A pom.xml is generated from the ReleaseId.

.Utilize and Run - Java
====
[source,java]
----
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();
KieFileSystem kfs = ks.newKieFileSystem();

kfs.write("src/main/resources/org/kie/example5/HAL5.drl", getRule());

KieBuilder kb = ks.newKieBuilder(kfs);

kb.buildAll(); // kieModule is automatically deployed to KieRepository if successfully built.
if (kb.getResults().hasMessages(Level.ERROR)) {
    throw new RuntimeException("Build Errors:\n" + kb.getResults().toString());
}

KieContainer kContainer = ks.newKieContainer(kr.getDefaultReleaseId());

KieSession kSession = kContainer.newKieSession();
kSession.setGlobal("out", out);

kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();
----
====

== Programmatically build a KieModule using Meta Models

* Project: kiemoduelmodel-example
* Summary: Programmatically build a KieModule, by creating its kmodule.xml meta model resources.


.Build and Install - Maven
====
[source]
----
mvn install
----
====


This programmatically builds a KieModule.
It populates the model that represents the ReleaseId and  kmodule.xml, as well as add the relevant resources.
A pom.xml is generated from the ReleaseId.

.Utilize and Run - Java
====
[source,java]
----
KieServices ks = KieServices.Factory.get();
KieFileSystem kfs = ks.newKieFileSystem();

Resource ex1Res = ks.getResources().newFileSystemResource(getFile("named-kiesession"));
Resource ex2Res = ks.getResources().newFileSystemResource(getFile("kiebase-inclusion"));

ReleaseId rid = ks.newReleaseId("org.drools", "kiemodulemodel-example", "6.0.0-SNAPSHOT");
kfs.generateAndWritePomXML(rid);

KieModuleModel kModuleModel = ks.newKieModuleModel();
kModuleModel.newKieBaseModel("kiemodulemodel")
            .addInclude("kiebase1")
            .addInclude("kiebase2")
            .newKieSessionModel("ksession6");

kfs.writeKModuleXML(kModuleModel.toXML());
kfs.write("src/main/resources/kiemodulemodel/HAL6.drl", getRule());

KieBuilder kb = ks.newKieBuilder(kfs);
kb.setDependencies(ex1Res, ex2Res);
kb.buildAll(); // kieModule is automatically deployed to KieRepository if successfully built.
if (kb.getResults().hasMessages(Level.ERROR)) {
    throw new RuntimeException("Build Errors:\n" + kb.getResults().toString());
}

KieContainer kContainer = ks.newKieContainer(rid);

KieSession kSession = kContainer.newKieSession("ksession6");
kSession.setGlobal("out", out);

Object msg1 = createMessage(kContainer, "Dave", "Hello, HAL. Do you read me, HAL?");
kSession.insert(msg1);
kSession.fireAllRules();

Object msg2 = createMessage(kContainer, "Dave", "Open the pod bay doors, HAL.");
kSession.insert(msg2);
kSession.fireAllRules();

Object msg3 = createMessage(kContainer, "Dave", "What's the problem?");
kSession.insert(msg3);
kSession.fireAllRules();
----
====
