25+ Drools Interview Questions and Answers [BEST & NEW]-2020
Drools Interview Questions and Answers

25+ Tricky SAP BI/BW Interview Questions with SMART ANSWERS

Last updated on 03rd Jul 2020, Blog, Interview Questions

About author

Rakshan (Sr Technical Director )

(5.0) | 16547 Ratings 1730

Drools is a business rule management system (BRMS) with a forward and backward chaining inference based rules engine, more correctly known as a production rule system, using an enhanced implementation of the Rete algorithm.

KIE (Knowledge Is Everything) is the new umbrella name to drools,optaPlanner, jBPM, Guvnor, uberFire and related technologies.

Drools supports the Java Rules Engine API (Java Specification Request 94) standard for its business rule engine and enterprise framework for the construction, maintenance, and enforcement of business policies in an organization, application, or service.

1) What is Drools?

Ans:

Drools is a Business Rules Management System (BRMS) solution. Using this framework users define rules that specify what action needs to be done when a particular condition is met.It extends and implements the Rete Pattern matching algorithm. In projects its usually used to define Business Rules. Business rules are composed of facts and conditional statements.

2) Why use Drools and not other programming languages ?

Ans:

The rules logic can be done in a programming language like Java .Consider a Jewellery shop which needs to maintain business logic of calculating discount based on the type of Jewellery. But such rules may change daily and need to be updated regularly in our code which is not good. Also we will always require a Developer for making such changes. So its a good practice to define this logic as rules in a Business Rule Management System. If tomorrow the discount is to be changed this can be done even by a non technical person.

3) What is meant by KIE?

Ans:

KIE stands for Knowledge is everything. It stands for Knowledge is everything. From Drools 6.0 onwards a new approach is used to create a Knowledge Base and a Knowledge Session. Knowledge base is an interface that manages a set of rules and processes. The main task of the knowledge base is to store and re-use rules because creation of rules is very expensive.Rules are contained inside the package org.drools.KnowledgeBase. These are commonly referred to as knowledge definitions or knowledge. Knowledge base provides methods for creating a Session.

4) What are Decision Tables? Have you used it?

Ans:

Drools Decision Tables are excel based decision tables. The main advantage of Drools is that the logic can also be changed by a non technical person. But if we look at the .drl file, any modification will also require technical knowledge. As the .drl becomes more complicated the more difficult it will become for non technical persons like Business Analysts. Also frequent changes to the drools file is cumbersome.Hence this format, decision tables, is a very good option to use where something is going to be changed frequently by non-programmers.

5) What is JBoss Enterprise BRMS?

Ans:

JBoss Enterprise BRMS is the reasoning engine for policy and rule developments for business. It also manages access and changes.

7) What is the productized version of Drools?

Ans:

JBoss Enterprise BRMS is the productized version of Drools and it has enterprise level support.

8) What is meant by accumulate in DRL Drools?

Ans:

Accumulate is conditional element that was introduced in Drools version 4.0. It is used to iterate over the list of objects and help validation of data in Java operation.

ex. accumulate (Counter() ; $cnt : count())

9) What is meant by Drools Stateful vs Stateless Knowledge Session?

Ans:

Stateless session that forms the simplest use case, not utilizing inference. A stateless session can be called like a function, passing it some data and then receiving some results back. Stateful sessions are longer lived and allow iterative changes over time.

Stateless Session

  • Any changes in the facts while executing rules is not made aware to the rule engine.
  • dispose() method is called automatically to release the session.
  • Any changes in the facts while executing rules is not made aware to the rule engine so if any rule is modified no other re-activation of rules will take place.

Stateful Session

  • Any changes in the facts while executing rules is made aware to the rule engine.
  • dispose() method should be called to release the session to avoid memory leaks.
  • As any changes in facts is available to the rule engine so if a rule is modified for a particular fact, this change will re-activate all the rules and fire the rules that are build on modified fact.

10) How is Backward chaining implemented in Drools?

Ans:

In Backward Chaining we first take a decision and then check if the decision is true or no by backtracking through sequence of events. For example if i want to find out if a particular student has passed or not? Then i will take a decision that the student has passed. Then analyze the data by backtracking through the sequence of analysis of data. Accordingly its decided if the decision is correct or not. Based on requirement either of the two approaches can be used. Sometimes the combination of both forward and backward chaining is also used. Backward chaining is often referred to as derivation queries and drools implements it with query construct. Further simple example can be found in this post-Backward chaining using Drools

11) Which Drools attributes have you used?

Ans:

Have used following attributes-

  • Salience is a prioritization value. Drools uses it in order figure out which drool to fire first when it is the case that the constraints for more than one rule are satisfied.
  • Using update makes the rules engine aware that a fact has been modified. This may cause other depending rules to get fired again.In some scenarios as shown below it cause indefinite looping.
  • Indefinite looping can be avoided using the no-loop attribute as shown in below example.

12) What are the different execution control statements in drools?

Ans:

If your KieBase defines multiple rules and if you want to selectively execute a subset of them, Drools provides several features to accomplish that.

  • agenda-group:This is an optional keyword. It can be assigned for all rules. If not assigned to any agenda group, the rule by default belongs to ‘main’ agenda.
  • ruleflow-group: This behaves exactly similar to agenda-group, except that it is generally used for rules used from jBPM process flows.
  • activation-group is a reserved keyword in drools drl file. There can be a single rule or multiple rules that can belong to a particular activation-group. Rules that belong to activation-group fire in similar fashion to “if..else if..else” block in java. In an activation group only one rule can fire at a time.

13) List the essential components of the JBoss enterprise.

Ans:

