【问题标题】:Drools, CEP: Collect events that are not followed by a certain eventDrools,CEP:收集某个事件后面没有的事件
【发布时间】:2021-12-17 21:56:36
【问题描述】:

我在STREAM模式下使用drools 7.29,我想收集某个事件后面没有的事件。

$transaction: TransactionOmDto(service_type == "CASHOUT", transfer_status == "TS", $requestId: transfer_id, $msisdn: msisdn) over window:length(1)

not(TransactionOmDto(service_type == "CONFIRMATION", transfer_status == "TS", transfer_id == $requestId, msisdn == $msisdn, this after [0s, 5m] $transaction))

//How to collect such $transaction in a List ???

例如在我的系统中,当我收到符合以下模式的交易$t1时,

$t1.transfer_id = "my_uniq_transfer_id"
$t1.msisdn == "07xxxxxxxx"
$t1.service_type == "CASHOUT"
$t1.transfer_status == "TS"

那么我还应该在接下来的 5 分钟内收到来自同一个 POS 的另一笔交易$t2,它应该满足以下条件:

$t2.transfer_id = "my_uniq_transfer_id"
$t2.msisdn == "07xxxxxxxx"
$t2.service_type == "CONFIRMATION"
$t2.transfer_status == "TS"

有时$t2 交易没有到达。 我的规则的目标是报告系统中没有$t2 确认交易的所有$t1 交易。

【问题讨论】:

  • 所以你想要$transation之前5分钟窗口内发生的所有事件?
  • 你好@Roddy,不。我想要在新的 5 分钟内没有被其他 TransactionOmDto 事件跟踪的所有 $transaction 与给定模式匹配,即:
    TransactionOmDto(service_type == "CONFIRMATION", transfer_status == "TS", transfer_id == $requestId, msisdn == $msisdn, this after [0s, 5m] $transaction)
  • 所以当您收到 $transaction 时,您想要接下来 5 分钟内的所有事件,除了那些看起来像您描述的 d 的事件?如果不是这样,您能否使用已接收交易的示例场景以及您希望哪些交易出现在您的收藏中来更新您的问题?
  • @RoddyoftheFrozenPeas,我以这个例子更新了这个问题。
  • 这条规则的触发器应该是什么?每次收到新交易?

标签: java drools rule-engine complex-event-processing


【解决方案1】:

常见的“心跳到达问题”。您能否从here 检查现有的简化示例是否适合您的需求。如果有任何问题,请提出其他问题。

规则

dialect 'mvel'

import TemporalReasoningTest.Heartbeat

declare Heartbeat @role (event) end

global java.io.PrintStream stdout

rule "Sound the Alarm"
when
    $h: Heartbeat() from entry-point "MonitoringStream"
    not(Heartbeat(this != $h, this after[0s,10s] $h) from entry-point "MonitoringStream")
then
    stdout.println('No heartbeat')
end

模型和测试

@DroolsSession("classpath:/temporalReasoning.drl")
public class TemporalReasoningTest {
    
    public static class Heartbeat {
        public int ordinal;
        
        public Heartbeat(int ordinal) {
            this.ordinal = ordinal;
        }
    }
    
    @RegisterExtension
    public DroolsAssert drools = new DroolsAssert();
    
    @BeforeEach
    public void before() {
        drools.setGlobal("stdout", System.out);
    }
    
    @Test
    @TestRules(expected = {})
    public void testRegularHeartbeat() {
        Heartbeat heartbeat1 = new Heartbeat(1);
        drools.insertAndFireAt("MonitoringStream", heartbeat1);
        drools.advanceTime(5, SECONDS);
        drools.assertExist(heartbeat1);
        
        Heartbeat heartbeat2 = new Heartbeat(2);
        drools.insertAndFireAt("MonitoringStream", heartbeat2);
        drools.assertExist(heartbeat1, heartbeat2);
        drools.advanceTime(5, SECONDS);
        drools.assertDeleted(heartbeat1);
        drools.assertExist(heartbeat2);
        
        Heartbeat heartbeat3 = new Heartbeat(3);
        drools.insertAndFireAt("MonitoringStream", heartbeat3);
        drools.assertExist(heartbeat2, heartbeat3);
        drools.advanceTime(5, SECONDS);
        drools.assertDeleted(heartbeat2);
        drools.assertExist(heartbeat3);
        
        Heartbeat heartbeat4 = new Heartbeat(4);
        drools.insertAndFireAt("MonitoringStream", heartbeat4);
        drools.assertExist(heartbeat3, heartbeat4);
        drools.advanceTime(5, SECONDS);
        drools.assertDeleted(heartbeat3);
        drools.assertExist(heartbeat4);
        
        drools.assertFactsCount(1);
        assertEquals(4, drools.getObject(Heartbeat.class).ordinal);
        drools.printFacts();
    }
    
    @Test
    @TestRules(expectedCount = { "1", "Sound the Alarm" })
    public void testIrregularHeartbeat() {
        drools.insertAndFireAt("MonitoringStream", new Heartbeat(1));
        drools.advanceTime(5, SECONDS);
        drools.advanceTime(5, SECONDS);
        drools.insertAndFireAt("MonitoringStream", new Heartbeat(2), new Heartbeat(3));
        drools.advanceTime(5, SECONDS);
        
        drools.assertFactsCount(2);
        drools.printFacts();
    }
}

【讨论】:

  • 你好@Mike。谢谢你的回答。我认为这条规则与我之前写的非常相似。我的问题是知道是否有可能随着时间的推移将这些Heartbeat对应于$hHeartbeat在10s内没有被其他Heartbeat跟随)收集到一个列表中。
  • 规则激活时,只需将 $h 添加到某个集合(全局变量)
  • 好的,谢谢。这就是我最终要做的,因为我不能直接使用collectaccumulate
猜你喜欢
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多