第5章 ルールの実行

ルールの例を特定するか、Business Central でルールを作成したら、関連のプロジェクトをビルドしてデプロイし、ローカルまたは Decision Server でルールを実行してテストできます。

前提条件

手順

  1. Business Central で、MenuDesignProjects に移動して、プロジェクト名をクリックします。
  2. プロジェクトの Assets ページの右上にある Deploy をクリックして、プロジェクトをビルドして Decision Server にデプロイします。ビルドに失敗したら、画面下部の Alerts パネルに記載されている問題に対処します。

    プロジェクトのデプロイメントオプションに関する詳細は、Red Hat Decision Manager プロジェクトのパッケージ化およびデプロイ を参照してください。

  3. ローカルでのルール実行に使用するか、Decision Server でルールを実行するクライアントアプリケーションとして使用できるように、まだ作成されていない場合には、Business Central 外に Maven または Java プロジェクトを作成します。プロジェクトには、pom.xml ファイルと、プロジェクトリソースの実行に必要なその他のコンポーネントを含める必要があります。

    テストプロジェクトの例は、その他の DRL ルールの作成および実行方法 を参照してください。

  4. テストプロジェクトまたはクライアントアプリケーションの pom.xml ファイルを開き、以下の依存関係が追加されていない場合は追加します。

    • kie-ci: クライアントアプリケーションで、ReleaseId を使用して、Business Central プロジェクトデータをローカルに読み込みます。
    • kie-server-client: クライアントアプリケーションで、Decision Server のアセットを使用してリモートに接続します。
    • slf4j: (オプション) クライアントアプリケーションで、Decision Server に接続した後に、SLF4J (Simple Logging Facade for Java) を使用して、デバッグのログ情報を返します。

    クライアントアプリケーションの pom.xml ファイルにおける、Red Hat Decision Manager 7.6 の依存関係の例

    <!-- For local execution -->
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-ci</artifactId>
      <version>7.30.0.Final-redhat-00003</version>
    </dependency>
    
    <!-- For remote execution on Decision Server -->
    <dependency>
      <groupId>org.kie.server</groupId>
      <artifactId>kie-server-client</artifactId>
      <version>7.30.0.Final-redhat-00003</version>
    </dependency>
    
    <!-- For debug logging (optional) -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.25</version>
    </dependency>

    このアーティファクトで利用可能なバージョンについては、オンラインの Nexus Repository Manager でグループ ID とアーティファクト ID を検索してください。

    注記

    個別の依存関係に対して Red Hat Decision Manager <version> を指定するのではなく、Red Hat Business Automation 部品表 (BOM) の依存関係をプロジェクトの pom.xml ファイルに追加することを検討してください。Red Hat Business Automation BOM は、Red Hat Decision Manager と Red Hat Process Automation Manager の両方に適用されます。BOM ファイルを追加すると、提供される Maven リポジトリーから、推移的依存関係の適切なバージョンがプロジェクトに含められます。

    BOM 依存関係の例:

    <dependency>
      <groupId>com.redhat.ba</groupId>
      <artifactId>ba-platform-bom</artifactId>
      <version>7.6.0.redhat-00004</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>

    Red Hat Business Automation BOM (Bill of Materials) の詳細情報は、What is the mapping between Red Hat Decision Manager and the Maven library version? を参照してください。

  5. モデルクラスを含むアーティファクトの依存関係が、クライアントアプリケーションの pom.xml ファイルに定義されていて、デプロイしたプロジェクトの pom.xml ファイルに記載されているのと同じであることを確認します。モデルクラスの依存関係が、クライアントアプリケーションとプロジェクトで異なると、実行エラーが発生します。

    Business Central でプロジェクトの pom.xml ファイルを利用するには、プロジェクトで既存のアセットを選択し、画面左側の Project Explorer メニューで Customize View ギアアイコンをクリックし、Repository Viewpom.xml を選択します。

    たとえば、以下の Person クラスの依存関係は、クライアントと、デプロイしたプロジェクトの pom.xml ファイルの両方に表示されます。

    <dependency>
      <groupId>com.sample</groupId>
      <artifactId>Person</artifactId>
      <version>1.0.0</version>
    </dependency>
  6. デバッグ向けロギングを行うために、slf4j 依存関係を、クライアントアプリケーションの pom.xml ファイルに追加した場合は、関連するクラスパス (Maven の src/main/resources/META-INF 内など) に simplelogger.properties ファイルを作成し、以下の内容を記載します。

    org.slf4j.simpleLogger.defaultLogLevel=debug
  7. クライアントアプリケーションに、必要なインポートを含む .java メインクラスと、KIE ベースを読み込む main() メソッドを作成し、ファクトを挿入し、ルールを実行します。

    たとえば、プロジェクトの Person オブジェクトには、名前、苗字、時給、および賃金を設定および取得するゲッターメソッドおよびセッターメソッドが含まれます。プロジェクトにある以下の Wage ルールでは、賃金と時給を計算し、その結果に基づいてメッセージを表示します。

    package com.sample;
    
    import com.sample.Person;
    
    dialect "java"
    
    rule "Wage"
      when
        Person(hourlyRate * wage > 100)
        Person(name : firstName, surname : lastName)
      then
        System.out.println("Hello" + " " + name + " " + surname + "!");
        System.out.println("You are rich!");
    end

    (必要に応じて) Decision Server の外でローカルにこのルールをテストするには、.java クラスで、KIE サービス、KIE コンテナー、および KIE セッションをインポートするように設定し、その後、main() メソッドを使用して、定義したファクトモデルに対してすべてのルールを実行するようにします。

    ローカルでルールの実行

    import org.kie.api.KieServices;
    import org.kie.api.builder.ReleaseId;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.KieSession;
    import org.drools.compiler.kproject.ReleaseIdImpl;
    
    public class RulesTest {
    
      public static final void main(String[] args) {
        try {
          // Identify the project in the local repository:
          ReleaseId rid = new ReleaseIdImpl("com.myspace", "MyProject", "1.0.0");
    
          // Load the KIE base:
          KieServices ks = KieServices.Factory.get();
          KieContainer kContainer = ks.newKieContainer(rid);
          KieSession kSession = kContainer.newKieSession();
    
          // Set up the fact model:
          Person p = new Person();
          p.setWage(12);
          p.setFirstName("Tom");
          p.setLastName("Summers");
          p.setHourlyRate(10);
    
          // Insert the person into the session:
          kSession.insert(p);
    
          // Fire all rules:
          kSession.fireAllRules();
          kSession.dispose();
        }
    
        catch (Throwable t) {
          t.printStackTrace();
        }
      }
    }

    Decision Server でこのルールをテストするには、ローカル例と同じように、インポートとルール実行情報で .java クラスを設定し、KIE サービス設定および KIE サービスクライアントの詳細を指定します。

    Decision Server でのルールの実行

    package com.sample;
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    import org.kie.api.command.BatchExecutionCommand;
    import org.kie.api.command.Command;
    import org.kie.api.KieServices;
    import org.kie.api.runtime.ExecutionResults;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.KieSession;
    import org.kie.server.api.marshalling.MarshallingFormat;
    import org.kie.server.api.model.ServiceResponse;
    import org.kie.server.client.KieServicesClient;
    import org.kie.server.client.KieServicesConfiguration;
    import org.kie.server.client.KieServicesFactory;
    import org.kie.server.client.RuleServicesClient;
    
    import com.sample.Person;
    
    public class RulesTest {
    
      private static final String containerName = "testProject";
      private static final String sessionName = "myStatelessSession";
    
      public static final void main(String[] args) {
        try {
          // Define KIE services configuration and client:
          Set<Class<?>> allClasses = new HashSet<Class<?>>();
          allClasses.add(Person.class);
          String serverUrl = "http://$HOST:$PORT/kie-server/services/rest/server";
          String username = "$USERNAME";
          String password = "$PASSWORD";
          KieServicesConfiguration config =
            KieServicesFactory.newRestConfiguration(serverUrl,
                                                    username,
                                                    password);
          config.setMarshallingFormat(MarshallingFormat.JAXB);
          config.addExtraClasses(allClasses);
          KieServicesClient kieServicesClient =
            KieServicesFactory.newKieServicesClient(config);
    
          // Set up the fact model:
          Person p = new Person();
          p.setWage(12);
          p.setFirstName("Tom");
          p.setLastName("Summers");
          p.setHourlyRate(10);
    
          // Insert Person into the session:
          KieCommands kieCommands = KieServices.Factory.get().getCommands();
          List<Command> commandList = new ArrayList<Command>();
          commandList.add(kieCommands.newInsert(p, "personReturnId"));
    
          // Fire all rules:
          commandList.add(kieCommands.newFireAllRules("numberOfFiredRules"));
          BatchExecutionCommand batch = kieCommands.newBatchExecution(commandList, sessionName);
    
          // Use rule services client to send request:
          RuleServicesClient ruleClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
          ServiceResponse<ExecutionResults> executeResponse = ruleClient.executeCommandsWithResults(containerName, batch);
          System.out.println("number of fired rules:" + executeResponse.getResult().getValue("numberOfFiredRules"));
        }
    
        catch (Throwable t) {
          t.printStackTrace();
        }
      }
    }

  8. 設定した .java クラスをプロジェクトディレクトリーから実行します。(Red Hat CodeReady Studio などの) 開発プラットフォーム、またはコマンドラインでファイルを実行できます。

    (プロジェクトディレクトリーにおける) Maven の実行例

    mvn clean install exec:java -Dexec.mainClass="com.sample.app.RulesTest"

    (プロジェクトディレクトリーにおける) Java の実行例

    javac -classpath "./$DEPENDENCIES/*:." RulesTest.java
    java -classpath "./$DEPENDENCIES/*:." RulesTest
  9. コマンドラインおよびサーバーログで、ルール実行のステータスを確認します。ルールが期待通りに実行しない場合は、プロジェクトに設定したルールと、メインのクラス設定を確認して、提供されるデータの妥当性を確認します。