Some of the essential components of the JBoss enterprise include:

  • JBoss enterprise web – platform: It is a software architecture that mainly supports and runs various business rule management system components
  • JBoss enterprise application – platform: It is another software architecture that is also used to support and run various business rule management system
  • Business Rules Engine – It is a centralized repository that contains all the basic Drools knowledge that can be used to run, edit and manage multitudes of business rules
  • Business Rules Repository

14) Write a coding exhibiting a simple rule in order to print information regarding the September holidays.

Ans:

The following simple coding can help print out any information required about the September holidays:

  • rule “validate holiday”
  • dialect “mvel”
  • dialect “java”
  • when
  • $h1 : Holiday (month == “September”)
  • then
  • System.out.println ($h1.name + “:” + $h1.month);
  • end

15) Describe KIE

Ans:

KIE is an acronym for “Knowledge is everything”. The latest versions of Drools have an approach that is used to create different knowledge bases and sessions. These bases act as an interface between the one that manages the set and of rules and the one that processes. One of the main objectives of KIE is to store the various knowledge bases and reuse the rules whenever required. This is mainly carried out because making a new set of rules on repetition can be expensive and time-consuming.

16) What is the procedure for implementing “backward chaining” in Drools?

Ans:

In “backward chaining”, one must first make a choice and after that check if the choice is valid or not by backtracking through a succession of occasions. For instance in the event that one needs to see whether a specific student has passed the exam or not? At that point, I will take the choice that the student has passed. Then dissect the information by backtracking through the succession of investigation of information. In like manner the decision made is either right or wrong. In light of necessity, both of the two methodologies can be utilized. Sometimes the blend of both forward and backward chaining is additionally utilized. In backward chaining, it is regularly alluded to as induction inquiries and Drools implement it with constructive questions.

17) List the different execution statements used in Drools

Ans:

Some of the commonly used execution control statements used in Drools include:

  • Rule flow group: It is generally utilized for rules from the JBoss business project management process
  • Agenda – group: It is an optional keyword that is assigned to all the rules available in the database
  • Activation – group: It is a reserved keyword found in all Drools DRL files. Activation – the group can consist of either a single rule or multiple rules. The rules in this group are run using “if…else if…else” statements

18) What are some of the advantages of using rule engines in business project management?

Ans:

Some of the advantages of using rule engines in business project management include:

  • High flexibility: keeping your guidelines into a Knowledgebase let you adjust effectively your choices when they are evolving.
  • Easy to learn: Rules are simpler to comprehend than procedural code so they can be successfully used to bridge any hindrance between business expert and engineers.
  • Reduced intricacy: When installing bunches of decisions, it mainly focuses on your procedural codes that it can undoubtedly transform your application into a bad dream. Also, the rules can handle much better expanding multifaceted nature since they utilize a predictable portrayal of business rules.
  • Reusability: Keeping rules at one spot prompts more noteworthy reusability of your business rules. Likewise, conventional procedural code regularly forces pointless varieties of base guidelines, which are consequently increasingly hard to reuse in different settings.

19) What do you understand by Drools Process?

Ans:

Drools Process (also known as Drools Flow) is a framework that provides a flow of work in addition to various business processes.

20) What are the global variables?

Ans:

