[rules-users] window:length with variables as constraints not working correctly

Andreas an.salden at googlemail.com
Thu Apr 25 08:58:45 EDT 2013


Hello, 

I'm having a problem using sliding windows length 

I would like to get the average oft he last 5 Events of the AccountNumber
"123" 
(rule: FiveLastEventsWhichBelongsToTheAccount).

If there are no Events with other AccountNumbers and if the AccountNumber is
directly added as String as a rule constraint, both cases will work
correctly as I understand the rule behaviour

But 

If there are Events available for different AccountNumbers and the
AccountNumber is extracted from the $account : Account() to use it as a
constraint to check if the Event belongs to the AccountNumber the condition
is not working like first filter then window; it seems to work like first
window then filter)

I don’t know if it should work like this or if it is maybe a bug.
If I’m wrong, how is it possible to solve my problem, so that I don’t need
to write a rule for every possible account number.


Thanks in advanced
Andreas

 
I’m using drools version 5.3.5 because of the NPE (
https://issues.jboss.org/browse/DROOLS-78?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel),
which don’t occurs in this test case but in other rules I’ve implemented. So
it would be nice to have a solution for version 5.3.5. 


For Testing you can use the following classes and drl File:

public class Account {
	private String number = "";
	
	public Account() {
		super();
	}
	
	public String getNumber() {
		return number;
	}
	public void setNumber(String number) {
		this.number = number;
	}
}

public class Event implements Serializable {
	
	private static final long serialVersionUID = 1L;
	
	private String accountNumber = "";
	private double amount = 0.00;
	
	public Event(String accountNumber, double amount) {
		this.accountNumber = accountNumber;
		this.amount = amount;
	}
	public String getAccountNumber() {
		return accountNumber;
	}
	public void setAccountNumber(String accountNumber) {
		this.accountNumber = accountNumber;
	}
	public double getAmount() {
		return amount;
	}
	public void setAmount(double amount) {
		this.amount = amount;
	}
}

Rule file
declare Event
	@role( event )
end

rule "FiveLastEventsWhichBelongsToTheAccount"

when
	$account : Account()
	
	$averageOfAmount : Number( doubleValue > 0 ) 
	from accumulate(
		Event(
			//accountNumber == “123“,  //works
                          accountNumber == $account.number, //not working if
more than one
                                                                            
//AccountNumbers available during all events

			$amount : amount
		) 
		over window:length( 5 ) from 
		entry-point EventStream, 
		average($amount)
	)

then

	System.out.println("Average of aveOfLastClaims: " + $averageOfAmount);
End


TesterClass:

public class Tester {

	private static final String DRL_FILENAME = "account.drl";
	private static final String ENTRY_POINT = "EventStream";

	private static KnowledgeBase knowledgeBase = null;
	private static StatefulKnowledgeSession session = null;

	private static Account account123 = null;
	private static String accountNumber123 = "123";
	private static Account account456 = null;
	private static String accountNumber456 = "456";

	private static void setUp() {
		prepareKnowledgeBase();
		prepareStatefulKnowledgeSession();
		prepareAccounts();
	}

	private static void prepareAccounts() {
		account123 = new Account();
		account123.setNumber(accountNumber123);
		
		account456 = new Account();
		account456.setNumber(accountNumber456);
	}

	private static void prepareStatefulKnowledgeSession() {
		KnowledgeSessionConfiguration sessConfig =
KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
		sessConfig.setOption(ClockTypeOption.get("pseudo"));
		session = knowledgeBase.newStatefulKnowledgeSession(sessConfig, null);
	}

	private static void prepareKnowledgeBase() {
		try {

			KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
			builder.add(ResourceFactory.newClassPathResource(DRL_FILENAME),
ResourceType.DRL);
			KnowledgeBuilderErrors errors = builder.getErrors();
			if (errors.size() > 0) {
				for (KnowledgeBuilderError error : errors) {
					System.err.println(error);
				}
				throw new IllegalArgumentException("Could not parse knowledge.");
			}

			knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
			knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		
		setUp();

		try {

			SessionPseudoClock clock = session.getSessionClock();

			WorkingMemoryEntryPoint eventStream =
session.getWorkingMemoryEntryPoint(ENTRY_POINT);

			eventStream.insert(new Event(accountNumber123, 50.00));
			eventStream.insert(new Event(accountNumber456, 500.00));
			clock.advanceTime(5, TimeUnit.DAYS);

			eventStream.insert(new Event(accountNumber123, 40.00));
			eventStream.insert(new Event(accountNumber456, 400.00));
			clock.advanceTime(10, TimeUnit.DAYS);

			eventStream.insert(new Event(accountNumber123, 30.00));
			eventStream.insert(new Event(accountNumber456, 300.00));
			clock.advanceTime(15, TimeUnit.DAYS);

			eventStream.insert(new Event(accountNumber123, 20.00));
			eventStream.insert(new Event(accountNumber456, 200.00));
			clock.advanceTime(20, TimeUnit.DAYS);

			eventStream.insert(new Event(accountNumber123, 10.00));
			eventStream.insert(new Event(accountNumber456, 100.00));

			session.insert(account123);
			session.fireAllRules();

		} catch (Throwable t) {
			t.printStackTrace();
		}
	}
}




--
View this message in context: http://drools.46999.n3.nabble.com/window-length-with-variables-as-constraints-not-working-correctly-tp4023518.html
Sent from the Drools: User forum mailing list archive at Nabble.com.



More information about the rules-users mailing list