1

I'm trying to write a rule for an event that needs to check if something happens during some time window after something else happened. At the moment the code looks like this (it works correctly):

    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

At the moment the 30s is effectively hard-coded. I read that if you want to parameterize rules you need to use other facts asserted into the KB, but I can't figure out how to do it for temporal rules.

So: How can I 'configure' the 30s in this rules so that I could change the value outside of the application? Something like this: MessageHandleStartedEvent(this after [ $duration ] ...

Pieter Breed
  • 5,579
  • 5
  • 44
  • 60

1 Answers1

0

You can use templates in order to provide the hard-coded 30 from outside 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

Then, you just need to provide the 30 as a template parameter:

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);
Josep Prat
  • 493
  • 5
  • 11