Drools Spring Integration

Drools Springの統合

1. 前書き

このクイックチュートリアルでは、DroolsとSpringを統合します。 Droolsを使い始めたばかりの場合は、check out this intro article.

2. Mavenの依存関係

pom.xmlファイルに次の依存関係を追加することから始めましょう。


    org.drools
    drools-core
    7.0.0.Final


    org.kie
    kie-spring
    7.0.0.Final

最新バージョンは、ここでdrools-coreについて、ここでkie-springについて見つけることができます。

3. 初期データ

ここで、この例で使用するデータを定義しましょう。 移動距離と夜間追加料金フラグに基づいて、乗車料金を計算します。

これはFact:として使用される単純なオブジェクトです

public class TaxiRide {
    private Boolean isNightSurcharge;
    private Long distanceInMile;

    // standard constructors, getters/setters
}

運賃を表すために使用される別のビジネスオブジェクトも定義しましょう。

public class Fare {
    private Long nightSurcharge;
    private Long rideFare;

    // standard constructors, getters/setters
}

それでは、タクシー料金を計算するためのビジネスルールを定義しましょう。

global com.example.spring.drools.model.Fare rideFare;
dialect  "mvel"

rule "Calculate Taxi Fare - Scenario 1"
    when
        taxiRideInstance:TaxiRide(isNightSurcharge == false && distanceInMile < 10);
    then
        rideFare.setNightSurcharge(0);
        rideFare.setRideFare(70);
end

ご覧のとおり、指定されたTaxiRideの合計運賃を計算するルールが定義されています。

このルールは、TaxiRideオブジェクトを受け入れ、isNightSurcharge属性がfalseであり、distanceInMile属性値が10未満であるかどうかを確認し、運賃を70として計算し、%を設定します。 (t4)sプロパティを0に。

計算された出力は、さらに使用するためにFareオブジェクトに設定されます。

4. 春の統合

4.1. Spring Beanの構成

それでは、Springの統合に移りましょう。

Spring Bean構成クラスを定義します。これはTaxiFareCalculatorServiceBeanとその依存関係のインスタンス化を担当します。

@Configuration
@ComponentScan("com.example.spring.drools.service")
public class TaxiFareConfiguration {
    private static final String drlFile = "TAXI_FARE_RULE.drl";

    @Bean
    public KieContainer kieContainer() {
        KieServices kieServices = KieServices.Factory.get();

        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        kieFileSystem.write(ResourceFactory.newClassPathResource(drlFile));
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
        kieBuilder.buildAll();
        KieModule kieModule = kieBuilder.getKieModule();

        return kieServices.newKieContainer(kieModule.getReleaseId());
    }
}

KieServicesは、Kieが提供するすべてのサービスを取得するためのシングルポイントエントリとして機能するシングルトンです。 KieServicesは、KieServices.Factory.get().を使用して取得されます

次に、ルールエンジンを実行するために必要なすべてのオブジェクトのプレースホルダーであるKieContainerを取得する必要があります。

KieContainerは、KieFileSystem, KieBuilder,KieModule.を含む他のBeanの助けを借りて構築されます

KieBase.と呼ばれるルール知識を定義するために必要なすべてのリソースのコンテナであるKieModuleの作成に進みましょう。

KieModule kieModule = kieBuilder.getKieModule();

KieBaseは、ルール、プロセス、関数、型モデルなど、アプリケーションに関連するすべての知識を含むリポジトリであり、KieModule内に隠されています。 KieBaseは、KieContainer.から取得できます。

KieModuleが作成されたら、KieBaseが定義されているKieModuleを含むKieContainerの作成に進むことができます。 KieContainerは、次のモジュールを使用して作成されます。

KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId());

4.2. 春のサービス

結果を処理するためにFactオブジェクトをエンジンに渡すことにより、実際のビジネスロジックを実行するサービスクラスを定義しましょう。

@Service
public class TaxiFareCalculatorService {

    @Autowired
    private KieContainer kieContainer;

    public Long calculateFare(TaxiRide taxiRide, Fare rideFare) {
        KieSession kieSession = kieContainer.newKieSession();
        kieSession.setGlobal("rideFare", rideFare);
        kieSession.insert(taxiRide);
        kieSession.fireAllRules();
        kieSession.dispose();
        return rideFare.getTotalFare();
    }
}

最後に、KieContainerインスタンスを使用してKieSessionが作成されます。 KieSessionインスタンスは、入力データを挿入できる場所です。 KieSessionはエンジンと対話して、挿入されたファクトに基づいてルールで定義された実際のビジネスロジックを処理します。

グローバル(グローバル変数と同様)は、エンジンに情報を渡すために使用されます。 この例では、setGlobal(“key”, value);を使用してGlobalを設定できます。計算されたタクシー料金を格納するために、FareオブジェクトをGlobalとして設定しました。

セクション4で説明したように、a Rule requires data to operate onkieSession.insert(taxiRide);を使用してFactをセッションに挿入しています

入力Fact,の設定が完了したら、fireAllRules().を呼び出すことにより、エンジンにビジネスロジックの実行を要求できます。

最後に、dispose()メソッドを呼び出してメモリリークを回避するために、セッションをクリーンアップする必要があります。

5. 実例

これで、Springコンテキストを接続し、Droolsが期待どおりに動作することを実際に確認できます。

@Test
public void whenNightSurchargeFalseAndDistLessThan10_thenFixWithoutNightSurcharge() {
    TaxiRide taxiRide = new TaxiRide();
    taxiRide.setIsNightSurcharge(false);
    taxiRide.setDistanceInMile(9L);
    Fare rideFare = new Fare();
    Long totalCharge = taxiFareCalculatorService.calculateFare(taxiRide, rideFare);

    assertNotNull(totalCharge);
    assertEquals(Long.valueOf(70), totalCharge);
}

6. 結論

この記事では、単純なユースケースとDrools Springの統合について学びました。

いつものように、例とコードスニペットの実装はover on GitHubで利用できます。