Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KOGITO-5533: add examples of evaluation of rules via CloudEvents #886

Merged
merged 11 commits into from
Sep 29, 2021
Merged
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@
<module>process-usertasks-with-security-quarkus</module>
<module>process-usertasks-with-security-springboot</module>
<module>rules-quarkus-helloworld</module>
<module>ruleunit-event-driven-quarkus</module>
<module>ruleunit-event-driven-springboot</module>
<module>ruleunit-quarkus-example</module>
<module>ruleunit-springboot-example</module>
<module>rules-legacy-quarkus-example</module>
Expand Down Expand Up @@ -303,6 +305,7 @@
<module>process-usertasks-with-security-oidc-quarkus-with-console</module>
<module>process-usertasks-with-security-quarkus</module>
<module>rules-quarkus-helloworld</module>
<module>ruleunit-event-driven-quarkus</module>
<module>ruleunit-quarkus-example</module>
<module>serverless-workflow-greeting-quarkus</module>
<module>serverless-workflow-service-calls-quarkus</module>
Expand Down Expand Up @@ -334,6 +337,8 @@
<module>rules-legacy-quarkus-example</module>
<module>rules-legacy-springboot-example</module>
<module>rules-quarkus-helloworld</module>
<module>ruleunit-event-driven-quarkus</module>
<module>ruleunit-event-driven-springboot</module>
<module>ruleunit-quarkus-example</module>
<module>ruleunit-springboot-example</module>
<module>process-decisions-quarkus</module>
Expand Down
192 changes: 192 additions & 0 deletions ruleunit-event-driven-quarkus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# Event-Driven DMN Quarkus Example

## Description

This example demonstrates the capability of the _Kogito Event-Driven Rules AddOn_: to enable, when included as dependency of a simple service containing
DRL files, to trigger evaluations of its queries and receive the corresponding results via specific CloudEvents.

The source and destination of these events are two configured Kafka topics.

The main goal behind the addon is to allow Kogito DRL services to be used as part of an event processing pipeline.

## Installing and Running

### Prerequisites

