LoginSignup
9
5

More than 3 years have passed since last update.

Red Hat Decision Manager - Decision Serverにルールをデプロイして呼び出す -

Last updated at Posted at 2018-08-16

Red Hat Decision Manager 7.0には、Decision Serverという機能があります。
ルールを書いてビルド後、この Decision Serverにデプロイすると、すぐにRESTのサービスとしてルールを実行することができる、というものです。
以前のバージョンにもあったのですが、7.0からは、Decision Serverを単体で使うこともできるようになり、便利になりました。

ということで、今回は、Decision Serverの構築方法と、ルールのデプロイ・実行方法について書きます。

注)記事内容はすべて個人の見解に基づくものであり、RedHat社の公式見解ではありません。

Decision Server構築に必要な環境を整える

Decision Serverは、APサーバ上にデプロイして使うものです。「.war」形式で提供されます。
ちなみに、warの名前は、kie-server.warです。なので、Kie Serverという言われ方をすることもあります。以前はExecution Serverと言ったりもしていました。全部同じものを指していると思ってください。

さて、まずはAPサーバが必要です。
Red Hat Decision Managaer 7.0において、Decision Serverをデプロイ可能な基盤は以下。

スクリーンショット 2018-08-15 16.23.54.png

ここでは、JBoss EAP7.1を使いたいと思います。
ちなみに、Red Hat Decision Managerを正式にサブスクリプション契約すると、JBoss EAPも使うことができます。なので、よほどの事情がない限り、APサーバはJBoss EAPを選択しておけばよいです。

必要なもの

  • JDK 1.8
  • Red Hat JBoss EAP 7.1
  • Red Hat Decision ManagerのDecision Server

EAPとDecision Serverについては、Red Hatのサイトからダウンロードする必要があります。
Red Hat Customer Portalからダウンロードが可能です。

上記サイトで「Request an Evaluation」というリンクがありますので、そこをクリックして、アカウント無い人は、個人アカウントでもなんでも作成することで、90日間の評価版がダウンロード出来ます。
評価版といっても、製品版と中身はまったく同じです。とりあえず使うだけならば、ここから自由にダウンロードが出来るようになっています。(一部製品を除く)

スクリーンショット 2018-08-15 16.32.49.png

まずは、EAPを上記からダウンロードします。
バージョンは、7.1をダウンロードします。インストーラーからインストールしてもよいですが、以下をダウンロードして、解凍するだけでもOKです。

スクリーンショット 2018-08-15 16.36.17.png

次に、Decision Serverをダウンロードして、EAP上にデプロイします。
同じく、Red Hat Customer Portalから、ダウンロードします。

スクリーンショット 2018-08-15 16.39.01.png

Red Hat Decision Manager 7.0.1 Decision Server for All Supported EE7 Containersを選択します。

スクリーンショット 2018-08-15 16.42.20.png

zip(rhdm-7.0.1.GA-kie-server-ee7.zip)がダウンロードされるので、解凍します。
解凍すると、kie-server.warというディレクトリがあるのがわかると思います。

Decision Serverのデプロイ

  1. rhdm-7.0.1.GA-kie-server-ee7/kie-server.warディレクトリを、EAP_HOME/standalone/deployments/ にコピーする
  2. rhdm-7.0.1.GA-kie-server-ee7/SecurityPolicyディレクトリを、EAP_HOME/bin に上書きする
  3. EAP_HOME/standalone/deployments/に、kie-server.war.dodeployというファイルを作成する。(中身は空でOK。このファイルがあると、EAP起動時にkie-server.warが自動デプロイされる)

以上です。

Decision Serverの起動

EAPを起動します。
が、その前にユーザを作っておきます。

ユーザを追加するシェルは、EAP_HOME/bin/add-user.shです。

$ ./add-user.sh -a --user <USERNAME>  --password <PASSWORD> --role kie-server,admin

kie-serverとadminのロールを与える必要があります。
ここでは、USERNAME = redhat, PASSWORD = password1! として作成しました。
(パスワードは、8文字以上で、数値と記号をそれぞれ1つ以上入れる必要があります)

ユーザを追加後、EAPを起動します。

