You can create a Business Service using the Decision and Rule engines with the Quarkus framework support.

During the compilation, some code is automatically generated by a specific Maven plugin where part of the code is common and rest of it is engine-specific.

For each model, REST endpoints are generated, that are specific to the model and the engine.

Developers can add custom classes to the Business Service project to provide additional functionality, which will be built with the automatically generated code as in normal Java applications.

Dependencies

Use the BAMOE BOM for easily managing the version of all BAMOE libraries.

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.ibm.bamoe</groupId>
      <artifactId>bamoe-bom</artifactId>
      <version>9.2.1-ibm-0005</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

The dependencies required for a Decision or Rules application with Quarkus are:

<!-- For Decisions -->
<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-quarkus-decisions</artifactId>
</dependency>

<!-- or -->

<!-- For Rules -->
<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-quarkus-rules</artifactId>
</dependency>

Hot-reload is enabled out-of-the-box during development, using

mvn clean compile quarkus:dev

To enable Test Scenario support, use

<dependency>
  <groupId>org.kie.kogito</groupId>
  <artifactId>kogito-scenario-simulation</artifactId>
  <scope>test</scope>
</dependency>

Finally, the following Maven plugin is required to correctly build and package the application:

<plugin>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-maven-plugin</artifactId>
</plugin>

Configuration

Beside the pom.xml, the application.properties file is required to further customize the application with Quarkus or BAMOE specific properties (for example, server.address).

Lastly, a logback.xml file should be provided to customize logging output.

Structure

Decision Business Service projects follows Maven’s standard directory layout.

Decisions, application.properties and logback.xml files have to be written in the src/main/resources` directory.

To change the behavior during test execution, application.properties and logback.xml could also be written in src/test/resources.

Generated code will be in target/generated-sources/kogito.

Code

Decisions (DMN) and Rules (DRL) files need to go in the src/main/resources directory.

Testing

For full integration tests, testing classes should be annotated as @QuarkusTest, eventually injecting required managed properties or beans.

Here is an example that verifies the response received when posting an HTTP request on a given (automatically generated) entry point for a Decision:

@QuarkusTest
public class TrafficViolationTest {


    @Test
    public void testEvaluateTrafficViolation() {
        given()
                .body("{\n" +
                        "    \"Driver\": {\n" +
                        "        \"Points\": 2\n" +
                        "    },\n" +
                        "    \"Violation\": {\n" +
                        "        \"Type\": \"speed\",\n" +
                        "        \"Actual Speed\": 120,\n" +
                        "        \"Speed Limit\": 100\n" +
                        "    }\n" +
                        "}")
                .contentType(ContentType.JSON)
                .when()
                .post("/Traffic Violation")
                .then()
                .statusCode(200)
                .body("'Should the driver be suspended?'", is("No"));
    }
}

or for Rules:

@QuarkusTest
public class RestQueryTest {

    private static final String JSON_PAYLOAD =
            "{\n" +
                    "  \"maxAmount\":5000,\n" +
                    "  \"loanApplications\":[\n" +
                    "    {\n" +
                    "      \"id\":\"ABC10001\",\n" +
                    "      \"amount\":2000,\n" +
                    "      \"deposit\":100,\n" +
                    "      \"applicant\":{\n" +
                    "        \"age\":45,\n" +
                    "        \"name\":\"John\"\n" +
                    "      }\n" +
                    "    },\n" +
                    "    {\n" +
                    "      \"id\":\"ABC10002\",\n" +
                    "      \"amount\":5000,\n" +
                    "      \"deposit\":100,\n" +
                    "      \"applicant\":{\n" +
                    "        \"age\":25,\n" +
                    "        \"name\":\"Paul\"\n" +
                    "      }\n" +
                    "    },\n" +
                    "    {\n" +
                    "      \"id\":\"ABC10015\",\n" +
                    "      \"amount\":1000,\n" +
                    "      \"deposit\":100,\n" +
                    "      \"applicant\":{\n" +
                    "        \"age\":12,\n" +
                    "        \"name\":\"George\"\n" +
                    "      }\n" +
                    "    }\n" +
                    "  ]\n" +
                    "}";

    @Test
    public void testApproved() {
        given()
                .body(JSON_PAYLOAD)
                .contentType(ContentType.JSON)
                .when()
                .post("/find-approved")
                .then()
                .statusCode(200)
                .body("id", hasItem("ABC10001"));
    }
}

It is also possible to execute tests on native image. To do so:

  1. extend a testing class annotated as @QuarkusTest

  2. annotate that new class with @QuarkusIntegrationTest

E.g.

@QuarkusIntegrationTest
public class NativeTrafficViolationIT extends TrafficViolationTest {
    // Execute the same tests but in native mode.
}

Compilation

During Maven’s compilation phase, quarkus-maven-plugin scans the src/main/resources directory to find any .dmn or .drl files.

For each discovered file, the decision engine creates REST Resource classes, with endpoints specifically to:

  1. Retrieve the original model

  2. Execute the model

  3. Execute the model and retrieve “explanation” information

The classes are generated in a package whose name reflects the namespace of the DMN files, while the name of the generated class and the endpoint root are derived from the name of the model itself. For Rules, the classes are generated in the package of the DRL file.

Execution in dev mode

The following Maven command will compile from scratch and start the Quarkus application in dev mode:

mvn clean compile quarkus:dev

After a successful start, the application will be available at http://:0.0.0.0:8080 address (IP depends on application.properties configuration).

The Swagger UI page (http://0.0.0.0:8080/q/swagger-ui/) shows all the generated endpoints, providing a way to quickly verify them.

Hot-reload in dev mode

For medium to large sized applications, recompiling and restarting the application upon code changes could be cumbersome and time-consuming. To simplify that, the Quarkus framework offers an embedded hot-reload feature.

To fire it, there are two steps required:

  1. modify any source/resource

  2. reload any page of the generated application

Debugging

The way to debug the application without using specific IDE tools or plug-ins, relies on the standard Java remote debug setup:

  1. Create a remote debug configuration on port 5005 (details vary by IDE).

  2. Start application in dev mode.

    mvn clean compile quarkus:dev
  3. Put a breakpoint in some of the code-generated sources.

  4. Connect the remote debugger.

It is also possible to block the compilation until a debugger is connected, using the following command:

mvn clean compile quarkus:dev -Dsuspend

This is useful to debug code generation.