5.1. 実行可能ルールモデル

実行可能ルールモデルは埋め込み可能なモデルで、ビルド時に実行するルールセットの Java ベース表記を提供します。実行可能モデルは Red Hat Decision Manager の標準アセットパッケージングの代わりとなるもので、より効率的です。KIE コンテナーと KIE ベースの作成がより迅速にでき、DRL (Drools Rule Language) ファイルリストや他の Red Hat Decision Manager アセットが多い場合は、特に有効です。KIE コンテナーと KIE ベースの作成がより迅速にでき、DRL (Drools Rule Language) ファイルリストや他の Red Hat Process Automation Manager アセットが多い場合は、特に有効です。このモデルは詳細レベルにわたり、インデックス評価の lambda 表記など、必要な実行情報すべてを提供できます。

実行可能なルールモデルでは、プロジェクトにとって具体的に以下のような利点があります。

  • コンパイル時間: 従来のパッケージ化された Red Hat Decision Manager プロジェクト (KJAR) には、制限や結果を実装する事前生成済みのクラスと合わせて、ルールベースを定義する DRL ファイルのリストやその他の Red Hat Decision Manager アーティファクトが含まれています。これらの DRL ファイルは、KJAR が Maven リポジトリーからダウンロードされ、KIE コンテナーにインストールされた時点で、解析してコンパイルする必要があります。特に大規模なルールセットの場合など、このプロセスは時間がかかる可能性があります。実行可能なモデルでは、プロジェクト KJAR 内で、Java クラスをパッケージ化して、プロジェクトルールベースの実行可能なモデルを実装し、はるかに速い方法で KIE コンテナーと KIE ベースを再作成することができます。Maven プロジェクトでは、kie-maven-plugin を使用してコンパイルプロセス中に DRL ファイルから 実行可能なモデルソースを自動的に生成します。
  • ランタイム: 実行可能なモデルでは、制約はすべて、Java lambda 式で定義されます。同じ lambda 式も制約評価に使用するため、mvel ベースの制約をバイトコードに変換するのに、解釈評価用の mvel 式も、Just-In-Time (JIT) プロセスも使用しません。これにより、さらに迅速で効率的なランタイムを構築できます。
  • 開発時間: 実行可能なモデルでは、DRL 形式で直接要素をエンコードしたり、DRL パーサーを対応するように変更したりする必要なく、デシジョンエンジンの新機能で開発および試行できます。
