使用反应流作为Drools的数据源

几个月前,我们开始重新设计Drools最低级别的可执行模型 ,并使最终用户可以使用Java 8 API进行访问。 为了证明这种方法的灵活性,我尝试将其与反应流集成在一起,尤其是将该流用作Drools的数据源。

为了说明这是如何工作的,我创建了一个简单的温度服务器,该服务器提供RxJava Observable每秒发射给定镇的温度,并在5秒钟后终止。 还有第二种工厂方法,该方法允许合并更多的这些Observable,以使一个Observable可以同时发射一个以上城镇的温度。

public class TempServer {
    public static Observable<TempInfo> getFeed(String town) {
        return Observable.create(subscriber ->
                                         Observable.interval(1, TimeUnit.SECONDS)
                                                   .subscribe(i -> {
                                                       if (i > 5) subscriber.onCompleted();
                                                       try {
                                                           subscriber.onNext(TempInfo.fetch(town));
                                                       } catch (Exception e) {
                                                           subscriber.onError(e);
                                                       }
                                                   }));
    }

    public static Observable<TempInfo> getFeeds(String... towns) {
        return Observable.merge(Arrays.stream(towns)
                                      .map(TempServer::getFeed)
                                      .collect(toList()));
    }
}

其中TempInfo.fetch方法仅返回-20至50度之间的随机温度

public TempInfo(String town, int temp) {
    this.town = town;
    this.temp = temp;
}

public static TempInfo fetch(String town) {
    return new TempInfo(town, random.nextInt(70) - 20);
}

使用前一篇文章中介绍的Java 8 DSL的改进版本,我定义了以下2条规则:

Variable<TempInfo> temp = any( TempInfo.class );
Variable<Person> person = any( Person.class );

Rule r1 = rule("low temp")
        .view(
                subscribe(temp, "tempFeed"),
                expr(temp, t -> t.getTemp() < 0),
                input(person, "persons"),
                expr(person, temp, (p, t) -> p.getTown().equals(t.getTown()))
             )
        .then(on(person, temp)
                      .execute((p, t) -> System.out.println(p.getName() + " is freezing in " + p.getTown() + " - temp is " + t.getTemp())));

Rule r2 = rule("high temp")
        .view(
                subscribe(temp, "tempFeed"),
                expr(temp, t -> t.getTemp() > 30),
                input(person, "persons"),
                expr(person, temp, (p, t) -> p.getTown().equals(t.getTown()))
             )
        .then(on(person, temp)
                      .execute((p, t) -> System.out.println(p.getName() + " is sweating in " + p.getTown() + " - temp is " + t.getTemp())));

在这里,我使用2种不同的数据源:一个被动的数据源,可以将其视为事实的存储:

DataStore persons = storeOf(new Person("Mark", 37, "London"),
                            new Person("Edson", 35, "Toronto"),
                            new Person("Mario", 40, "Milano"));

可以绑定到特定的Drools KieSession与

bindDataSource(ksession, "persons", persons);

以及从上面实现的TempServer中获取的一个响应式

Observable<TempInfo> tempFeed = TempServer.getFeeds( "Milano", "London", "Toronto" );

也可以以类似的方式绑定到相同的KieSession

bindRxObservable( ksession, "tempFeed", tempFeed );

完成此操作后,您可以触发这两个规则并获得如下输出:

Mark is freezing in London - temp is -9
Edson is sweating in Toronto - temp is 42
Mario is sweating in Milano - temp is 42
Mario is sweating in Milano - temp is 49
Mark is freezing in London - temp is -17
Edson is sweating in Toronto - temp is 40
Edson is sweating in Toronto - temp is 47
Mario is freezing in Milano - temp is -14
Mark is freezing in London - temp is -8
Mark is freezing in London - temp is -17
  • 在此处找到运行此示例的完整测试用例。

翻译自: https://www.javacodegeeks.com/2015/11/using-a-rective-stream-as-a-data-source-for-drools.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值