Prez27
Prez27

Reputation: 11

Not able to retrieve session object in KIE stateful session in Drools rules file

In Drools rules file (drt) ,I'm storing the productId and Customer name in session . I want to apply discount only if for that particular customer and product ,discount wasn't applied already

Format of the Template file (Excel)

ProductID     Quatntity       Discount     
Item_1           10            15    
Item_2           20            20   

Below is the drt file

 template header
    ProductId
    Quantity
    Discount

    package com.main.discount;

dialect "java"


import java.util.Random;
import java.time.LocalDateTime;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import com.main.discount.Customer;

declare Discount
    lCurrentTime: long
    lCustomerName: String
    lProductId: String
    lExist: boolean
    @timestamp(currentTime)
end

function Discount addDiscount(String productId,String customerName) {
    Discount newRecord = new Discount();
    newRecord.setLCustomerName(customerName);
    newRecord.setLProductId(productId);
    newRecord.setLCurrentTime(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
    newRecord.setLExist(true);   
    return newRecord;
}

template "OperationalMeasurement"

rule "Apply_Discount_@{row.rowNumber}"
no-loop
lock-on-active
salience 400
when
  $c: Customer(productId == "@{ProductId}" ,$productId: productId && quantity >= "@{Quantity}" , $quantity: quantity, $customer: CustomerName)
  not (Discount(lProductId == $productId, lCustomerName == $customer))
 then   
    $c.setDiscount("@{Discount}");
    Discount addCondition = addDiscount($productId,$customer);
    insert(addCondition);
    retract($c);
end

end template

Below is the code to call Initiate the Drools Kie session

  KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
KieSessionConfiguration sessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
sessionConfig.setOption( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) );
try {
    loadRuleTemplate(DATA_FILE, RULE_TEMPLATE_FILE, "Discount", 2, 1);
} catch (IOException errorMsg) {
    log.error(errorMsg.getMessage());       }
InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addPackages(kbuilder.getKnowledgePackages());       
KieSession kieSession =  kbase.newKieSession(sessionConfig, null);
sessionClock = ksession.getSessionClock();
ksession.insert(Customer);
ksession.fireAllRules();

But everytime, not condition is ignored, eventhough record exist for customer and product , it still applies discount, Looks like I'm not able to retrieve Discount object from session. I'm using Stateful session.

Upvotes: 0

Views: 370

Answers (1)

Esteban Aliverti
Esteban Aliverti

Reputation: 6322

I guess the problem you are having is related to the use of the lock-on-active attribute in your rule. The lock-on-active is nice to avoid infinite loops, but it comes with a cost: no new activations of that rule can happen by insertion or modifications of facts during the call of fireAllRules().

You can get a better explanation of the lock-on-active attibute (and some ways to avoid having to use it) in this blog post.

Hope it helps,

Upvotes: 1

Related Questions