Drools in Spring Boot

Droolsを組み込んだSpringBootプロジェクトを作ってみました。

当プロジェクトを実行しブラウザから http://localhost:8080/getDiscount?type=diamond にアクセスすると、SpringBootプロジェクトに組み込んだルールエンジンが走ります。そして、結果をJSON形式で次のように返却してくれます。(ブラウザに表示されます)

{"type":"diamond","discount":15}

1. 全体構成

全体の構成はこんな感じになります。

2. ライブラリ追加

まずは必要なライブラリを追加しましょう。pom.xmlのdependencies 要素配下に dependency を2つ追加します。

pom.xml
<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-decisiontables</artifactId>
  <version>${kie.version}</version>
</dependency>
<dependency>
  <groupId>org.kie</groupId>
  <artifactId>kie-ci</artifactId>
  <version>${kie.version}</version>
</dependency>

properties 要素配下で kie.version を指定します。

<kie.version>6.1.0.Final</kie.version>

3. ソースコードの作成

src/main/javaにソースコードを追加していきます。

3.1 controllerの作成

まずフロント処理とのやりとりをするControllerクラスを次のとおりに作成します。

JewelleryShopController.java
package com.javainuse.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.javainuse.model.Product;
import com.javainuse.service.JewelleryShopService;

@RestController
public class JewelleryShopController {

  private final JewelleryShopService jewelleryShopService;

  @Autowired
  public JewelleryShopController(JewelleryShopService jewelleryShopService) {
    this.jewelleryShopService = jewelleryShopService;
  }

  @RequestMapping(value = "/getDiscount", method = RequestMethod.GET, produces = "application/json")
  public Product getQuestions(@RequestParam(required = true) String type) {

    Product product = new Product();
    product.setType(type);
    jewelleryShopService.getProductDiscount(product);

    return product;
  }
}

3.2 Modelの作成

データをマッピングするModelクラスを次のとおり作成します。

Product.java
package com.javainuse.model;

public class Product {

  private String type;
  private int discount;

  public String getType() {
    return type;
  }

  public void setType(String type) {
    this.type = type;
  }

  public int getDiscount() {
    return discount;
  }

  public void setDiscount(int discount) {
    this.discount = discount;
  }
}

3.3     Serviceの作成

キーの処理、ルールエンジンの処理を実行するServiceクラスを次のとおり作成します。

JewelleryShopService.java
package com.javainuse.service;

import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.javainuse.model.Product;

@Service
public class JewelleryShopService {
  private final KieContainer kieContainer;

  @Autowired
  public JewelleryShopService(KieContainer kieContainer) {
    this.kieContainer = kieContainer;
  }

  public Product getProductDiscount(Product product) {
    KieSession kieSession = kieContainer.newKieSession("rulesSession");
    kieSession.insert(product);
    kieSession.fireAllRules();
    kieSession.dispose();
    
    return product;
  }
}

3.4 main作成

設定を読み込むmain処理を次のとおり作成します。設定内容は後述します。

SpringBootDroolsHelloWorldApp.java
package com.javainuse;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringBootDroolsHelloWorldApp {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootDroolsHelloWorldApp.class, args);
  }

  @Bean
  public KieContainer kieContainer() {
    return KieServices.Factory.get().getKieClasspathContainer();
  }
}

4. 設定の作成

src/main/resourcesに設定を追加していきます。META-INFフォルダを作成します。その中に設定内容であるkmodule.xmlを作成します。

kmodule.xml
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <kbase name="rules" packages="rules">
    <ksession name="rulesSession" />
  </kbase>
</kmodule>

5. ルールの作成

ここに作成したルールを追加します。rulesフォルダを作成します。その中に今回は次のようなルールを作成し、この場所に配置しました。

rules.xls

6. 実行

プロジェクトを右クリックしてRun As -> Spring Boor Appして実行しましょう。

http://localhost:8080/getDiscount?type=diamond にアクセスしてみましょう。

ブラウザに次のように表示されたらこのサンプルアプリ作り完了です。

{"type":"diamond","discount":15}

7. まとめ

Spring BootからDroolsを使用することが出来ました。このように一度サンプルを作成してしまえば応用は簡単にできるかと思います。

少しハマったポイントとして、Spring Boot の devtools を使用していると ルールが実行されませんでした。ですので、devtools は予め使用しないようにしておくといいかと思います。

参考情報

https://access.redhat.com/documentation/ja-jp/jboss_enterprise_soa_platform/5/html/jboss_rules_5_reference_guide/chap-language_reference