Contents

Drools 使用 Excel 文件中的规则

1. 概述

Drools 支持以电子表格格式管理业务规则。

在本文中,我们将看到一个使用 Drools 通过 Excel 文件管理业务规则的快速示例。

2. Maven依赖

让我们将所需的 Drools 依赖项添加到我们的应用程序中:

<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-ci</artifactId>
    <version>7.1.0.Beta2</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-decisiontables</artifactId>
    <version>7.1.0.Beta2</version>
</dependency>

这些依赖项的最新版本可以在kie-cidrools-decisiontables 中找到。

3. 在 Excel 中定义规则

对于我们的示例,让我们定义规则以根据客户类型和客户年数确定折扣:

  • 3年以上的个人客户享受15%的折扣
  • 3年以下的个人客户享受5%的折扣
  • 所有商务客户均可享受 20% 的折扣

3.1. Excel 文件

/uploads/drools_excel/1.png

对于我们的简单示例,我们使用了最相关的一组关键字:

  • RuleSet – 表示决策表的开始
  • Import – 规则中使用的 Java 类
  • RuleTable – 表示规则集的开始
  • Name - 规则的名称
  • CONDITION – 要根据输入数据检查的条件的代码片段。规则应至少包含一个条件
  • ACTION – 满足规则条件时要执行的操作的代码片段。规则应至少包含一项操作。在示例中,我们在Customer对象上调用setDiscount

此外,我们在 Excel 文件中使用了Customer类。所以,让我们现在创建它。

3.2. Customer

从 Excel 表中的 CONDITIONs 和 ACTION 可以看出,我们使用Customer类的对象作为输入数据(typeyears)并存储结果(discount)。

Customer类:

public class Customer {
    private CustomerType type;
    private int years;
    private int discount;
    // Standard getters and setters
    public enum CustomerType {
        INDIVIDUAL,
        BUSINESS;
    }
}

4. 创建 Drools 规则引擎实例

在我们可以执行我们定义的规则之前,我们必须使用 Drools 规则引擎的一个实例。为此,我们必须使用 Kie 核心组件。

4.1. KieServices

KieServices类提供对所有 Kie 构建和运行时设施的访问。它提供了几种工厂、服务和实用方法。所以,让我们首先获取一个KieServices实例:

KieServices kieServices = KieServices.Factory.get();

使用 KieServices,我们将创建KieFileSystemKieBuilderKieContainer的新实例。

4.2. KieFileSystem

KieFileSystem是一个虚拟文件系统。让我们将 Excel 电子表格添加到其中:

Resource dt 
  = ResourceFactory
    .newClassPathResource("com/blogdemo/drools/rules/Discount.xls",
      getClass());
KieFileSystem kieFileSystem = kieServices.newKieFileSystem().write(dt);

4.3. KieBuilder

现在,通过将KieFileSystem的内容传递给KieBuilder来构建它:

KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();

如果成功构建,它会创建一个KieModule (任何 Maven 生成的带有 kmodule.xml 的 jar 都是KieModule)。

4.4. KieRepository

该框架自动将KieModule(由构建产生)添加到KieRepository

KieRepository kieRepository = kieServices.getRepository();

4.5. KieContainer

现在可以使用这个KieModule使用它的ReleaseId创建一个新的KieContainer。在这种情况下,Kie 分配了一个默认的ReleaseId

ReleaseId krDefaultReleaseId = kieRepository.getDefaultReleaseId();
KieContainer kieContainer 
  = kieServices.newKieContainer(krDefaultReleaseId);

4.6. KieSession

我们现在可以从KieContainer获取KieSession。我们的应用程序与KieSession交互,它存储和执行运行时数据:

KieSession kieSession = kieContainer.newKieSession();

5. 执行规则

最后,是时候提供输入数据并触发规则了:

Customer customer = new Customer(CustomerType.BUSINESS, 2);
kieSession.insert(customer);
kieSession.fireAllRules();

6. 测试用例

现在让我们添加一些测试用例:

public class DiscountExcelIntegrationTest {
    private KieSession kSession;
    @Before
    public void setup() {
        Resource dt 
          = ResourceFactory
            .newClassPathResource("com/blogdemo/drools/rules/Discount.xls",
              getClass());
        kSession = new DroolsBeanFactory().getKieSession(dt);
    }
    @Test
    public void 
      giveIndvidualLongStanding_whenFireRule_thenCorrectDiscount() 
        throws Exception {
        Customer customer = new Customer(CustomerType.INDIVIDUAL, 5);
        kSession.insert(customer);
        kSession.fireAllRules();
        assertEquals(customer.getDiscount(), 15);
    }
    @Test
    public void 
      giveIndvidualRecent_whenFireRule_thenCorrectDiscount() 
      throws Exception {
        Customer customer = new Customer(CustomerType.INDIVIDUAL, 1);
        kSession.insert(customer);
        kSession.fireAllRules();
        assertEquals(customer.getDiscount(), 5);
    }
    @Test
    public void 
      giveBusinessAny_whenFireRule_thenCorrectDiscount() 
        throws Exception {
        Customer customer = new Customer(CustomerType.BUSINESS, 0);
        kSession.insert(customer);
        kSession.fireAllRules();
        assertEquals(customer.getDiscount(), 20);
    }
}

7. 故障排除

Drools 将决策表转换为DRL 。因此,处理 Excel 文件中的错误和拼写错误可能很困难。错误通常与 DRL 的内容有关。因此,要进行故障排除,打印和分析 DRL 会有所帮助:

Resource dt 
  = ResourceFactory
    .newClassPathResource("com/blogdemo/drools/rules/Discount.xls",
      getClass());
DecisionTableProviderImpl decisionTableProvider 
  = new DecisionTableProviderImpl();
 
String drl = decisionTableProvider.loadFromResource(dt, null);