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:
-
extend a testing class annotated as
@QuarkusTest
-
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:
-
Retrieve the original model
-
Execute the model
-
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:
-
modify any source/resource
-
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:
-
Create a remote debug configuration on port 5005 (details vary by IDE).
-
Start application in dev mode.
mvn clean compile quarkus:dev
-
Put a breakpoint in some of the code-generated sources.
-
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.