1 Kasım 2021 Pazartesi

Drools

Maven
Eğer parent pom istersek şu satırı dahil ederiz
<dependency>
<groupId>org.kie</groupId> <artifactId>kie-ci</artifactId> <version>7.45.0.Final</version> </dependency>
Eğer her şeyi ayrı ayrı kullanmak istersek şu satırı dahil ederiz
<properties>
  <drools.version>7.59.0.Final</drools.version>
</properties>

<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-core</artifactId>
  <version>${drools.version}</version>
</dependency>
<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-compiler</artifactId>
  <version>${drools.version}</version>
</dependency>
<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-decisiontables</artifactId>
  <version>${drools.version}</version>
</dependency>
Kullanım
Esas amaç bir KieSession nesnesi yaratmak. Bunu yaratmak için KieBase veya KieContainer kullanılıyor.

KieSession nesnesinin insert() metodu çağrılıp girdi veriliyor. Daha sonra fireAllRules() metodu çağrılır. KieSession sateless veya statefull olabilir. Açıklaması şöyle. statefull session newKieSession() çağrısı ile yaratılır
A stateful session allows to iteratively work with the Working Memory, while a stateless one is a one-off execution of a Working Memory with a provided data set. In other terms all the data that is inserted into stateful session will be there.
KieContainer Sınıfı
Şu satırı dahil ederiz
import org.kie.api.runtime.KieContainer;
Açıklaması şöyle. Yani aslında KieBase için cache gibi düşünülebilir.
KieBase is a repository of all the application’s knowledge definitions. It will contain rules, processes, functions, and type models. The KieBase itself does not contain data; instead, sessions are created from the KieBase into which data can be inserted and from which process instances may be started. Creating the KieBase can be heavy, whereas session creation is very light, so it is recommended that KieBase be cached where possible to allow for repeated session creation. However end-users usually shouldn’t worry about it, because this caching mechanism is already automatically provided by the KieContainer
Örnek
Şöyle yaparız. KieServices singleton nesnesi ile KieFileSystem elde ediliyor. Bu kuralları yükler.
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
 
@Configuration
public class DroolsConfig {
 
  private static final String RULES_CUSTOMER_RULES_DRL = "rules/customer-discount.drl";
  private static final KieServices kieServices = KieServices.Factory.get();
 
  @Bean
  public KieContainer kieContainer() {
    KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
    kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_CUSTOMER_RULES_DRL));
    KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
    kb.buildAll();
    
    KieModule kieModule = kb.getKieModule();
    KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
    return kieContainer;
  }
}
getKieBase metodu
Örnek
Şöyle yaparız
private KieBase createKieBase(byte[] fileArray){
  KieServices kieServices = KieServices.Factory.get();
    
  
  Resource resource= ResourceFactory.newByteArrayResource(fileArray);
  resource.setSourcePath("src/main/resources/ruleFile");
  resource.setResourceType(ResourceType.DRL);
  
  KieFileSystem kieFileSystem=kieServices.newKieFileSystem();
  kieFileSystem.write(resource);
  
  KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
  kb.buildAll();
  
  KieModule kieModule = kb.getKieModule();
  KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId());
  return kContainer.getKieBase();
}

KieBase Sınıfı
newKieSession metodu
Örnek
Şöyle yaparız
KieSession configStateful()
  KieBase kieBase = ...
  return kieBase.newKieSession();
}
KieSession Sınıfı
Şu satırı dahil ederiz
import org.kie.api.runtime.KieSession;
fireAllRules metodu
Örnek
Şöyle yaparız
public Integer executeRules(...) throws IOException {
  KieSession kieSession= ...;
  kieSession.insert(...);
  int rulesFired = kieSession.fireAllRules();
  kieSession.dispose();
  return rulesFired;
}

Örnek
Şöyle yaparız. Burada insert() ile girdi verilen nesne değiştiriliyor.
import com.ruleEngine.drools.demo.dto.*;

rule "If customer type is regular and quantity [76-100] , Set Price as 10"
when
  $product:Product(item=='apple' && customerType=='regular' && quantity>=76 &&
                   quantity<=100)
then
    $product.setCost(10);
end

rule "If customer type is premium and quantity [76-100] , Set Price as 8"
when
  $product:Product(item=='apple' && customerType=='premium' && quantity>=76 &&
                   quantity<=100)
then
  $product.setCost(8);
end
Örnek
Şöyle yaparız
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
 
import com.demo.example.model.OrderDiscount;
import com.demo.example.model.OrderRequest;
 
@Service
public class OrderDiscountService {
 
  @Autowired
  private KieContainer kieContainer;
 
  public OrderDiscount getDiscount(OrderRequest orderRequest) {
    OrderDiscount orderDiscount = new OrderDiscount();
    
    KieSession kieSession = kieContainer.newKieSession();
    kieSession.setGlobal("orderDiscount", orderDiscount);//Set global parameter
    kieSession.insert(orderRequest); //Pass object to DRL
    kieSession.fireAllRules(); //Execute rules
    kieSession.dispose();
  
    return orderDiscount;
  }
}
/src/main/resources/rules/customer-discount.drl dosyası şöyledir
import com.demo.example.model.OrderRequest;
import com.demo.example.model.CustomerType;
global com.demo.example.model.OrderDiscount orderDiscount;
 
dialect "mvel"
 
rule "Age based discount"
  when
    OrderRequest(age < 20 || age > 50)
  then
    orderDiscount.setDiscount(orderDiscount.getDiscount() + 10);
end
 
rule "Customer type based discount - Loyal customer"
  when
    OrderRequest(customerType.getValue == "LOYAL")
  then
    orderDiscount.setDiscount(orderDiscount.getDiscount() + 5);
end
     
rule "Customer type based discount - others"
  when
    OrderRequest(customerType.getValue != "LOYAL")
  then
    orderDiscount.setDiscount(orderDiscount.getDiscount() + 3);
end
 
rule "Amount based discount"
  when
    OrderRequest(amount > 1000L)
  then
    orderDiscount.setDiscount(orderDiscount.getDiscount() + 5);
end
Açıklaması şöyle. Eşleşen her kural biraz daha indirim ilave eder.
We are also using a global parameter with the name orderDiscount. The global parameter can be shared between multiple rules.

The DRL file can contain one or multiple rules. We can use the mvel syntax to specify the rules. Also, each rule can be described with a description using the rule keyword.

We can use when-then syntax to define the conditions for a rule.

Based on the input values of the Order request, we are adding discount to the result. Every rule adds additional discount to the global result variable if the rule expression matches.


Hiç yorum yok:

Yorum Gönder