как написать динамические временные правила в drools-fusion

Я пытаюсь написать правило для события, которое должно проверять, происходит ли что-то в течение некоторого временного окна после того, как что-то еще произошло. На данный момент код выглядит так (работает корректно):

    rule "Detect BPM reseed not starting when requested from Mart"
        when
            $martDailyRefreshRequestedEvent: MessageSentEvent(
                $correlationId: correlationId,
                $when: timestamp,
                messageTypeName == "MartDailyRefreshCompletedEvent")
                    from entry-point "mart"
            not ( MessageHandleStartedEvent(
                    this after[0ms, 30s] $martDailyRefreshRequestedEvent, 
                    correlationId == $correlationId,
                    messageTypeName == "MartDailyRefreshCompletedEvent") 
                            from entry-point "bpm")
        then
            notifier.notify("BPM not responding to MartDailyRefreshCompletedEvent quick enough", 
                String.format(
                    "At **%s** Mart sent out a **MartDailyRefreshCompletedEvent**.\n\n**BPM** was supposed to react to it within **30 seconds**.",
                    $when));
    end

На данный момент 30s фактически жестко закодирован. Я читал, что если вы хотите параметризовать правила, вам нужно использовать другие факты, указанные в базе знаний, но я не могу понять, как это сделать для временных правил.

Итак: как я могу «настроить» 30s в этих правилах, чтобы я мог изменить значение вне приложения? Что-то вроде этого: MessageHandleStartedEvent(this after [ $duration ] ...


person Pieter Breed    schedule 30.09.2013    source источник


Ответы (1)


Вы можете использовать шаблоны, чтобы предоставить жестко закодированные 30 извне Drools.

template dynamicTimer
rule "Detect BPM reseed not starting when requested from Mart"
    when
        $martDailyRefreshRequestedEvent: MessageSentEvent(
            $correlationId: correlationId,
            $when: timestamp,
            messageTypeName == "MartDailyRefreshCompletedEvent")
                from entry-point "mart"
        not ( MessageHandleStartedEvent(
                this after[0ms, @{timeout}s] $martDailyRefreshRequestedEvent, 
                correlationId == $correlationId,
                messageTypeName == "MartDailyRefreshCompletedEvent") 
                        from entry-point "bpm")
    then
        notifier.notify("BPM not responding to MartDailyRefreshCompletedEvent quick enough", 
            String.format(
                "At **%s** Mart sent out a **MartDailyRefreshCompletedEvent**.\n\n**BPM** was supposed to react to it within **@{timeout} seconds**.",
                $when));
end
end template

Затем вам просто нужно указать 30 в качестве параметра шаблона:

ObjectDataCompiler converter = new ObjectDataCompiler();
InputStream templateStream = getClass().getResourceAsStream(resource.getFilePath());
Collection<Map<String, String>> paramMaps = new ArrayList<>();
Map<String,String> param = new HashMap<>();
param.put("timeout", "30");
paramMaps.add(param);
String drl = converter.compile(paramMaps, templateStream);
Reader rdr = new StringReader(drl);
kbuilder.add(ResourceFactory.newReaderResource(rdr), ResourceType.DRL);
person Josep Prat    schedule 19.02.2015