注記

実行可能なルールモデルのクエリー定義に使用できるのは、引数最大 10 個のみです。

実行可能なルールモデルのルール結果内にある変数で使用できるバインド変数は、最大 24 個のみとなっています (同梱されている drools 変数を含む)。たとえば、以下のルールの結果では、バインド変数を 24 個以上使用しているため、コンパイルエラーが発生します。

...
then
  $input.setNo25Count(functions.sumOf(new Object[]{$no1Count_1, $no2Count_1, $no3Count_1, ..., $no25Count_1}).intValue());
  $input.getFirings().add("fired");
  update($input);

5.1.1. Maven プロジェクトへの実行可能なルールモデルの埋め込み

Maven プロジェクトに実行可能ルールモデルを埋め込み、ビルド時にルールアセットをより効率的にコンパイルすることができます。

前提条件

  • Red Hat Decision Manager ビジネスアセットを含む Maven 化されたプロジェクトがあること

手順

  1. Maven プロジェクトの pom.xml ファイルで、パッケージタイプを kjar に設定し、kie-maven-plugin ビルドコンポーネントを追加します。

    <packaging>kjar</packaging>
    ...
    <build>
      <plugins>
        <plugin>
          <groupId>org.kie</groupId>
          <artifactId>kie-maven-plugin</artifactId>
          <version>${rhdm.version}</version>
          <extensions>true</extensions>
        </plugin>
      </plugins>
    </build>

    kjar パッケージングタイプは、kie-maven-plugin コンポーネントをアクティブにして、アーティファクトリーソースを検証してプリコンパイルします。<version> は、プロジェクトで現在使用する Red Hat Decision Manager の Maven アーティファクトバージョンです (例: 7.30.0.Final-redhat-00003)。これらの設定は、Maven プロジェクトを適切にパッケージ化するために必要です。

    注記

    個別の依存関係に対して Red Hat Decision Manager <version> を指定するのではなく、Red Hat Business Automation 部品表 (BOM) の依存関係をプロジェクトの pom.xml ファイルに追加することを検討してください。Red Hat Business Automation BOM は、Red Hat Decision Manager と Red Hat Process Automation Manager の両方に適用されます。BOM ファイルを追加すると、提供される Maven リポジトリーから、推移的依存関係の適切なバージョンがプロジェクトに含められます。

    BOM 依存関係の例:

    <dependency>
      <groupId>com.redhat.ba</groupId>
      <artifactId>ba-platform-bom</artifactId>
      <version>7.6.0.redhat-00004</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>

    Red Hat Business Automation BOM (Bill of Materials) についての詳細情報は、What is the mapping between RHDM product and maven library version? を参照してください。

  2. 以下の依存関係を pom.xml ファイルに追加して、ルールアセットが実行可能なモデルからビルドできるようにします。

    • drools-canonical-model: Red Hat Decision Manager から独立するルールセットモデルの実行可能な正規表現を有効にします。
    • drools-model-compiler: デシジョンエンジンで Red Hat Decision Manager の内部データ構造に実行可能なモデルをコンパイルします。
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-canonical-model</artifactId>
      <version>${rhdm.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-model-compiler</artifactId>
      <version>${rhdm.version}</version>
    </dependency>
  3. コマンドターミナルで Maven プロジェクトディレクトリーに移動して、以下のコマンドを実行し、実行可能なモデルからプロジェクトをビルドします。

    mvn clean install -DgenerateModel=<VALUE>

    -DgenerateModel=<VALUE> プロパティーで、プロジェクトが DRL ベースの KJAR ではなく、モデルベースの KJAR としてビルドできるようにします。

    <VALUE> は、3 つの値のいずれかに置き換えます。

    • YES: オリジナルプロジェクトの DRL ファイルに対応する実行可能なモデルを生成し、生成した KJAR から DRL ファイルを除外します。
    • WITHDRL: オリジナルプロジェクトの DRL ファイルに対応する実行可能なモデルを生成し、文書化の目的で、生成した KJAR に DRL ファイルを追加します (KIE ベースはいずれの場合でも実行可能なモデルからビルドされます)。
    • NO: 実行可能なモデルは生成されません。

    ビルドコマンドの例:

    mvn clean install -DgenerateModel=YES

Maven プロジェクトのパッケージ化に関する詳細は、Red Hat Decision Manager プロジェクトのパッケージ化およびデプロイを参照してください。

5.1.2. Java アプリケーションページへの実行可能なルールモデルの埋め込み

Java アプリケーションに実行可能ルールモデルをプログラミングを使用して埋め込み、ビルド時にルールアセットをより効率的にコンパイルすることができます。

前提条件

  • Red Hat Decision Manager ビジネスアセットを含む Java アプリケーションがある。

手順

  1. Java プロジェクトの適切なクラスパスに、以下の依存関係を追加します。

    • drools-canonical-model: Red Hat Decision Manager から独立するルールセットモデルの実行可能な正規表現を有効にします。
    • drools-model-compiler: デシジョンエンジンで Red Hat Decision Manager の内部データ構造に実行可能なモデルをコンパイルします。
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-canonical-model</artifactId>
      <version>${rhdm.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-model-compiler</artifactId>
      <version>${rhdm.version}</version>
    </dependency>

    <version> は、プロジェクトで現在使用する Red Hat Decision Manager の Maven アーティファクトバージョンです (例: 7.30.0.Final-redhat-00003)。

    注記

    個別の依存関係に対して Red Hat Decision Manager <version> を指定するのではなく、Red Hat Business Automation 部品表 (BOM) の依存関係をプロジェクトの pom.xml ファイルに追加することを検討してください。Red Hat Business Automation BOM は、Red Hat Decision Manager と Red Hat Process Automation Manager の両方に適用されます。BOM ファイルを追加すると、提供される Maven リポジトリーから、推移的依存関係の適切なバージョンがプロジェクトに含められます。

    BOM 依存関係の例:

    <dependency>
      <groupId>com.redhat.ba</groupId>
      <artifactId>ba-platform-bom</artifactId>
      <version>7.6.0.redhat-00004</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>

    Red Hat Business Automation BOM (Bill of Materials) についての詳細情報は、What is the mapping between RHDM product and maven library version? を参照してください。

  2. ルールアセットを KIE 仮想ファイルシステム KieFileSystem に追加して、KieBuilderbuildAll( ExecutableModelProject.class ) を指定して使用し、実行可能なモデルからアセットをビルドします。

    import org.kie.api.KieServices;
    import org.kie.api.builder.KieFileSystem;
    import org.kie.api.builder.KieBuilder;
    
      KieServices ks = KieServices.Factory.get();
      KieFileSystem kfs = ks.newKieFileSystem()
      kfs.write("src/main/resources/KBase1/ruleSet1.drl", stringContainingAValidDRL)
      .write("src/main/resources/dtable.xls",
        kieServices.getResources().newInputStreamResource(dtableFileStream));
    
      KieBuilder kieBuilder = ks.newKieBuilder( kfs );
      // Build from an executable model
      kieBuilder.buildAll( ExecutableModelProject.class )
      assertEquals(0, kieBuilder.getResults().getMessages(Message.Level.ERROR).size());

    実行可能なモデルから KieFileSystem をビルドした後に、作成された KieSession は効率のあまりよくない mvel 式ではなく、lambda 式をもとにした制約を使用します。buildAll() に引数が含まれていない場合には、プロジェクトは実行可能なモデルのない標準の手法でビルドされます。

    KieFileSystem を使用する代わりに、手作業を多く使用して実行可能なモデルを作成する別の方法として、Fluent API で Model を定義して、そこから KieBase を作成することができます。

    Model model = new ModelImpl().addRule( rule );
    KieBase kieBase = KieBaseBuilder.createKieBaseFromModel( model );

Java アプリケーション内でプロジェクトをプログラミングを使用してパッケージ化する方法については、Red Hat Decision Manager プロジェクトのパッケージ化およびデプロイを参照してください。