A global variable is a keyword for Drools. “Global” is the variable that is used in Drools which is visible to all the rules inside .drl files. The main objective of using a global variable is that it can be utilized for any kind of object without worrying about mismatches.

    Subscribe For Free Demo

    22) What do you mean by accumulating in .drl files in Drools?

    Ans:

    Accumulate is an extra element introduced in the recent versions of Drools that is used to iterate the list of objects and also help in the authentication of data in operations utilizing Java. For instance: accumulate (Counter() ; $cnt : count())

    23) Why is the symbol “$” used in Drools before variables?

    Ans:

    The symbol “$” is used before variables in Drools to make sure that there is a difference between variables of Rules and the POJO class.

    24) Name the types of interfaces in the Knowledge Session and differentiate between them.

    Ans:

    The two types of interfaces in knowledge sessions are:

    • Stateless Knowledge Session
    • Stateful Knowledge Session
    S.NoStateless SessionStateful Session
    1The engine rule is not made well aware of all the changes in the facts during executionThe engine rule is made well aware of all the changes in the facts during execution
    2The code used to automatically release the session is dispose()The code dispose of () is used manually to release the session and avoid any kind of memory loss
    3No reactivation of rules take place as the engine is not made aware of the changesEven the slightest reactivation of rules will aggravate the rules that are built on the altered facts

    25) What is BPM?

    Ans:

    BPM stands for Business Process Management. There are 2 different aspects of BPM: BPM as management discipline and BPM as software engineering. The BPM vendors have long time tried to make abstraction of those 2 distinct aspects. That path lead to more confusion then anything else.

    BPM as a management discipline is the responsibility of every strategic executive manager. It’s to ensure that the organization performs well in their core business processes. This involves understanding what values the organization delivers and how those are achieved. This means analyzing, documenting and improving the way that people and systems work together. As part of that work, it’s useful to work with models and diagrams.

    BPMN diagrams express the execution flow of the steps to accomplish a certain goal. Important to note that these models are used for people to people communication. They can be underspecified, which means that they can contain valuable high level information without including unnecessary details. Such underspecified process models are also known as abstract business processes.

    26) What are the components of JBoss Enterprise Version?

    Ans:

    The components of JBoss Enterprise Version are JBoss Enterprise web platform, JBoss Enterprise application of SOA platform, Business Rules Engine, and Business Rules Manager.

    27) What is JBPM?

    Ans:

    JBPM is a flexible Business Process Management (BPM) Suite. It makes the bridge between business analysts and developers. Traditional BPM engines have a focus that is limited to non-technical people only. jBPM has a dual focus: it offers process management features in a way that both business users and developers like it.

    28) What does jBPM do?

    Ans:

    This business process allows you to model your business goals by describing the steps that need to be executed to achieve that goal and the order, using a flow chart. This greatly improves the visibility and agility of your business logic, results in higher-level and domain-specific representations that can be understood by business users and is easier to monitor.

    The core of jBPM is a light-weight, extensible workflow engine written in pure Java that allows you to execute business processes using the latest BPMN 2.0 specification. It can run in any Java environment, embedded in your application or as a service.

    29) What are the features of JBoss Enterprise Web Platform?

    Ans:

    The JBoss Enterprise Web Platform is the software infrastructure that supports the running of BRMS components.

    30) What are the features of JBoss Enterprise Application or SOA Platform?

    Ans:

    It is the application software structure in the system that supports running of BRMS components.

    Course Curriculum

    Get Hands-On Practical Drools Training to Advance Your Career

    • Instructor-led Sessions
    • Real-life Case Studies
    • Assignments
    Explore Curriculum

    31) Who use the Business Rules Engine?

    Ans:

    Drools experts use the Business Rules Engine through Rete algorithm and Drools Rule Language (DLR).

    32) Is the Graphical Process Designer (GPD) only useable in Eclipse? Is there a way to use it standalone?

    Ans:

    The jBPM GPD is an eclipse plugin that targets usage by multiple roles. Both the business analyst and developer are able to use the same tool in different ways. The main reason why we think it is important to integrate those two in one single environment is because in many teams, these two roles are done by one person. Then it becomes very important that the tool can support both roles and gradually shift from being a diagramming tool to an implementation tool.

    33) What are the advantages of Rule engine?

    Ans:

    Advantages of Rule Engines:

    Greater flexibility: keeping your rules into a Knowledge base let you adapt easily your decisions when they are changing.

    Easier to grasp: Rules are easier to understand than procedural code so they can be effectively used to bridge the gap between business analyst and developers.

    Reduced complexity: When embedding lots of decision points to your procedural codes it can easily turn your application into a nightmare. On the other hand rules can handle much better increasing complexity because they use a consistent representation of business rules.

    Reusability: By keeping rules are kept in one place leads to a greater reusability of your business rules. Also, traditional procedural code often impose unnecessary variations of base rules which are therefore more difficult to reuse in other contexts.

    34) Where to use global variable?

    Ans:

    Consider a scenario, where in the rules there is a requirement for database connection object. In this case, the DB Connection object can be inserted as a global variable in the working memory and the connection object will be visible to all the rules in that DRL file.

    35) What is Business Rules Manager?

    Ans:

    Business Rules Manager is a centralized repository for the Drools knowledge bases and has rich web based Graphical User Interface as well as tools and editors to manage large numbers of rules.

    36) What is global in DRL file?

    Ans:

    Global is the keyword used in drools to define a global variable. Global variable is the one which will be visible to all the rules inside a DRL file.

    Globals must be used very carefully in a DRL file, since the changes in a global variable are not notified to the working memory. For example, you are using a list variable as a global and in any rule you are adding a value in a list and in one particular rule, you are checking if list size() > 0, then in this case rule may not fire. Global variable can be used for any type of object.

    37) Explain the difference between StringBuilder and StringBuffer class?

    Ans:

    StringBuilder is unsynchronized whereas StringBuffer is synchronized. So when the application needs to be run only in a single thread then it is better to use StringBuilder. StringBuilder is more efficient than StringBuffer.

    38) What is meant by Drools Guvnor and Drools Expert?

    Ans:

    Drools Guvnor is the Business Rules Manager and Drools Expert is the Business Rules Engine.

    39) What are Drool Workbench, Expert, and Fusion?

    Ans:

    Drools Workbench is the web user interface for authoring and management. Drools Expert is the business rule engine and Drools Fusion is the complex event processing feature.

    40) How to halt process in DRL file?

    Ans:

    User has to resort to drools.halt() in the consequence (then) part of the application.

    41) How to remove object from knowledge session?

    Ans:

    Using retract method to remove the object from knowledge session can help.

    42) How to fetch and play around with the rules in java code?

    Ans:

    Rules does not exist as the Java codes. However it is possible using Guvnor REST API for downloading the DRL source code for the rules and thereafter uploads them all over again.

    43) Is it possible using round trips between rules modified in Guvnor, loade in the UI, modified and uploaded to Guvnor?

    Ans:

    There is no such way of ensuring this. Especially newcomers should not try this to avoid complications.

    44) Is it possible working with completely custom UI instead of using Guvnor Rule?

    Ans:

    Rules can be stored in the custom domain model in a database generating the DRL from that model. This can render Guvnor redundant in the custom environment.

    45) What is meant by Drools Recursive Rules?

    Ans:

    A Fibonacci series is the most common example of recursion in Drools. In the Drools the implementation is carried out using the insert and modifies keywords.

    46) What are the most important parts of Recursion in Drools?

    Ans:

    The three most important parts of in the process of implementation of recursive rules in Drools are inserting keywords in ‘then’ part, not keyword used in ‘when’ part, and ‘breaking condition’.

    47) What would be the breaking condition in Fibonacci series?

    Ans:

    The breaking condition in Fibonacci series would be (sequence==1).

    48) Architecture of Drools

    Ans:

    Architecture-Drools

    Here is the working system of a rules engine:

    Step 1) The rules are loaded into Rule Base, which are available all the times.

    Step 2) Facts are asserted into the Working Memory where they may then be modified or retracted.

    Step 3) The process of matching the new or existing facts against production rules is called pattern matching, which is performed by the Rule engine.

    Step 4) The agenda allows you to manage the execution order of the conflicting rules with the help of a conflict resolution strategy.

    49) Features of Drool

    Ans:

    Here are important features of Drool:

    • Helps you to separate application from dynamic logic
    • Declarative Programming
    • Centralization of Knowledge
    • Speed and Scalability
    • Separate logic from application
    • Understandable rules

    50) How to add Drools plugins in Eclipse

    Ans:

    Step 1) Go to link and click “Distribution ZIP” for jBPM Integration. Once downloaded extract it in your hard drive

    Drools-plugins-in-Eclipse

    Step 2) In Eclipse, select Install New Software

    Eclipse,-select-Install-New-Software

    Step 3) Click on Add

    Eclipse,-select-Install-New-Software

    Step 4) In the next screen,

    • Click on Local
    • Select folder “org.drools.updatesite/”
    • Click Ok
    Eclipse,-select-Install-New-Software

    Step 5) Click Next

    Eclipse,-select-Install-New-Software

    Step 6) Accept the license agreement and click next

    Eclipse,-select-Install-New-Software

    Step 7) Software will download and you will be asked to reboot eclipse

    Step 8) In Windows > Preferences menu, you will see Drools option indicating it’s installed.

    Eclipse,-select-Install-New-Software
    Course Curriculum

    Enroll in Best Drools Courses and Get Hired by TOP MNCs

    Weekday / Weekend BatchesSee Batch Details

    51) Create a Drools Program

    Ans:

    • package com.sample
    • inport com.sample.DroolsTest.Message;
    • rule “Hello World”
    •  when
    • m : Message( status ** Message.Hello, myMessage : message )
    •   then
    • System.out.println( myMessage );
    • m.setMessage( “Goodbye cruel world” );
    • m.setStatus( Message.GOODBYE ); 
    • update( m );
    • end
    •  rule “GoodBye”
    • when
    • Message( status ** Message.GOODBYE, myMessage : message )
    • then
    • System.out.println( myMessage );
    • end

    52) What is Backward vs. Forward Chaining?

    Ans:

    A forward-chaining engine checks the facts and derives a specific conclusion.

    Let’s consider a scenario of the medical diagnosis system. If the patient’s symptoms are put as facts into working memory, then it is easy to diagnose him with an ailment.

    Backward-vs-Forward-Chaining

    A backward chaining engine has the set goal, and the engine tries to satisfy it.

    Consider the same scenario of medical diagnosis. Assume that an epidemic of a certain disease. This AI could presume a given individual had the disease and attempt to determine if its diagnosis is correct based on available information.

    Backward-vs-Forward-Chaining

    53) Why use Drools Rule Engine?

    Ans:

    Here, are prime reasons for using Drools rules engine:

    • Rules are easy to understand for developers and business analysts.
    • Rules are easily maintainable.
    • Rule Engine uses a Rete algorithm which states that the performance of the engine never depends on the number of rules.
    • Rules can be modified and deployed without bringing down the application.
    • Externalizes the business logic from the comparatively static codebase.
    • Rules are developed in less complicated formats so the business analyst can easily read and verify a group of rules.
    • Rules allow you to create a warehouse of knowledge which is executable in form.
    • Tools like Eclipse help you to manage rules, get an instant response, authentication, and content support.

    54) Disadvantages of Rules Engine

    Ans:

    Here, are drawbacks/ cons of using rules engine:

    • Lots of learning effort requires by developers to know this method of programming
    • Rule engine is not a secure method to troubleshoot issues.
    • Needs to understand the working of rule engine to consumes more memory
    • There are a wide set of rules for a complex branching.

    Rules may change over time and will become effective with code changes

    55) What problem we are trying to solve?

    Ans:

    Let’s consider the domain of email marketing. As marketers we have an email list of persons interested in our content. Each of them may have demonstrate interest in a specific topic, read some of our articles and bought certain products. Considering all their history and preferences we want to send to them at each time the most appropriate content. This content may be either educative or proposing some deal. The problem is that there are constraints we want to consider (i.e., not sending emails on sunday or not sending emails promoting a product to someone who already bought it).

    All these rules are simple per se, but the complexity derives by how they are combined and how they interact. The business rule engine will deal with that complexity for us, all we have to do is to express clearly the single rules. Rules will be expressed in the terms of our domain data so let’s focus on our domain model first.

    The model of our domain

    In our domain model we have:

    • Emails: the single emails we want to send, described by their title and content
    • Email Sequences: groups of emails that have to be sent in a specific order, for example a set of emails representing a tutorial or describing different features of a product
    • Subscribers: the single subscriber to the mailing list. We will need to know which emails we sent to him, what things he is interested in, and which products he bought
    • Products: the products we sell
    • Purchases: the purchases subscribers have made
    • Email Sending: the fact we sent or are about to send a certain email, on a certain date to a certain subscriber
    • Email Scheduling: the plan for sending an email, with some additional information

    The latter two elements of our domain model could seem less obvious compared to the others, but we will see in the implementation for which reasons we need them.

    model-of-ou- domain

    56) What our system should do?

    Ans:

    Our system should execute all the rules, using the Drools engine, and to determine for each user which email we should send on a specific day. The result could be the decision to not send any email, or to send an email, selecting one among many possible emails.

    An important thing to consider is that these rules may evolve over time. The people in charge of marketing may want to try new rules and see how they affect the system. Using Drools it should be easy for them to add or remove rules or tweak the existing rules.

    57) What are the The rules?

    Ans:

    Ok, now that we know which data do we have, we can express rules based on that model.

    Let’s see some examples of rules we may want to write:

    • We may have sequences of emails, for example the content of a course. They have to be sent in order
    • We may have time sensitive emails that should either be sent in a specific time window or not sent at all
    • We may want to avoid sending emails on specific days of the week, for example on the public holidays in the country where the subscriber is based
    • We may want to send certain type of emails (for example proposing a deal) only to persons who received certain other emails (for example at least 3 informative emails on the same subject)
    • We do not want to propose a deal on a certain product to a subscriber who has already bought that product
    • We may want to limit the frequency we send emails to users. For example, we may decide to not send an email to a user if we have sent already one in the last 5 days

    58) Setting up drools

    Ans:

    Setting up drools can be very simple. We are looking into running drools in a standalone application. Depending on your context this may or may not be an acceptable solution and in some cases you will have to look into JBoss, the application server supporting Drools. However if you want to get started you can forget all of this and just configure your dependencies using Gradle (or Maven). You can figure out the boring configuration bits later, if you really have to.

    • buildscript {
    •    ext.droolsVersion = “7.20.0.Final”
    •    repositories {
    •        mavenCentral()
    •    }
    • }
    • plugins {
    •    id “org.jetbrains.kotlin.jvm” version “1.3.21”
    • }
    • apply plugin: ‘java’
    • apply plugin: ‘idea’
    • group ‘com.strumenta’
    • version ‘0.1.1-SNAPSHOT’
    • repositories {
    •    mavenLocal()
    •    mavenCentral()
    •    maven {
    •        url ‘https://repository.jboss.org/nexus/content/groups/public/’
    •    }
    • }
    • dependencies {
    •    compile “org.kie:kie-api:${droolsVersion}”
    •    compile “org.drools:drools-compiler:${droolsVersion}”
    •    compile “org.drools:drools-core:${droolsVersion}”
    •    compile “ch.qos.logback:logback-classic:1.1.+”
    •    compile “org.slf4j:slf4j-api:1.7.+”   
    •    implementation “org.jetbrains.kotlin:kotlin-stdlib”
    •    implementation “org.jetbrains.kotlin:kotlin-reflect”
    •    testImplementation “org.jetbrains.kotlin:kotlin-test”
    •    testImplementation “org.jetbrains.kotlin:kotlin-test-junit”
    • }

    In our Gradle script we use:

    • Kotlin, because Kotlin rocks!
    • IDEA, because it is my favorite IDE
    • Kotlin StdLib, reflect and test
    • Drools

    And this is how our program will be structured:

    • fun main(args: Array<String>) {
    •    try {
    •        val kbase = readKnowledgeBase(listOf(
    •                File(“rules/generic.drl”),
    •                File(“rules/book.drl”)))
    •        val ksession = kbase.newKieSession()
    •       // typically we want to consider today but we may decide to schedule
    •       // emails in the future or we may want to run tests using a different date
    •        val dayToConsider = LocalDate.now()
    •        loadDataIntoSession(ksession, dayToConsider)
    •        ksession.fireAllRules()
    •        showSending(ksession)
    •    } catch (t: Throwable) {
    •        t.printStackTrace()
    •    }
    • }

    Pretty simple, pretty neat.

    What we do in, details is:

    • We load the rules from file. For now we just load the file rules/generic.drl
    • We setup a new session. Think of the session as the universe as seen by the rules: all data they can access is there
    • We load our data model into the session
    • We fire all the rules. They could change stuff in the session
    • We read the modified data model (a.k.a. the session) to figure out which emails we should send today

    59) Writing the classes for the data model

    Ans:

    We have previously seen how our data model looks like, let’s now see the code for it.

    Given we are using Kotlin it will be pretty concise and obvious.

    • package com.strumenta.funnel
    • import java.time.DayOfWeek
    • import java.time.LocalDate
    • import java.util.*
    • enum class Priority {
    •    TRIVIAL,
    •    NORMAL,
    •    IMPORTANT,
    •    VITAL
    • }
    • data class Product(val name: String,
    •                   val price: Float)
    • data class Purchase(val product: Product,
    •                    val price: Float,
    •                    val date: LocalDate)
    • data class Subscriber(val name: String,
    •                      val subscriptionDate: LocalDate,
    •                      val country: String,
    •                      val email: String = “$name@foo.com”,
    •                      val tags: List<String> = emptyList(),
    •                      val purchases: List<Purchase> = emptyList(),
    •                      val emailsReceived: MutableList<EmailSending> = LinkedList()) {
    •    val actualEmailsReceived
    •            get() = emailsReceived.map { it.email }
    •  
    •    fun isInSequence(emailSequence: EmailSequence) =
    •            hasReceived(emailSequence.first)
    •                    && !hasReceived(emailSequence.last)
    •    fun hasReceived(email: Email) = emailsReceived.any { it.email == email }
    •    fun hasReceivedEmailsInLastDays(nDays: Long, day: LocalDate)
    •            : Boolean {
    •        return emailsReceived.any {
    •            it.date.isAfter(day.minusDays(nDays))
    •        }
    •    }
    •    fun isOnHolidays(date: LocalDate) : Boolean {
    •        return date.dayOfWeek == DayOfWeek.SATURDAY
    •                || date.dayOfWeek == DayOfWeek.SUNDAY
    •    }
    •    fun emailReceivedWithTag(tag: String) =
    •            emailsReceived.count { tag in it.email.tags }
    •  
    • }
    • data class Email(val title: String,
    •                 val content: String,
    •                 val tags: List<String> = emptyList())
    •  
    • data class EmailSequence(val title: String,
    •                         val emails: List<Email>,
    •                         val tags: List<String> = emptyList()) {
    •  
    •    val first = emails.first()
    •    val last = emails.last()
    •  
    •    init {
    •        require(emails.isNotEmpty())
    •    }
    •    fun next(emailsReceived: List<Email>) =
    •        emails.first { it !in emailsReceived }
    • }
    • data class EmailSending(val email: Email,
    •                        val subscriber: Subscriber,
    •                        val date: LocalDate) {
    •    override fun equals(other: Any?): Boolean {
    •        return if (other is EmailSending) {
    •            this.email === other.email && this.subscriber === other.subscriber && this.date == other.date
    •        } else {
    •            false
    •        }
    •    }
    •    override fun hashCode(): Int {
    •        return this.email.title.hashCode() * 7 + this.subscriber.name.hashCode() * 3 + this.date.hashCode()
    •    }
    • }
    • data class EmailScheduling @JvmOverloads constructor(val sending: EmailSending,
    •                           val priority: Priority,
    •                           val timeSensitive: Boolean = false,
    •                           var blocked: Boolean = false) {
    •    val id = ++nextId
    •  
    •    companion object {
    •        private var nextId = 0
    •    }
    • }

    Nothing surprising here: we have the seven classes we were expecting. We have a few utility methods here and there but nothing that you cannot figure out by yourself.

    60) Writing a rule to schedule an email

    Ans:

    It is now time to write our first business rule. This rule will state that, given a sequence and given a person, we will schedule the first email of the sequence to be sent to a person if that person is not already receiving an email from that sequence.

    • dialect “java”
    • rule “Start sequence”
    •   when
    •      sequence : EmailSequence ()
    •      subscriber : Subscriber ( !isInSequence(sequence) )
    •   then
    •      EmailSending $sending = new EmailSending(sequence.getFirst(), subscriber, day);
    •      EmailScheduling $scheduling = new EmailScheduling($sending, Priority.NORMAL);
    •      insert($scheduling);
    • end

    In the header of the rule we specify the language we are using for writing the clauses. In this tutorial we will consider only Java. There is another possible value: mvel. We will not look into that. Also, while in this example we specify the dialect on the rule it can be instead specified once for the whole file. There is even a better option: not specifing the dialect at all, as Java is the default anyway and the usage of mvel is discouraged.

    The when section determines on which elements our rule will operate. In this case we state that it will operate on an EmailSequence and a Subscriber. It will not work just on any person but only on a person for which the condition !isInSequence(sequence) is satisfied. This condition is based on a call to the method isInsequence that we will show below:

    • data class Subscriber(…) {
    •    fun isInSequence(emailSequence: EmailSequence) =
    •            hasReceived(emailSequence.first) &&
    •                !hasReceived(emailSequence.last)
    •    fun hasReceived(email: Email) =
    •            emailReceived.any { it.email == email }
    • }

    Let’s now look at the then section of our rule. In such section we specify what happens when the rule is fired. The rule will be fired when elements satisfying the when section can be found.

    In this case we will create an EmailScheduling and add it to the session. In particular we want to send to the considered person the first email of the sequence, on the day considered. We also specify the priority of this email (NORMAL in this case). This is necessary to decide which email effectively to send when we have more than one. Indeed we will have another rule looking at these values to decide which emails to prioritize (hint: it will be the email with the highest priority).

    In general you may want to typically add things into the session in the thenclause. Alternatively you may want to modify objects which are part of the session. You could also call methods on objects which have side-effects. While the recommended approach is to limit yourself to manipulate the session you may want to add side effects for logging, for example. This is especially useful when learning Drools and trying to wrap your head around your first rules.

    61) Writing a rule to block an email from being sent

    Ans:

    We will see that we have two possible types of rules: rules to schedule new emails and rules to prevent scheduled emails to be sent. We have seen before how to write a rule to send an email and we will now see how to write an email to prevent an email from being sent.

    In this rule we want to check if an email is scheduled to be sent to a person who has received already emails in the last three days. If this is the case we want to block that email from being sent.

    • rule “Prevent overloading”
    •   when
    •      scheduling : EmailScheduling(
    •            sending.subscriber.hasReceivedEmailsInLastDays(3, day),
    •            !blocked )
    •   then
    •      scheduling.setBlocked(true);
    • end

    In the when section we specify that this rule will operate on an EmailScheduling. So, every time another rule will add an EmailScheduling this rule could be triggered to decide if we have to block it from being sent.

    This rule will apply to all scheduling which are directed to subscribers who have received emails in the last 3 days. In addition to that we will check if the EmailScheduling was not already blocked. If that is the case we will not need to apply this rule.

    We use the setBlocked method of the scheduling object to modify an element which is part of the session.

    At this point we have seen the pattern we will use:

    • We will create `EmailScheduling` when we think it makes sense to send an email to the user
    • We will check if we have reasons to block those emails. If that is the case we will set the blocked flag to true, effectively removing the EmailScheduling

    Using a flag to mark elements to remove/invalidate/block is a common pattern used in business rules. It can sound a bit unfamiliar at the beginning but it is actually quite useful. You may think that you could just delete elements from the session, however doing so it becomes easy to create infinite loops in which you create new elements with some rules, remove them with others and keep recreating them again. The block-flag pattern avoids all of that.

    62) The session

    Ans:

    Rules operate on data which is part of the session. Data is typically inserted into the session during the initialization phase. Later we could have rules inserting more data into the session, potentially triggering other rules.

    This is how we could populate the session with some example data:

    • fun loadDataIntoSession(ksession: KieSession,
    •                        dayToConsider: LocalDate) {
    •    val products = listOf(
    •            Product(“My book”, 20.0f),
    •            Product(“Video course”, 100.0f),
    •            Product(“Consulting package”, 500.0f)
    •    )
    •    val persons = listOf(
    •            Subscriber(“Mario”,
    •                    LocalDate.of(2019, Month.JANUARY, 1),
    •                    “Italy”),
    •            Subscriber(“Amelie”,
    •                    LocalDate.of(2019, Month.FEBRUARY, 1),
    •                    “France”),
    •            Subscriber(“Bernd”,
    •                    LocalDate.of(2019, Month.APRIL, 18),
    •                    “Germany”),
    •            Subscriber(“Eric”,
    •                    LocalDate.of(2018, Month.OCTOBER, 1),
    •                    “USA”),
    •            Subscriber(“Albert”,
    •                    LocalDate.of(2016, Month.OCTOBER, 12),
    •                    “USA”)
    •    )
    •    val sequences = listOf(
    •            EmailSequence(“Present book”, listOf(
    •                    Email(“Present book 1”, “Here is the book…”,
    •                            tags= listOf(“book_explanation”)),
    •                    Email(“Present book 2”, “Here is the book…”,
    •                            tags= listOf(“book_explanation”)),
    •                    Email(“Present book 3”, “Here is the book…”,
    •                            tags= listOf(“book_explanation”))
    •            )),
    •            EmailSequence(“Present course”, listOf(
    •                    Email(“Present course 1”, “Here is the course…”,
    •                            tags= listOf(“course_explanation”)),
    •                    Email(“Present course 2”, “Here is the course…”,
    •                            tags= listOf(“course_explanation”)),
    •                    Email(“Present course 3”, “Here is the course…”,
    •                            tags= listOf(“course_explanation”))
    •            ))
    •    )
    •    ksession.insert(Email(“Question to user”,
    •            “Do you…”))
    •    ksession.insert(Email(“Interesting topic A”,
    •            “Do you…”))
    •    ksession.insert(Email(“Interesting topic B”,
    •            “Do you…”))
    •    ksession.insert(Email(“Suggest book”,
    •            “I wrote a book…”,
    •            tags= listOf(“book_offer”)))
    •    ksession.insert(Email(“Suggest course”,
    •            “I wrote a course…”,
    •            tags= listOf(“course_offer”)))
    •    ksession.insert(Email(“Suggest consulting”,
    •            “I offer consulting…”,
    •            tags= listOf(“consulting_offer”)))
    •    ksession.setGlobal(“day”, dayToConsider)
    •    ksession.insert(products)
    •    persons.forEach {
    •        ksession.insert(it)
    •    }
    •    sequences.forEach {
    •        ksession.insert(it)
    •    }
    • }

    Of course in a real application we would access some database or some form of storage to retrieve the data to be used to populate the session.

    63) Global objects

    Ans:

    In rules we will not only access elements which are part of the session but also global objects.

    Global objects are inserted in the session using setGlobal. We have seen an example in loadDataIntoSession:

    • fun loadDataIntoSession(ksession: StatefulKnowledgeSession, dayToConsider: LocalDate) : EmailScheduler {
    •    …
    •    ksession.setGlobal(“day”, dayToConsider)
    •    …
    • }

    In the rules we declare the globals:

    • package com.strumenta.funnellang
    • import com.strumenta.funnel.Email;
    • import com.strumenta.funnel.EmailSequence;
    • import com.strumenta.funnel.EmailScheduling
    • import com.strumenta.funnel.EmailScheduler;
    • import com.strumenta.funnel.Person
    • import java.time.LocalDate;
    • global LocalDate day;

    At this point we can refer to these globals in all rules. In our example we use day value to know which day we are considering for the scheduling. Typically it would be tomorrow, as we would like to do the scheduling one day in advance. However for testing reasons we could use any day we want. Or we may want to use days in the future for simulation purposes.

    Global should not be abused. Personally I like to use them to specify configuration parameters. Others prefer to insert this data into the session and this is the recommended approach. The reason why I use globals (carefully and rarely) is because I like to distinguish between the data I am working on (stored in the session) and the configuration (for that I use globals).

    Drools Sample Resumes! Download & Edit, Get Noticed by Top Employers! Download

    64) Writing the generic rules

    Ans:

    Let’s now see the whole set of generic rules that we have written. By generic rules we mean rules that could be applied to all email schedulings we want to do. To complement these rules we may have others for specific products or topics we are promoting.

    • package com.strumenta.funnellang
    • import com.strumenta.funnel.Email;
    • import com.strumenta.funnel.EmailSequence;
    • import com.strumenta.funnel.EmailScheduling
    • import com.strumenta.funnel.EmailSending;
    • import com.strumenta.funnel.Subscriber
    • import java.time.LocalDate;
    • import com.strumenta.funnel.Priority
    • global LocalDate day;
    • rule “Continue sequence”
    •   when
    •      sequence : EmailSequence ()
    •      subscriber : Subscriber ( isInSequence(sequence) )
    •   then
    •      EmailSending $sending = new EmailSending(sequence.next(subscriber.getActualEmailsReceived()), subscriber, day);
    •      EmailScheduling $scheduling = new EmailScheduling($sending, Priority.IMPORTANT, true);
    •      insert($scheduling);
    • end
    • rule “Start sequence”
    •   when
    •      sequence : EmailSequence ()
    •      subscriber : Subscriber ( !isInSequence(sequence) )
    •  
    •   then
    •      EmailSending $sending = new EmailSending(sequence.getFirst(), subscriber, day);
    •      EmailScheduling $scheduling = new EmailScheduling($sending, Priority.NORMAL);
    •      insert($scheduling);
    • end
    • rule “Prevent overloading”
    •   when
    •      scheduling : EmailScheduling(
    •            sending.subscriber.hasReceivedEmailsInLastDays(3, day),
    •            !blocked )
    •   then
    •      scheduling.setBlocked(true);
    • end
    • rule “Block on holidays”
    •   when
    •      scheduling : EmailScheduling( sending.subscriber.isOnHolidays(scheduling.sending.date), !blocked )
    •  
    •   then
    •      scheduling.setBlocked(true);
    • end
    • rule “Precedence to time sensitive emails”
    •   when
    •      scheduling1 : EmailScheduling( timeSensitive == true, !blocked )
    •      scheduling2 : EmailScheduling( this != scheduling1,
    •                !blocked,
    •                sending.subscriber == scheduling1.sending.subscriber,
    •                sending.date == scheduling1.sending.date,
    •                timeSensitive == false)
    •   then
    •      scheduling2.setBlocked(true);
    • end
    • rule “Precedence to higher priority emails”
    •  when
    •     scheduling1 : EmailScheduling( !blocked )
    •     scheduling2 : EmailScheduling( this != scheduling1,
    •               !blocked,
    •               sending.subscriber == scheduling1.sending.subscriber,
    •               sending.date == scheduling1.sending.date,
    •               timeSensitive == scheduling1.timeSensitive,
    •               priority < scheduling1.priority)
    •   then
    •      scheduling2.setBlocked(true);
    • end
    • rule “Limit to one email per day”
    •  when
    •     scheduling1 : EmailScheduling( blocked == false )
    •     scheduling2 : EmailScheduling( this != scheduling1,
    •               blocked == false,
    •               sending.subscriber == scheduling1.sending.subscriber,
    •               sending.date == scheduling1.sending.date,
    •               timeSensitive == scheduling1.timeSensitive,
    •               priority == scheduling1.priority,
    •               id > scheduling1.id)
    •   then
    •      scheduling2.setBlocked(true);
    • end
    • rule “Never resend same email”
    •  when
    •     scheduling : EmailScheduling( !blocked )
    •     subscriber : Subscriber( this == scheduling.sending.subscriber,
    •            hasReceived(scheduling.sending.email) )
    •   then
    •      scheduling.setBlocked(true);
    • end

    Let’s examine all these rules, one by one:

    • Continue sequence: if someone started receiving an email sequence and he did not receive the last email yet, then he should get the next email in the sequence
    • Start sequence: if someone did not yet receive the first email of a sequence he should. Note that technically speaking this rule alone would cause everyone who has finished a sequence to immediately restart it. This does not happen because of the Never resend same email rule. However you could decide to rewrite this rule to explicitly forbidding someone who has already received a certain sequence to be re-inserted in it.
    • Prevent overloading: if someone has received an email in the last three days then we should block any email scheduling directed to that person
    • Block on holidays: if someone is on holidays we should not send emails to them
    • Precedence to time sensitive emails: given a pair of email schedulings directed to the same person on the same date, if only one of the two is time sensitive we should block the other
    • Precedence to higher priority emails: given a pair of email schedulings directed to the same person on the same date being both time sensitive or both not time sensitive, we should block the one with lower importance
    • Limit to one email per day: we should not schedule to send more than one email per day to the same person. If this happens we have to pick one somehow. We use the internal ID to discriminate between the two
    • Never resend same email: if someone has already received a certain email he should not receive it again in the future

    65) Writing the rules specific to the book emails

    Ans:

    Our marketing experts may want to write specific rules for specific products or topics. Let’s assume they want to create a set of emails to promote and sell a book. We could write these rules in a separate file, perhaps maintained by the marketing expert in charge of selling that book.

    To write rules regarding a specific topic we will take advantage of tags, a mechanism that will give us a certain amount of flexibility. Let’s see the rules we can write:

    • package com.strumenta.funnellang
    •  
    • import com.strumenta.funnel.Subscriber;
    • import com.strumenta.funnel.EmailScheduling;
    • import java.time.DayOfWeek;
    •  
    • rule “Send book offer only after at least 3 book presentation emails”
    •   when
    •      subscriber : Subscriber (
    •          emailReceivedWithTag(“book_explanation”) < 3
    •      )
    •      scheduling : EmailScheduling(
    •        !blocked,
    •        sending.subscriber == subscriber,
    •        sending.email.tags contains “book_offer”
    •      )
    •   then
    •        scheduling.setBlocked(true);
    • end
    •  
    • rule “Block book offers on monday”
    •   when
    •      scheduling : EmailScheduling(
    •        !blocked,
    •        sending.date.dayOfWeek == DayOfWeek.MONDAY,
    •        sending.email.tags contains “book_offer”
    •      )
    •   then
    •        scheduling.setBlocked(true);
    • end
    •  
    • rule “Block book offers for people who bought”
    •   when
    •      subscriber : Subscriber (
    •          tags contains “book_bought”
    •      )
    •      scheduling : EmailScheduling(
    •        !blocked,
    •        sending.subscriber == subscriber,
    •        sending.email.tags contains “book_offer”
    •      )
    •   then
    •        scheduling.setBlocked(true);
    • end

    Let’s examine our rules:

    • Send book offer only after at least 3 book presentation emails: we want to block any email selling the book if the subscriber did not receive at least three emails explaining the content of the book
    • Block book offers on monday: we want to block book offers to be sent on monday, for example because we have seen that subscribers are less inclined to buy on that day of the week
    • Block book offers for people who bought: we do not want to propose a deal on the book to subscribers who already bought it

    Are you looking training with Right Jobs?

    Contact Us
    Get Training Quote for Free