You will need:
- Java 11+ installed
- Environment variable JAVA_HOME set accordingly
- Maven 3.6.2+ installed
- [Docker Engine](https://docs.docker.com/engine/) and [Docker Compose](https://docs.docker.com/compose/) installed

When using native image compilation, you will also need:
- [GraalVM 19.3.1](https://github.com/oracle/graal/releases/tag/vm-19.3.1) installed
- Environment variable GRAALVM_HOME set accordingly
- Note that GraalVM native image compilation typically requires other packages (glibc-devel, zlib-devel and gcc) to be installed too. You also need 'native-image' installed in GraalVM (using 'gu install native-image'). Please refer to [GraalVM installation documentation](https://www.graalvm.org/docs/reference-manual/aot-compilation/#prerequisites) for more details.

### Enable The AddOn

Like the other Kogito AddOns, the only required step to enable it is to include it as dependency in the [POM file](pom.xml):

```xml
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-addons-quarkus-events-rules</artifactId>
</dependency>
```

The version is implicitly derived from the `kogito-quarkus-bom` included in the `dependencyManagement` section.

### Configuration

The only configuration required is for the input and output topics. The Quarkus addon uses [MicroProfile Reactive Messaging](https://quarkus.io/guides/kafka)
under the hood and must be configured accordingly.

Here is the important section of [application.properties](src/main/resources/application.properties):

```properties
mp.messaging.incoming.kogito_incoming_stream.group.id=<group_id>
mp.messaging.incoming.kogito_incoming_stream.connector=smallrye-kafka
mp.messaging.incoming.kogito_incoming_stream.topic=<input_topic_name>
mp.messaging.incoming.kogito_incoming_stream.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer

mp.messaging.outgoing.kogito_outgoing_stream.group.id=<group_id>
mp.messaging.outgoing.kogito_outgoing_stream.connector=smallrye-kafka
mp.messaging.outgoing.kogito_outgoing_stream.topic=<output_topic_name>
mp.messaging.outgoing.kogito_outgoing_stream.value.serializer=org.apache.kafka.common.serialization.StringSerializer
```

Insert the value you need in `<group_id>`, `<input_topic_name>` and `<output_topic_name>`. Pre-configured values already works if you follow this
guide without changes.

### Start test Kafka instance via Docker Compose

There's a useful [docker-compose.yml](docker-compose.yml) in the root that starts a dedicated Kafka instance for quick tests.

Simply start it with this command from the root of the repo:

```
docker-compose up -d
```

Once everything is started you can check the data contained in your small Kafka instance via [Kafdrop](https://github.com/obsidiandynamics/kafdrop) at `http://localhost:9000/`.

### Compile and Run in Local Dev Mode

```
mvn clean compile quarkus:dev
```

### Package and Run in JVM mode

```
mvn clean package
java -jar target/quarkus-app/quarkus-run.jar
```

or on Windows

```
mvn clean package
java -jar target\quarkus-app\quarkus-run.jar
```

### Package and Run using Local Native Image
Note that this requires GRAALVM_HOME to point to a valid GraalVM installation

```
mvn clean package -Pnative
```

To run the generated native executable, generated in `target/`, execute

```
./target/dmn-quarkus-example-runner
```

Note: This does not yet work on Windows, GraalVM and Quarkus should be rolling out support for Windows soon.

## Example Usage

Here is an example of a input event that triggers the evaluation of the [Loan Unit](src/main/resources/org/kie/kogito/queries/RuleUnitQuery.drl) queries
included in this example. The `data` field contains the query input.

Just send this payload to the configured input topic:

```json
{
"specversion": "1.0",
"id": "a89b61a2-5644-487a-8a86-144855c5dce8",
"source": "SomeEventSource",
"type": "RulesRequest",
"subject": "TheSubject",
"kogitoruleunitid": "org.kie.kogito.queries.LoanUnit",
"kogitoruleunitquery": "FindApproved",
"data": {
"maxAmount": 5000,
"loanApplications": [
{
"id": "ABC10001",
"amount": 2000,
"deposit": 100,
"applicant": {
"age": 45,
"name": "John"
}
},
{
"id": "ABC10002",
"amount": 5000,
"deposit": 100,
"applicant": {
"age": 25,
"name": "Paul"
}
},
{
"id": "ABC10015",
"amount": 1000,
"deposit": 100,
"applicant": {
"age": 12,
"name": "George"
}
}
]
}
}
```

And you should receive something similar to this in the output topic:

```json
{
"specversion": "1.0",
"id": "d54ace84-6788-46b6-a359-b308f8b21778",
"source": "find-approved",
"type": "RulesResponse",
"subject": "TheSubject",
"kogitoruleunitid": "org.kie.kogito.queries.LoanUnit",
"kogitoruleunitquery": "FindApproved",
"data": [
{
"id": "ABC10001",
"applicant": {
"name": "John",
"age": 45
},
"amount": 2000,
"deposit": 100,
"approved": true
}
]
}
```

The `data` field contains the query output. Values of `id` fields will change, but the rest will be the same.

### Other examples

All the leaf subfolders of [the test events resource folder](src/test/resources/events) contain a pair of `input.json` and `output.json` files.

There's one for every possible variation in the structure of the input/output events supported by the addon. Feel free to try them all.
37 changes: 37 additions & 0 deletions ruleunit-event-driven-quarkus/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
version: '2'

services:

zookeeper:
image: wurstmeister/zookeeper:3.4.6
ports:
- "2181:2181"
environment:
LOG_DIR: "/tmp/logs"

kafka:
image: wurstmeister/kafka:2.12-2.2.1
depends_on:
- zookeeper
ports:
- "9092:9092"
expose:
- "9093"
environment:
KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
LOG_DIR: "/tmp/logs"

kafdrop:
image: obsidiandynamics/kafdrop
depends_on:
- kafka
ports:
- "9000:9000"
environment:
KAFKA_BROKERCONNECT: "kafka:9093"
JVM_OPTS: "-Xms32M -Xmx64M"
SERVER_SERVLET_CONTEXTPATH: "/"
92 changes: 92 additions & 0 deletions ruleunit-event-driven-quarkus/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.kie.kogito.examples</groupId>
<artifactId>kogito-examples</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<artifactId>ruleunit-event-driven-quarkus</artifactId>
<name>Kogito Example :: Rule Unit Event-Driven :: Quarkus</name>
<properties>
<quarkus-plugin.version>2.1.0.Final</quarkus-plugin.version>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<quarkus.platform.version>2.1.0.Final</quarkus.platform.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-quarkus-rules</artifactId>
</dependency>

<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-addons-quarkus-events-rules</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-quarkus-test-utils</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<version>1.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2020 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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.kie.kogito.queries;

public class AllAmounts {
private int amounts;

public AllAmounts(int amounts) {
this.amounts = amounts;
}

public int getAmounts() {
return amounts;
}

public void setAmounts(int amounts) {
this.amounts = amounts;
}
}
Loading