Search code examples
jbossdroolsrule-engine

entry points with the or conditon throw a exception


I want to implement a rule likes below(in stream mode):


declare EventTest
  @role( event )
  @timestamp( callDateTime )
  @duration( callDuration )
  @expires( 1h35m )
end

rule "Event2"
    when
        $m : EventTest( originNumber == "123", originNumber : originNumber )  from entry-point "ATM Stream"
        or
        $m1 : EventTest( originNumber == "456" )  from entry-point "ATM Stream"
    then
        System.out.println( originNumber );
end
public class EventTest {
    private String  originNumber;
    private String  destinationNumber;
    private Timestamp callDateTime;
    private long    callDuration;  // in milliseconds

    // Constructors, getters, and setters


    public EventTest(String originNumber,String destinationNumber,Timestamp callDateTime,long callDuration) {
        this.originNumber = originNumber;
        this.destinationNumber = destinationNumber;
        this.callDateTime = callDateTime;
        this.callDuration = callDuration;
    }

    public String getOriginNumber() {
        return originNumber;
    }

    public void setOriginNumber(String originNumber) {
        this.originNumber = originNumber;
    }

    public String getDestinationNumber() {
        return destinationNumber;
    }

    public void setDestinationNumber(String destinationNumber) {
        this.destinationNumber = destinationNumber;
    }

    public Timestamp getCallDateTime() {
        return callDateTime;
    }

    public void setCallDateTime(Timestamp callDateTime) {
        this.callDateTime = callDateTime;
    }

    public long getCallDuration() {
        return callDuration;
    }

    public void setCallDuration(long callDuration) {
        this.callDuration = callDuration;
    }
}

public class EventExample {
    public static final void main(final String[] args) throws Exception{
        // KieServices is the factory for all KIE services
        KieServices ks = KieServices.Factory.get();

        // From the kie services, a container is created from the classpath
        KieContainer kc = ks.getKieClasspathContainer();
        execute( kc );
    }

    public static void execute( KieContainer kc) throws Exception{
        // From the container, a session is created based on
        // its definition and configuration in the META-INF/kmodule.xml file

        KieSession ksession = kc.newKieSession("EventKS");


LocalTime.now().plusSeconds(3).atDate(zoneId));

        EntryPoint atmStream  = ksession.getEntryPoint("ATM Stream");


        new Thread( new Runnable() {
            @Override
            public void run() {
                ksession.fireUntilHalt();
            }
        } ).start();


        atmStream.insert(new EventTest("123","456", Timestamp.valueOf(LocalDateTime.now()),30));



        int i = 0;
        while (true){
            i++;
            atmStream.insert(new EventTest("456","789",Timestamp.valueOf(LocalDateTime.now().plusSeconds(4)),30));

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (i == 5){
                break;
            }
        }

        atmStream.insert("test string aaaa");

        ksession.halt();
        ksession.dispose();

    }
}

it throws a exception

Exception in thread "main" java.lang.RuntimeException: Error while creating KieBase[Message [id=1, kieBase=EventKS, level=ERROR, path=/home/dai/download/drools-examples-master/drools-simple-demo/target/classes/rules/Event.drl, line=45, column=0
   text=Rule Compilation error originNumber cannot be resolved to a variable]]
    at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBase(KieContainerImpl.java:379)
    at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBaseFromKieSessionModel(KieContainerImpl.java:577)
    at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:553)
    at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:523)
    at com.neo.drools.EventExample.execute(EventExample.java:35)
    at com.neo.drools.EventExample.main(EventExample.java:28)

when i set it to and ,it's normal and output the following log

123 123 123 123 123

it seams drools doesn't support the or condition for entry points ,the CompositeFactPattern also can not set or type with entry points facts,but the and condition is no problem.how can i achive this logic rule?


Solution

  • Try executing below rule and check :

    rule "Event2"
        when
            $m : EventTest( originNumber == "123", originNumber : originNumber )  from entry-point "ATM Stream"
            or
            $m1 : EventTest( originNumber == "456",originNumber : originNumber )  from entry-point "ATM Stream"
        then
            System.out.println( originNumber );
    end