$ ./standalone.sh -c standalone-full.xml

起動が成功したら、Decision Serverにアクセスしてみましょう。
RESTfulのインターフェースで実行ができるところからであれば、確認が可能です。
とりあえず、ブラウザに以下を入力して実行してみましょう。

http://localhost:8080/kie-server/services/rest/server

これは、Decision Serverの情報を取得するREST APIです。
XML形式でレスポンスが表示されるはずです。"SUCCESS"とあれば、Decision Serverにアクセス出来ています。

curlコマンドから実行することも可能です。

curl -X GET "http://localhost:8080/kie-server/services/rest/server" -H "accept: application/json" -u <USERNAME>:<PASSWORD>

USERNAMEPASSWORDは、add-userで追加したユーザとパスワードをセット。

レスポンスで、"SUCCESS"が帰ってきていたら、Decision Serverにアクセス出来ています。
レスポンス例

{
  "type" : "SUCCESS",
  "msg" : "Kie Server info",
  "result" : {
    "kie-server-info" : {
      "id" : "15ad5bfa-7532-3eea-940a-abbbbc89f1e8",
      "version" : "7.5.0.Final-redhat-6",
      "name" : "KieServer@/kie-server",
      "location" : "http://localhost:8230/kie-server/services/rest/server",
      "capabilities" : [ "KieServer", "BRM", "BPM", "CaseMgmt", "BPM-UI", "BRP", "DMN", "Swagger" ],
      "messages" : [ {
        "severity" : "INFO",
        "timestamp" : {
  "java.util.Date" : 1534320753784
},
        "content" : [ "Server KieServerInfo{serverId='15ad5bfa-7532-3eea-940a-abbbbc89f1e8', version='7.5.0.Final-redhat-6', location='http://localhost:8230/kie-server/services/rest/server', capabilities=[KieServer, BRM, BPM, CaseMgmt, BPM-UI, BRP, DMN, Swagger]}started successfully at Wed Aug 15 17:12:33 JST 2018" ]
      } ]
    }
  }

swagger

Decision Serverで使えるREST API一覧は、swaggerでリストされています。
Decision Serverが起動している状態で、以下にアクセスしてみてください。
swagger UIの画面が表示されます。

http://localhost:8080/kie-server/docs/

スクリーンショット 2018-08-15 17.28.34.png

kie-server.warは、Red Hat Process Automation ManagementというBPM製品でも使われるもののため、Decision Managerでは使われないAPIもずらっとリストされます。
ルール実行で使うAPIは、
Kie Server::CORE、Decision Service::DMN、Rules Evalutaion::BRM
のあたりだけです。

追記:
kie-serverをDecision Serverとしてだけ使う場合、EAP起動時に、-Dorg.jbpm.server.ext.disabled=trueオプションを付与すると、BPM関連のAPIが除外されます。
EAPの起動時オプションは、EAP_HOME/bin/standalone.confを修正すればいちいち付けなくてよいです。

このswagger UIから、REST実行も可能になっています。

ルールをDecision Serverにデプロイする

Decision Serverでは、ルール実行単位、デシジョンサービス単位に、Kie Containerというのを作る必要がある。
まずは、Kie Containerを作るところから。
Kie Containerは、任意のIDを付け、どのルールパッケージを実行するのかを指定する必要がある。
ルールパッケージは、MavenのGAV(GroupID,ArtifactID,Version)を指定する。

事前に、ルールパッケージを作っておく必要があるわけだが、ここでは、
Red Hat Decision Managerをとりあえず触ってみたい場合 -サンプルプロジェクト実行編-
で作成した、サンプルプロジェクトを使うことにします。
ただし、いくつか手をいれる必要があります。

修正点1 pom.xmlの修正

pom.xml
  <dependencies>
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-api</artifactId>
      <version>${runtime.version}</version>
      <scope>provided</scope>   ← ここを追加すればOK
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-core</artifactId>
      <version>${runtime.version}</version>
      <scope>provided</scope>  ← ここを追加すればOK
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-decisiontables</artifactId>
      <version>${runtime.version}</version>
      <scope>provided</scope> ← ここを追加すればOK
    </dependency>
    <dependency>
      <groupId>org.jbpm</groupId>
      <artifactId>jbpm-test</artifactId>
      <version>${runtime.version}</version>
      <scope>provided</scope> ← ここを追加すればOK
    </dependency>

org.drools,org.jbpm等のjarは、Decision Server内のものを参照するため、dependencyのscopeを変更します。

修正点2 Messageファクトクラスを作成

サンプルプロジェクトでは、Messageファクトは、com.sample.DroolsTestクラス内のインナークラスとして定義されていましたが、独立したクラスとして定義します。

Message.java
package com.sample;

public class Message {

    @Override
    public String toString() {
        return "Message [message=" + message + ", status=" + status + "]";
    }

    public static final int HELLO = 0;
    public static final int GOODBYE = 1;

    private String message;

    private int status;

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getStatus() {
        return this.status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

}

また、上記により、Messageファクトのパッケージが変更になりますので、drlのimport文も修正します。

Sample.drl
package com.sample

import com.sample.Message;   ←ここを変更

以下略

サンプルプロジェクトを、Maven Installします。Decision Serverはデフォルトでは、ローカルの.m2ディレクトリを見に行きます。

サンプルプロジェクトのGAVは以下の通り。

pom.xml
  <groupId>com.sample</groupId>
  <artifactId>Sampleprj</artifactId>
  <version>1.0.0-SNAPSHOT</version>

Kie ContainerIDはなんでもよいので、ここでは、testconとします。

Kie Containerを新規作成するAPIは、これです。

[PUT]/server/containers/{id}

idは、Kie ContainerID

bodyには、GAVを指定します。

{
  "release-id": {
    "group-id": "com.sample",
    "artifact-id": "Sampleprj",
    "version": "1.0.0-SNAPSHOT"
  }
}

そして、REST実行。

curlコマンドからでもいいですが、swaggerUIからの実行が簡単です。
swaggerUIで、実行するAPIを検索して、「Try it out」をクリック。
スクリーンショット 2018-08-15 23.50.59.png

必須パラメータと、body部を記入して、「Execute」を実行。リクエスト・レスポンスの形式は、xmlかjsonかを選択出来ます。

スクリーンショット 2018-08-15 23.49.47.png

さて、ここで「Execute」を押して、Kie Containerの作成が成功すれば、サンプルプロジェクトのルールがデプロイされたことになります。Kie Containerは作成すると同時に開始します。
成功した場合、EAPのサーバログには以下のようなログが出されます。

23:38:06,768 INFO  [org.kie.server.services.impl.KieServerImpl] (EJB default - 1) Container testcon (for release id com.sample:Sampleprj:1.0.0-SNAPSHOT) successfully started

Kie Containerの作成(ルールのデプロイ)に失敗する場合

Cannot find kbase, either it does not exist or there are multiple default kbases in kmodule.xml というエラーになる場合

23:29:07,431 ERROR [org.kie.server.services.jbpm.JbpmKieServerExtension] (default task-5) Error when creating container testcon by extension jBPM KIE Server extension: java.lang.RuntimeException: java.lang.IllegalStateException: Cannot find kbase, either it does not exist or there are multiple default kbases in kmodule.xml

これは、上のほうの追記にも書きましたが、EAP起動時オプションに、-Dorg.jbpm.server.ext.disabled=trueを付けたら、解消されました。

大量のWARNログが出る

Kie Container作ろうとすると、以下のようなWARNログが大量に出る、という場合は、ルールパッケージのdependencyに原因がある可能性が高い。

02:48:20,141 WARN  [org.kie.server.services.drools.DroolsKieServerExtension] (EJB default - 1) Unexpected error while create instance of type org.dom4j.xpath.DefaultNamespaceContext due to Failed to link org/dom4j/xpath/DefaultNamespaceContext (Module "deployment.kie-server.war" from Service Module Loader): org/jaxen/NamespaceContext
02:48:20,189 WARN  [org.kie.server.services.drools.DroolsKieServerExtension] (EJB default - 1) Unable to create instance of type org.jaxen.expr.iter.IterableFollowingSiblingAxis due to org.jaxen.expr.iter.IterableFollowingSiblingAxis
02:48:20,191 WARN  [org.kie.server.services.drools.DroolsKieServerExtension] (EJB default - 1) Unable to create instance of type org.jaxen.expr.iter.IterableAncestorAxis due to org.jaxen.expr.iter.IterableAncestorAxis

サンプルプロジェクトのpom.xmlを見ると、org.droolsやorg.jbpmのjarを参照していると思います。
これらは、Decision Server上で提供されるため、build packageの際に含めないように、スコープをprovidedにする必要があります。

pom.xml
  <dependencies>
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-api</artifactId>
      <version>${runtime.version}</version>
      <scope>provided</scope>   ← ここを追加すればOK
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-core</artifactId>
      <version>${runtime.version}</version>
      <scope>provided</scope>  ← ここを追加すればOK
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-decisiontables</artifactId>
      <version>${runtime.version}</version>
      <scope>provided</scope> ← ここを追加すればOK
    </dependency>
    <dependency>
      <groupId>org.jbpm</groupId>
      <artifactId>jbpm-test</artifactId>
      <version>${runtime.version}</version>
      <scope>provided</scope> ← ここを追加すればOK
    </dependency>

このWARNログが出た場合、Kie Containerの作成は成功したように見えても、その後のルール実行がうまくいかないので、注意が必要です。

ルールを実行する

さて、それでは、デプロイしたサンプルルールをRESTで実行してみたいと思います。
ルール実行のAPIは、以下です。

[POST]/server/containers/instances/{id}

idは、testcon
body部に、ルール実行に関するコマンドや、ルールに渡すデータ(ファクト)を指定します。

たとえば、こんな感じです。

{
  "lookup": "ksession-rules",
  "commands":[
    {
      "insert":{
         "object":{
            "com.sample.Message":{
                     "message": "Hello World",
                     "status": 0
            }
         }
      }
    },
    {"fire-all-rules":""}
  ]
}
name description
lookup 実行するkie-session名を指定する。(kmodule.xmlで指定した値)
commands BatchExecutionCommandを渡す。
複数ある場合は、リスト形式で。
(ここでは、insertとfire-all-rulesの2つ)
insert InsertObjectCommand実行。
object インサートするオブジェクト。
fire-all-rules FireAllRulesCommand実行。

複数のファクトを渡したい場合は、insertを繰り返します。↓こんな感じです。

  {"insert":
    {"object":{"com.sample.Message":{
                "message":"hello1",
                "status":0
               }
              }
    }
  },
  {"insert":
    {"object":{"com.sample.Message":{
                "message":"hello2",
                "status":0
               }
              }
    }
  },

さて、ルール実行が成功すると、サンプルプロジェクトをローカルで実行した際と同様のログが、EAPのサーバログに出力されるはずです。

00:49:48,935 INFO  [stdout] (default task-49) Hello World
00:49:48,936 INFO  [stdout] (default task-49) Goodbye cruel world

ルール実行結果を返したい場合

ルール実行後のファクトを取得したい場合は、取得したいファクトにout-identifierでキー名をつけます。

{
  "lookup": "ksession-rules",
  "commands":[
    {
      "insert":{
         "object":{
            "com.sample.Message":{
                     "message": "Hello World",
                     "status": 0
            }
         },
         "out-identifier": "fact1"
      }
    },
    {"fire-all-rules":""}
  ]
}

すると、レスポンスがこのようになります。

{
  "type" : "SUCCESS",
  "msg" : "Container testcon successfully called.",
  "result" : {
    "execution-results" : {
      "results" : [ {
        "value" : {"com.sample.Message":{
  "message" : "Goodbye cruel world",
  "status" : 1
}},
        "key" : "fact1"
      } ],
      "facts" : [ {
        "value" : {"org.drools.core.common.DefaultFactHandle":{
  "external-form" : "0:1:279781204:279781204:2:DEFAULT:NON_TRAIT:com.sample.Message"
}},
        "key" : "fact1"
      } ]
    }
  }
}

ちなみに、このようなJSONをいちいち作成していられないので、もともとクライアント用のJavaクラスが用意されています。
このクライアントの使い方については、また別の投稿で。

9
5
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5