Kogitoを使用してアプリケーションにルール・エンジン機能を追加する
このガイドでは、QuarkusアプリケーションがKogitoを使用してルール付きのDRLファイルを追加する方法を説明します。
Kogitoは、よく知られたオープンソース・プロジェクトであるDrools(ビジネス・ルール用)とjBPM(ビジネス・プロセス用)から生まれた、次世代のビジネス・オートメーション・ツールキットです。Kogitoは、ビジネス・オートメーションに新しいアプローチを提供することを目的としており、主なメッセージは、ビジネス・ナレッジ(プロセス、ルール、決定、予測)をドメイン固有の方法で公開することです。
前提条件
このガイドを完成させるには、以下が必要です:
-
約15分
-
IDE
-
JDK 11+ がインストールされ、
JAVA_HOME
が適切に設定されていること -
Apache Maven 3.8.1+
-
動作するコンテナランタイム(Docker, Podman)
-
使用したい場合、 Quarkus CLI
-
ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること
アーキテクチャ
この例では、1つのRESTエンドポイントを提供する非常にシンプルなマイクロサービスを構築します:
-
/find-approved
このエンドポイントは、DRLファイルのRule Unitに挿入されたクエリに基づいて自動的に生成されます。これは、ビジネス・ルールの実行が副作用を伴わないステートレス呼び出し(「純粋な関数呼び出し」とも呼ばれる)の例です。返される出力値は、提供された入力に一意に基づいています。
ソリューション
次のセクションで紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。
Gitリポジトリをクローンする: git clone https://github.com/quarkusio/quarkus-quickstarts.git
、または archive をダウンロードする。
このソリューションは kogito-drl-quickstart
directory にあります。
Mavenプロジェクトの作成
まず、新しいプロジェクトを用意します。以下のコマンドで新しいプロジェクトを作成します:
このコマンドはMavenプロジェクトを生成し、アプリケーションにビジネス・オートメーションの機能を追加するために必要な依存関係と構成をすべて備えた kogito-quarkus-rules
エクステンションをインポートします。また、KogitoがRESTサービスを公開するのに必要な resteasy-jackson
エクステンションをインポートします。
すでにQuarkusプロジェクトが設定されている場合は、プロジェクトのベースディレクトリで以下のコマンドを実行することで、 kogito-quarkus-rules
エクステンションをプロジェクトに追加することができます:
quarkus extension add 'kogito-quarkus-rules'
./mvnw quarkus:add-extension -Dextensions="kogito-quarkus-rules"
./gradlew addExtension --extensions="kogito-quarkus-rules"
これにより、 pom.xml
に以下が追加されます:
<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-quarkus-rules</artifactId>
</dependency>
implementation(“org.kie.kogito:kogito-quarkus-rules”)
アプリケーションの作成
Let’s start from the application domain model. This application will approve Loan Applications, so we have a class with all the details of the wanted Loan:
package org.acme.kogito.model;
public class LoanApplication {
private String id;
private Applicant applicant;
private int amount;
private int deposit;
private boolean approved = false;
public LoanApplication() {
}
public LoanApplication(String id, Applicant applicant,
int amount, int deposit) {
this.id = id;
this.applicant = applicant;
this.amount = amount;
this.deposit = deposit;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Applicant getApplicant() {
return applicant;
}
public void setApplicant(Applicant applicant) {
this.applicant = applicant;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public int getDeposit() {
return deposit;
}
public void setDeposit(int deposit) {
this.deposit = deposit;
}
public boolean isApproved() {
return approved;
}
public void setApproved(boolean approved) {
this.approved = approved;
}
}
そして、申請者の詳細を記載した別のクラスを用意します:
package org.acme.kogito.model;
public class Applicant {
private String name;
private int age;
public Applicant() {
}
public Applicant(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
次に、生成されたプロジェクトの src/main/resources/org/acme/kogito/queries
フォルダ内にルールファイル loan-rules.drl
を作成します。
package org.acme.kogito.queries;
unit LoanUnit; // no need to using globals, all variables and facts are stored in the rule unit
import org.acme.kogito.model.Applicant;
import org.acme.kogito.model.LoanApplication;
rule LargeDepositApprove when
$l: /loanApplications[ applicant.age >= 20, deposit >= 1000, amount <= maxAmount ] // oopath style
then
modify($l) { setApproved(true) };
end
rule LargeDepositReject when
$l: /loanApplications[ applicant.age >= 20, deposit >= 1000, amount > maxAmount ]
then
modify($l) { setApproved(false) };
end
// ... more loans approval/rejections business rules ...
// approved loan applications are now retrieved through a query
query FindApproved
$l: /loanApplications[ approved ]
end
このファイルには、ローンが承認されるべきかどうかを決定するためのルールの例があります。このサービスでは、申請者の年齢が20歳以上で、銀行口座に1,000通貨以上の預金があることを求めています。ローンの金額は maxAmount
を超えてはいけません。
この例では、Kogitoに導入された新しい概念であるルール・ユニットを使用しています。これは、ルールのセットと、それらのルールが照合されるファクトをカプセル化するのに役立ちます。
挿入されたファクトは、タイプセーフのエントリーポイントである DataStore
に挿入されます。すべてを機能させるには、RuleUnitとDataStoreの両方を定義する必要があります。
package org.acme.kogito.queries;
import org.acme.kogito.model.LoanApplication;
import org.kie.kogito.rules.DataSource;
import org.kie.kogito.rules.DataStore;
import org.kie.kogito.rules.RuleUnitData;
public class LoanUnit implements RuleUnitData {
private int maxAmount;
private DataStore<LoanApplication> loanApplications;
public LoanUnit() {
this(DataSource.createStore(), 0);
}
public LoanUnit(DataStore<LoanApplication> loanApplications, int maxAmount) {
this.loanApplications = loanApplications;
this.maxAmount = maxAmount;
}
public DataStore<LoanApplication> getLoanApplications() { return loanApplications; }
public void setLoanApplications(DataStore<LoanApplication> loanApplications) {
this.loanApplications = loanApplications;
}
public int getMaxAmount() { return maxAmount; }
public void setMaxAmount(int maxAmount) { this.maxAmount = maxAmount; }
}
これで完了です。ローン申請を検証するためのRESTエンドポイントが、このRule Unitから自動的に生成されます。
アプリケーションの実行と使用
Devモードでの動作
マイクロサービスをdevモードで実行するには:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
JVMモードでの動作
「開発モード」で遊び終わったら、標準のJavaアプリケーションとして実行することができます。
まず、コンパイルします:
quarkus build
./mvnw clean package
./gradlew build
それから実行してください:
java -jar target/quarkus-app/quarkus-run.jar
ネイティブモードでの実行
同じデモをネイティブコードにコンパイルすることができます。修正は必要ありません。
これは、生成されたバイナリにランタイム技術が含まれており、最小限のリソースオーバーヘッドで実行できるように最適化されているため、本番環境にJVMをインストールする必要がないことを意味します。
コンパイルには少し時間がかかるので、このステップはデフォルトでは無効になっています。以下のコマンドでネイティブ実行可能ファイルをビルドしてみましょう:
quarkus build --native
./mvnw package -Dnative
./gradlew build -Dquarkus.package.type=native
コーヒーを飲み終わると、このバイナリは以下のように直接実行出来るようになります:
target/kogito-drl-quickstart-1.0.0-SNAPSHOT-runner
アプリケーションのテスト
アプリケーションをテストするには、JSONペイロードとして期待される入力を提供して、エンドポイントにリクエストを送るだけです。
curl -X POST http://localhost:8080/find-approved \
-H ‘Content-Type: application/json’\
-H ‘Accept: application/json’ \
-d ‘{“maxAmount”:5000,
“loanApplications”:[
{“id”:”ABC10001”,”amount”:2000,”deposit”:1000,
“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”}}
]}’
レスポンスでは、承認されたアプリケーションのリストが返されます:
[{“id”:”ABC10001”,
“applicant”:{“name”:”John”,”age”:45},
“amount”:2000,”deposit”:100,”approved”:true}]