Tuesday, February 9, 2021

Guided Exercise: Authoring Business Rules

 


In this exercise, you will update a loan application to decide whether to approve or reject a loan.

The rules are categorized in several groups, which themselves are organized in a process for ordered execution. The complete process looks like:

The rules are organized in groups called ruleflow-groups, and as the process is executed, the different rule groups are executed in isolation from each other. This has several advantages:

  • Organization of the rules in functional groups.

  • Better understanding of the use-case and overall functionality.

  • Rule authoring becomes easier because there are ​less side-effects caused by the inference engine.

For the use case lab the following ruleflow-groups are defined:

  • Initialization rules: initialize the domain object models

  • Eligibility rules: determine whether the application is eligible. As an example, if the applicant is too young or too old, then the application is rejected.

    In the process definition, there is a decision point after the execution of the eligibility rules. If the application is not eligible, the process is terminated. In the opposite case the process continues with the interest rate calculation rules.

  • Interest calculation rules: determine the interest rate (based on requested loan amount and duration) and calculate the monthly repayment rate.

  • Loan approval rules: the loan is approved or rejected based on the debt ratio and the credit score of the applicant.

For each of these rule groups use another authoring technique. This is for educational purposes. It does not necessarily reflect the best or most convenient way to author business rules in Red Hat Decision Manager.

Outcomes

You should be able to implement rules using guided rules, decision tables, and organize the execution with ruleflows.

You must be logged in to the Decision Central web page as adminUser, using the test1234! password.

  1. Set up the project for the loan application app.

    Log in to Decision Central, and navigate to the Spaces view. From the home screen in Decision Central, click projects (just below the Design icon), and then on Spaces in the upper left corner. Click Add Space in the upper right corner. Name your new space loan-application.

    Select the loan-application space, and click Add Project to create a new project in the space. Name the project loan-application-rules.

  2. Create the Applicant data object model.

    1. The Applicant data object represents the person applying for a loan. Holds information about age and income.

      In the loan-application-rules project view, click Data Object. Alternatively, click Create New Asset and choose Data Object from the drop-down menu.

    2. In the Create new Data Object dialog box, enter Applicant as the data object name. Choose com.loan_application.loan_application_rules as package. Leave Persistable unchecked.

      Click Ok to create the data object.

  3. In the Applicant data object view, click add field to add fields to the data object.

    In the New Field dialog, enter name as id, Name as label, and String as type. Leave Listunchecked.

    Click Create and continue to create the field.

    Create the following fields for the Applicant data object:

    FieldLabelType
    nameNameString
    ageAgeint
    creditScoreCredit Scoreint
    eligibleEligibleBoolean
    monthlyIncomeMonthly Incomedouble
    yearlyIncomeYearly Incomelong

    NOTE

    Note that the field names use camel case.

    The type of the eligible field should be Boolean (with capital B).

    Once finished, the Applicant data object looks like:

    Click Save to save the data object.

  4. Create a second data object named Loan. The data object stores the characteristics of the requested loan such as ​amount and duration. The result of the approval process is stored in this object.

    In the com.loan_application.loan_application_rules package, with the following fields:

    FieldLabelType
    amountAmountlong
    approvedApprovedboolean
    commentCommentString
    durationDurationint
    interestRateInterest Ratedouble
    monthlyRepaymentMonthly Repaymentdouble
  5. Compose the initialization rules with Drools Rule Language (DRL).

    DRL is the syntax that the Decision Manager rules execution engine expects. Rules authored with different techniques are ultimately transformed in DRL rules. DRL consists of two rules

    A rule has a name, and the following skeleton:

    rule "name"
    <rule-attributes>
    when
      <conditional elements>
    then
      <actions>
    end
    • The when part (or Left-Hand Side) of the rule consists of one or more conditional patterns. If all patterns evaluate to true, the rule will fire, and the action part is executed.

    • The conditional element defines variables whenever an object of that type is in the current session. An object inserted into the working memory is also called a fact.

    • The actions part are Java code fragments. They are executed when the rule fires.

    The initialization rules set some default values on the Applicant and Loan data objects.

    In the loan-application-rules project view, click Create New Asset and choose DRL file from the drop-down menu.

    In the Create new DRL file dialog box, enter Initialisation as name of the DRL file. Select the com.loan_application.loan_application_rules package, and leave the Use Domain Specific Language unchecked.

    NOTE

    The following source code can be downloaded from http://materials.example.com/labs/Initialisation.drl

    In the DRL editor, paste the following under the package declaration:

    import com.loan_application.loan_application_rules.Applicant;
    import com.loan_application.loan_application_rules.Loan;
    
    rule "Setting default values on Applicant"
    	dialect "mvel"
    	ruleflow-group "initialisation-rules"
    	no-loop true
    	when
    	    applicant : Applicant( )
    	then
    	    System.out.println("Rule fired : [" + drools.getRule().getName()+"]");
    	    applicant.setEligible( true );
    	    applicant.setMonthlyIncome (applicant.getYearlyIncome()/12);
    end
    
    rule "Setting default values on Loan"
    	dialect "mvel"
    	ruleflow-group "initialisation-rules"
    	no-loop true
    	when
    	    loan : Loan( )
    	then
    	    System.out.println("Rule fired : [" + drools.getRule().getName()+"]");
    	    loan.setApproved( false );
    
    end
    • In the conditional element when, the pattern Applicant( ) means: there is an object of type Applicant in the working memory. There are no further constraints defined on the Applicant object. So this rule will be activated for every object of type Applicant present in the working memory.

    • In the Setting default values on Applicant rule, the eligible field is set to true, and the monthly income field is set to the value of the yearly income field divided by 12.

      As part of the rule actions the name of the rule is written to the console.

    • The ruleflow-group attribute determines to which ruleflow-group the rule belongs. Ruleflow is a feature that controls over the firing of rules. Rules that are assembled by the same ruleflow-group identifier fire only when their group is active.

      When using ruleflow processes, ruleflow-groups are used to restrict the rules that can fire in the context of a node in the process.

    • The no-loop attribute prevents a rule from being activated again after changing the state of a fact. In the case of the Setting default values on Applicant rule, the conditional pattern stays true after the firing of the rule, so no-loop prevents that the rule is activated again which would result in an endless loop.

    Validate the rules for syntax errors by clicking Validate.

    Click Save.

  6. Create a test scenario.

    The Decision Central tool allows to define test scenario’s in order to verify the correctness of the rules. Rules can be tested in isolation, or as a group.

    In general, it is considered good practice to maintain test scenario's for the rules in a rule set. In the case of large rule sets, this can become cumbersome to do so in Decision Central. An alternative is to write tests as Java unit tests, outside of the Decision Central tool. This however is out of reach for most business analysts.

    1. Create the test scenario.

      In the loan-application-rules project view, click Create New Asset and choose Test Scenario from the drop-down menu.

      In the Create new Test Scenario dialog box, enter InitialisationTests as name of the test scenario, and select the com.loan_application.loan_application_rulespackage.

    2. Define the structures used by the rules.

      Typically, test scenario’s consist of a given part, and an expectation part. In the given part, you describe the state of the working memory before firing the rules. The expectation part describes the expected outcome of the rule execution.

      Click Given. In the New input dialog box, insert a new fact of type Applicant, and bind it to the name applicant. Click Add next to the fact name.

      Click Add a field under Insert Applicant [applicant]. In the dialog box, select the yearlyIncome field. Click Ok.

      Click on the pencil icon next to yearlyIncome. In the dialog box, select Literal value. Back on the test scenario screen, type a value of 120000 in the text box next to yearlyIncome.

      Click Given to add a fact of type Loan with fact name loan.

      Click Given, and in the dialog box enter initialisation-rules in the Activate rule flow group field. Click Add

      At this moment, your test scenario should look like:

    3. Click Expect. In the New expectation dialog box, select applicant in the Fact value drop-down. Click Add.

      Back in the test scenario screen, click Applicant 'applicant' has values link. In the Choose a field to add dialog box, select the monthlyIncome field. Click Ok.

      Back in the test scenario screen, in the dropdown box next to monthlyIncome, select equals, and in the text box next to it enter 10000.0.

      Click Applicant 'applicant' has values to add another value, and this time select the eligible field.

      Set the expectation for the eligible field to equals and true.

      Click Expect. In the New expectation dialog box, select loan in the Fact value drop-down. Click Add.

      Add an expectation for the approved field of loan, and set to equals and false.

      Click Expect, and in the dialog box, select the Setting default values on Applicant rule. Click Ok. Back in the test scenario screen, select fired at least once for the Setting default values on Applicant. Repeat for the Setting default values on Loan.

      At this moment, your test scenario should look like:

      Save the test scenario.

  7. To run the scenario, click Run scenario on the top right. In the Reporting section of the section, you should see a green bar with Success. This indicates that the test scenario executed successfully.

    • A red bar means that the test failed. In that case, you need to fix the rules under test, or the test case itself. Verify the test setup (the given part) and the expectations, and correct if needed. The goal is to end with a green bar.

  8. Author rules with the Guided Rules Editor and a DSL.

    The Guided Rules Editor is a graphical editor in Decision Central that offers a graphical and guided approach to writing DRL rules. As such it is easier to use for less experienced or less technical users than the free flow DRL editor.

    In Decision Manager, a domain-specific language (DSL) acts as a kind of stylesheet for DRL rules, allowing rule fragments (conditions and actions) to be expressed in a more natural language.

    In this section of the lab, you will develop the eligibility rules, which determines whether an applicant is eligible for a loan. In this first iteration the rules are quite simple: applicants younger than 18 or older than 70 are not eligible, all the others are.

    1. Create the DSL, and use it afterwards to author the rules.

      In the loan-application-rules project view, click Create New Asset and choose DSL definition from the drop-down menu. In the Create new DSL definition dialog box, enter EligibilityDSL as name of the DSL definition file. Select the com.loan_application.loan_application_rules package. Click Ok.

      NOTE

      The following source code may be found at http://materials.example.com/labs/EligibilityDSL

      The DSL editor is a simple text editor. In the editor, paste the following contents:

      [when]The applicant is less than {age} years old=applicant:Applicant( age < {age} )
      [when]The applicant is more than {age} years old=applicant:Applicant( age > {age} )
      [when]There is a loan=loan:Loan()
      [then]The applicant is not eligible=modify( applicant ) \{ setEligible( false )\}
      [then]The loan is rejected because "{message}"=modify( loan ) \{setApproved(false), setComment( "{message}" )\}
      [then]Log rule name=System.out.println("Rule fired : [" + drools.getRule().getName()+"]");

      The DSL functionality acts as a substitution engine, where natural language fragments are replaced by DRL fragments when building the rule.

      DSL can be used in both conditions and actions. The DSL fragment starts with [when] or [then] to distinguish between both.

      The language fragments are parametrizable, and can be reused in several rules. Parameters are enclosed in curly braces.

      In a DSL fragment, the part before the = sign is the natural language fragment shown in the editors. The part following the = sign is the corresponding DRL fragment.

      Save the DSL fragment.

    2. Create the guided rule.

      In the loan-application-rules project view, click Create New Asset and choose Guided rule from the drop-down menu.

      In the Create new Guided Rule dialog box, enter EligibilityApplicantTooYoung as name of the DRL file. Select the com.loan_application.loan_application_rules package, and check the Use Domain Specific Language check box.

      In the Guided Rule Editor, click on the green + icon on the far right of the WHEN word. The Add a condition to the rule…​ dialog window opens:

      In the dialog box, select the phrase The applicant is less than {age} years old. Click Ok.

      In the guided rule editor, enter 18 in the age field.

      Click again on the green + icon to add another condition. This time select the There is a loan sentence.

      Click on the green + icon on the far right of the THEN clause to add an action to the rule. Select the The applicant is not eligible sentence.

      Add another action, and this time select The loan is rejected because {message}sentence. In the editor, enter applicant is too young as value for message.

      Add another action, and select the Log rule name sentence.

      Finally, in the editor click (show options…​). Click on the green + on the opposite side, and in the Add an option dialog box, choose the ruleflow-group attribute.

      In the editor, enter eligibility-rules as name of the ruleflow-group.

      At this point, your guided rule editor should look like:

      Save the rule.

    3. Click on the Source tab of the editor to see what the final rule looks like in plain DRL. Expect to see:

      package com.loan_application.loan_application_rules;
      
      import java.lang.Number;
      
      rule "EligibilityApplicantTooYoung"
      	dialect "mvel"
      	ruleflow-group "eligibility-rules"
      	when
      		applicant:Applicant( age < 18 )
      		loan:Loan()
      	then
      		modify( applicant ) { setEligible( false )}
      		modify( loan ) {setApproved(false), setComment( "applicant is too young" )}
      		System.out.println("Rule fired : [" + drools.getRule().getName()+"]");
      end
  9. Repeat the steps to create another guided rule with DSL. In contrast to the free DRL editor, which can contain several rule definitions in one file, the Guided rule is limited to one rule per file.

    • Name the rule EligibilityApplicantTooOld.

    • Select the Applicant is more than {age} years old as first condition. The value of age should be 70.

    • The rejection message is applicant is too old.

    • When finished, your rule should look like:

  10. Create test scenarios for the eligibility rules.

    As an example, a test scenario for the EligibilityRuleTooYoung rule could look like:

    Use as part of the Given section:

    • Applicant's information: age = 17 and name = 'John Doe'

    • Create an empty Loan

    • Activate rule flow group: eligibility-rules

    Use as part of the Expect section:

    • EligibilityApplicantTooYoung fired at least once

    • Loan's information: approved = true and comment = 'applicant is too young'

  11. Author rules in a spreadsheet editor.

    Decision tables are a popular method for authoring rules, especially among nontechnical people. Decision tables are particularly well suited for rules that can be expressed as rule templates and data, with other words when you have a potentially large set of identical rules, that only differ in the parameters they use.

    Decision Central supports the authoring of rules in Microsoft Excel or LibreOffice Calc. Authoring rules in a spreadsheet has the additional advantage that it is fairly easy to have control over what parameters of rules can be edited, without exposing the rules directly.

    Note that while supporting rules authored in a spreadsheet, Decision Central has no editor for spreadsheets. The rules need to be maintained outside of Decision Central, and uploaded as a binary file. At runtime, the spreadsheet will be converted into DRL rules.

    A rules spreadsheet has a tabular format, where columns represent a condition or an action. Every row in the table represents one rule. The spreadsheet can contain multiple tables representing different sets of rules.

    In this section of the lab, you will author the rules that determine the interest rate of the requested loan, which is a function of the loan duration and borrowed amount.

    NOTE

    To skip the creation of the spreadsheet, you may:

    • Download the spreadsheet from http://materials.example.com/labs/interest-rate-calculation.xls, and upload it to Decision Manager.

    • Implement the rules using a Guided Decision Table in Decision Manager. Instructions for doing so are provided at the end of this document.

    The calculation of the interest rate depends on the range of the loan amount and the loan duration. So in the decision table, you will need condition columns for the minimum value of the loan amount range, the maximum value of the range, and the loan duration.

    1. Create the spreadsheet.

      Open the spreadsheet program of your choice (Excel or LibreOffice) and create a new spreadsheet.

    2. Create the metadata for the interest rate calculation rules.

      In cell B2, enter the value RuleSet.

      In cell C2, enter the value com.loan_application.loan_application_rules.

      For historical reasons, the terminology used in rule spreadsheets is somewhat different than in plain DRL rules. A RuleSet is the equivalent of a package in DRL rules. A package is a means of organizing rules, it has no influence on the rule execution. Typically, rules that belong together from a functional point of view are kept in the same package.

      In cell B3, enter the value import.

      In cell C3, enter com.loan_application.loan_application_rules.Loan.

      The interest rate rules only use the Loan data object, so there is no need to import the Applicant object.

      At this point, the spreadsheet looks like:

      In cell B6, enter RuleTable Simple interest rate calculation. A RuleTable corresponds to one rule set. The name of the RuleTable will be used for the name of the generated DRL rules.

    3. Create a condition column for the minimum value of the loan amount range.

      • In cell B7, enter CONDITION to characterize the column as a condition column.

      • In cell B8, enter the fact on which the condition applies: $loan:Loan. The condition applies on an object of type Loan, bound to the variable name $loan. Note that the $ sign is merely a convention, to easily distinguish between fact bindings and fact properties.

      • In cell B9, enter the condition for this column: amount > $paramamount is a field of the Loan object and $param refers to a rule parameter, and ir corresponds to the value that will be entered in the rows of the RuleTable.

      • In cell B10, add the title for this column: Min amount. The title is only for the purpose of documentation.

    4. Create a condition column for the maximum value of the loan amount range.

      In cell C7, enter CONDITION.

      Leave cell C8 blank for the moment.

      In cell C9, enter the condition for this column: amount <= $param.

      In cell C10, add the title for this column: Max amount.

    5. Create a condition column for the loan duration.

      In cell D7, enter CONDITION.

      Leave cell D8 blank for the moment.

      In cell D9, enter the condition for this column: duration == $param.

      In cell D10, add the title for this column: Duration (years).

      Because the three conditions entered so far act on the same fact, the fact cells can be joined together. Merge the cells B8-C8-D8.

    6. Create an action column to set the interest rate of the loan, and calculate the monthly repayment.

      In cell E7, enter ACTION to characterize it as an ACTION column.

      Leave cell E8 blank.

      In cell E9, enter the action statements for this column:

      $loan.setInterestRate($param);
      $loan.setMonthlyRepayment( (($param*$loan.getAmount()/100)+$loan.getAmount())/($loan.getDuration()*12));
      System.out.println("Rule fired : [" + drools.getRule().getName()+"]");

      This sets the InterestRate field of the loan fact to the value of the rule parameter—​the value in the rows.

      This also calculates the monthly repayment (a function of the amount, the duration and the interest rate).

      Finally, log the name of the rule that fired to the console.

      In cell E10, add the title for this column: Interest rate (%).

      At this point, the spreadsheet looks like:

    7. Create a condition column for the maximum value of the loan amount range.

      Enter the first row of the table. Every row represents one rule.

      In cell A11, enter a name for the rule: Small - 7 years.

      Leave cell B11 blank

      A blank cell means that this value does not have to be taken into account.

      In cell C11, enter 300000.

      In cell D11, enter 7.

      In cell E11, enter 0.47.

      This rule states that for a loan with an amount smaller or equal to 300.000, and with a duration of seven years, the interest rate is 0.47%

      Enter the rows of the table. Every row represents one rule.

      In cell A12, enter a name for the rule: Large - 7 years.

      In cell B12, enter 300000.

      In cell C12, enter 600000.

      In cell D11, enter 7.

      In cell E11, enter 0.70.

      This rule states that for a loan with an amount between 300.000 and 600.000, and with a duration of 7 years, the interest rate is 0.70%.

      Fill in the remainder of the rows according to this table:

      NameMin AmountMax AmountDurationInterest Rate
      Small - 7 years300000 70.47
      Large - 7 years30000060000070.70
      Very Large - 7 years600000 70.98
      Small - 10 years300000 100.72
      Large - 10 years300000600000100.90
      Very Large - 10 years600000 101.10
      Small - 12 years300000 120.87
      Large - 12 years300000600000121.06
      Very Large - 12 years600000 121.31
      Small - 15 years300000 151.06
      Large - 15 years300000600000151.20
      Very Large - 15 years600000 151.45
      Small - 20 years300000 201.25
      Large - 20 years300000600000201.39
      Very Large - 20 years600000 201.65
      Small - 25 years300000 251.45
      Large - 25 years300000600000251.65
      Very Large - 25 years600000 251.85

      The resulting spreadsheet is syntactically correct, but not very readable. With the use of colors and indentation the spreadsheet is readable.

    8. Save the spreadsheet with the name interest-rate-calculation.xls

      Using the xls extension forces LibreOffice to use Excel xls format.

    9. Upload the spreadsheet to Decision Central.

      In the loan-application-rules project view, click Create New Asset and choose Decision Table (Spreadsheet) from the drop-down menu.

      In the Create new Decision Table (Spreadsheet) dialog box, name the decision table IntrestRateCalculation. Select the com.loan_application.loan_application_rules package and the appropriate format (xls or xlsx). Finally select the file to upload from your file system. Click Ok.

      In the Source tab of the Decision Table view, you can see the DRL rules that are generated from the spreadsheet.

      Note that for every row in the spreadsheet table, a rule is generated.

      The name of the rule is built from the name of the RuleTable and the row number in the spreadsheet.

  12. Author rules with the guided decision table.

    With Decision Central you can author business rules in a decision table inside the tool, rather than externally in a spreadsheet.

    The principle remains the same: columns represent conditions or actions, and every row is transformed to a single rule. Just as with spreadsheet decision tables, the decision table will be transformed to a rule set of DRL rules at runtime.

    Author the rules that determine if a loan application should be approved or rejected. This decision is a function of the applicant’s debt ratio, the credit score range, and the loan amount range. As a result the approved field of the Loan object is set to true or false.

    1. Create a guided decision table.

      In the loan-application-rules project view, click Create New Asset and choose Guided Decision Table from the drop-down menu.

      In the Create new Guided Decision Table dialog box, enter LoanApproval as the Guided Decision Table name. Select the com.loan_application.loan_application_rulespackage. Deselect Wizard. Leave the Hit Policy to None. For Table Format, choose Extended entry, values defined in table body. Click Ok.

    2. Define the minimum value of the loan amount range column.

      In the Guided Decision Table view, click on Insert → Insert column to insert a new column.

      In the Add a new column dialog box, select Add a condition. Click Next.

      In the next dialog, click Create a new Fact Pattern. Select Loan as fact type and loan as binding. Leave the Negate check box unchecked. Click Ok.

      Back in the main dialog box, click Next.

      Select Literal Value for the calculation type. Click Next.

      Select the amount field. You do not need a binding for the amount field, so click Next.

      Choose greater than as operator. Click Next.

      You do not need a value list or default values for this column, so click Next.

      Set the Header (description) to Min Amount. Leave the Hide column unchecked. Click Finish.

      At this point the decision table looks like:

    3. Add a column for the maximum value of the loan amount range.

      Select the existing Loan[loan]fact pattern, and use less than or equal to as operator for the amount field. Set the header to Max Amount.

    4. Add a condition column for the debt ratio of the applicant.

      The debt ratio is obtained by dividing the monthly repayment for the loan by the monthly income of the applicant.

      In the Guided Decision Table view, click on Insert → Insert column to insert a new column.

      In the Add a new column dialog box, select Add a condition. Click Next.

      In the next dialog, click Create a new Fact Pattern. Select Applicant as Fact type and applicant as binding. Leave the Negate check box unchecked. Click Ok.

      Choose Predicate as calculation type. Click Next.

      In the Field field, add the following predicate:

      100*(loan.getMonthlyRepayment()/this.getMonthlyIncome()) $param
      • A predicate is an expression that is evaluated to true or false.

      • When the rule is evaluated, $param is replaced by the value in the rule row for this column. If the rule contains the value < 30, the evaluated predicate becomes 100*(loan.getMonthlyRepayment()/this.getMonthlyIncome()) < 30. If the predicate evaluates to true, the rule might fire—​if all other conditions match as well.

      • this represents the current fact, in this case the Applicant.

      Leave Value list and Default value blank.

      Set the column header to Debt ratio (%).

    5. Add a condition column for the minimum value of the credit score range

      • Fact pattern: Applicant [applicant].

      • Calculation type: Literal value.

      • Field: creditScore, no binding required.

      • Operator: greater than.

      • Column header: Min Credit Score.

    6. Add a condition column for the maximum value of the credit score range

      • Fact pattern: Applicant [applicant].

      • Calculation type: Literal value.

      • Field: creditScore, no binding required.

      • Operator: less than or equal to.

      • Column header: Max Credit Score.

      • At this point the decision table looks like:

    7. Add an action column to set the approved field on the Loan object:

      • In the Guided Decision Table view, click on Insert → Insert Column to insert a new column.

      • In the Add a new column dialog box, select Set the value of a field. Click Next.

      • In the next dialog, select the Loan [loan] pattern. Click Next.

      • Select the approved field. Click Next.

      • You do not need a value list or default values for this column, so click Next.

      • Set the Header description to Approved. Leave Hide column unchecked. Leave Update engine with changes unchecked. Click Finish.

    8. Add an action column to set the comment field of the Loan object.

      • Use the Set the value of a field column type.

      • Use the Loan [loan] fact pattern.

      • Use the comment field.

      • In the Value list field, add the value enumeration for the comment field:

        "insufficient credit score","sufficient credit score","debt ratio too high","amount too low","amount too high"
      • Set the Header description to Comment. Leave the Hide column unchecked. Leave Update engine with changes unchecked.

    9. Add an action column to log the name of the rule to the console when it is fired.

      • In the Guided Decision Table view, click on Insert → Insert Column to insert a new column.

      • In the Add a new column dialog box, mark the Include advanced Options checkbox. Select Add an Action BRL fragment. Click Next.

      • In the next dialog window, click on the green + icon next to THEN. In the Add a new action dialog box, select Add free form DRL.

      • Back in the Add a new column dialog box, enter the following in the free from DRL text box:

        System.out.println("Rule fired : [" + drools.getRule().getName()+"]");
      • Set Log rule name as header description, and check the Hide column checkbox. Click Finish.

  13. Specify that the rules in the decision table belong to the approval-rules ruleflow group. This can be done with a hidden attribute column with default values.

    In the Guided Decision Table view, click Insert → Insert column to create a column.

    In the Add a new column dialog box, check the Include advanced Options checkbox. Select Add an Attribute column. Click Next.

    In the Select an Attribute dialog box, select Ruleflow-Group. Click Finish.

    Back in the Guided Decision Table editor, open the Columns tab, and expand the Attribute columns section.

    In the Default value text box, enter approval-rules. Check the Hide column check box.

    NOTE

    The default value is required to make sure that the ruleflow-group value sets automatically whenever a new rule row is added.

  14. Add the first rule row to the decision table.

    In the Guided Decision Table view, in the Editor tab, click Insert → Append row.

    Fill in the following values:

    • Description: Rejected - amount too low.

    • Min Amount: leave blank

    • Max amount: 1000

    • Debt ratio: leave blank

    • Min Credit Score: leave blank

    • Max Credit Score: leave blank

    • Approved: make sure to deselect

    • Comment: Select amount too low

    At this point the decision table looks like:

    Add the remainder of the rows according to the following table:

    DescriptionMin AmountMax AmountDebt RatioMin Credit ScoreMax Credit ScoreApprovedComment
    Rejected - amount too low 1000   Noamount too low
    Rejected - amount too high1000000    Noamount too high
    Rejected - debt ratio too high10001000000> 30  Nodebt ratio too high
    Rejected - insufficient credit score1000 <= 30 300Noinsufficient credit score
    Approved - sufficient credit score1000100000<= 30300 Yessufficient credit score
    Rejected - insufficient credit score100000400000<= 30 400Noinsufficient credit score
    Approved - sufficient credit score100000400000<= 30400 Yessufficient credit score
    Rejected - insufficient credit score400000500000<= 30 500Noinsufficient credit score
    Approved - sufficient credit score400000500000<= 30500 Yessufficient credit score
    Rejected - insufficient credit score5000001000000<= 30 700Noinsufficient credit score
    Approved - sufficient credit score5000001000000<= 30700 Yessufficient credit score

    In the Guided Decision Table view, click Validate. The validation should be successful.

  15. Evaluate the DRL rules generated from the decision table, click on the Source tab.

    Optionally, you can create test scenarios for the approval rules.

    As an example, a test scenario for the Accepted - sufficient credit score for a loan with an amount between 400000 and 500000 could look like:

  16. Build the ruleflow process that will govern rule execution as a ordered set of activities.

    In Red Hat Decision Manager, you can design ruleflow processes using BPMN2. However, not all BPMN2 constructs are supported. For example, there is no support for human tasks, as this would require a persistence engine to store the state of the process while waiting for the human task to be completed. Red Hat Decision Manager only supports in-memory execution of BPMN2 processes.

    1. Create a new business process.

      In the loan-application-rules project view, click Create New Asset and choose Business Process from the drop-down menu.

      In the Create new Business Process dialog box, enter LoanApplicationProcess as the name of the business process. Select the com.loan_application_loan_application_rules package. Click Ok.

      The Business Process editor opens. At this moment, the process only consists of a start node (the green circle).

    2. Configure the business process to support the data objects.

      Open the property pane by clicking << icon on the top right of the canvas.

      Click the Imports drop-down arrow to open the Editor for Imports dialog box.

      Click Add Import, select the default import type, and click on the Defined Class Name drop-down box. Select Applicant. Click Ok.

    3. Add a business rules node for the initialization rules.

      Select the start node, click on the square box on the right, and drag a node to the canvas.

      Select the new node, and hover over the tool icon at the bottom. In the pop-up box, select Business Rule Task.

      Alternatively, open the Object Library pane by clicking on the >> icon on the top left of the canvas. Open the Tasks pane, and drag a Business Rule task node on the canvas. Select the start node, select the arrow icon and drag into the business rule task node to connect the start node to the business rule task node.

      Select the business rule task node, and open the property pane by clicking on the << icon on the top right of the canvas.

      In the property pane, enter Initialisation in the Name text field box, and click on the Ruleflow Group drop-down arrow to open the ruleflow-group selection dialog.

      Select the initialisation-rules by clicking on the name of the ruleflow-group, and click Save.

    4. Add a business rules node for the eligibility rules.

      • Select the Initialisation node, click on the square box on the right, and drag a node to the canvas.

      • Select the new node, and hover over the tool icon at the bottom. In the pop-up box, select Business Rule Task.

      • Select the business rule task node, and open the property pane by clicking on the << icon on the top right of the canvas.

      • In the property pane, enter Eligibility Rules in the Name text field box, and click the Ruleflow Group drop-down arrow to open the Ruleflow Group selection dialog.

      • Select the eligibility-rules by clicking on the name of the Ruleflow Group, and click Save.

    5. Add a gateway node. After the execution of the eligibility rules, the process can go two ways: if the applicant is not eligible, the process should stop—​there is no point in continuing. If the applicant is eligible, the process should continue with the interest rate calculation and approval rules.

      Select the Eligibility Rules node, and click on the diamond-shaped icon on the right to drag an exclusive gateway (also called XOR gateway) to the canvas.

      Select the gateway node, click on the circle icon on the right, and drag an end node to the canvas.

      Select the arrow between the gateway node and the end node, open the property pane. Enter no in the Name field. Click on the drop-down arrow next to Condition Expression Language, and select drools from the drop-down list.

      Select the drop-down arrow next to Expression to open the Expression Editor dialog box.

      In the editor, enter the following expression:

      Applicant( eligible == false )

      Click Ok.

    6. Express the gateway condition with a DRL condition statement.

      The DRL expression evaluates to true if there is an Applicantobject with field eligible set to false in the rules working memory. This is the case if one of the eligibility rules fired.

      Select the gateway node, click on the square icon to the right and drag a task node to the canvas.

      Select the arrow between the gateway node and the new task node. Open the property pane, and enter yes in the Name field.

      Select the gateway node, open the property pane, and click on the drop-down arrow next to the default gate field. Select yes in the drop-down menu.

      The no branch is evaluated first. If it evaluates to false, then the execution follows the default branch (yes).

    7. Add a business rules node for the interest rate calculation rules.

      Select the task node to the right of the gateway node. Hover over the tool icon at the bottom. In the pop-up menu, select Business Rule Task.

      In the property pane, enter Interest Rate Calculation in the Name text field box, and click on the Ruleflow Group drop-down arrow to open the Editor for RuleFlow Groups selection dialog.

      Select calculation-rules by clicking in the ruleflow-group, and click Save.

    8. Add a business rules node for the approval rules.

      Select the task node to the right of the Interest Rate Calculation node. Hover over the tool icon at the bottom. In the pop-up menu, select Business Rule Task.

      Use Approval Rules for the node name.

      Use the approval-rules ruleflow-group.

      Select the Approval Rules node, and drag an end node to the canvas. The completed business process looks like:

      Click on the Save to save the process.

  17. Build the loan application and deploy it to a Decision Manager Execution Server.

    By now you have all the pieces to be able to deploy and test the Loan Application business rules app. Using the built-in Swagger integration, you can easily test the application.

    1. Define the knowledge base and knowledge session, and set the project version.

      In the loan-application-rules project view, click Settings in the top right corner to open the Project Settings View.

      In the Project Settings view, select Knowledge bases and sessions from the Project Settings drop-down list,

      In the Knowledge Base Settings view, click Add to create a Knowledge base definition.

      In the pop-up window, enter default-kbase as the knowledge base name.

      Scroll down to the Knowledge Sessions section, and click Add.

      In the pop-up window, enter default-ksession as the knowledge session name.

      Check the Default check box, and make sure the state is set to Stateless.

      When using a stateless session, a new session is created on the Decision Manager Execution Server for every request. This ensures that different invocations of the rule engine are completely isolated from each other. With a stateful session, different invocations would share the same session, and would be able to see and act on each other fact objects, leading to unwanted side-effects. There are valid use-cases for stateful sessions, but for most one-off calculation-type decisions a stateless session is recommended.

      Click Save.

      Click Knowledge Base Settings on the top left of the screen, and select Project General Settings from the drop-down box.

      Change the version of the project from 1.0.0 to 1.0.0-SNAPSHOT.

      Working with a snapshot version makes it a lot easier during the development phase to do iterative deployments of the project.

      Click Save to save the project settings.

    2. Build and deploy to the Decision manager Execution Server.

      In the loan-application-rules project view, click Build & deploy in the top right corner.

      Expect to see a green bar appearing at the top of the screen to indicate success.

      The Build & Deploy action compiles the project assets, packages them in a archive and deploys the archive on the execution server.

      If the build fails, then something is wrong with one or more of the project assets. In that case, inspect the messages, and make the required adjustments.

      Navigate to the Decision Central home screen, and click on the deploy icon. In the deploy screen verify that the loan-application-rules container is deployed on the execution server

    3. Test the application using Swagger

      In another browser window or tab, navigate to the URL of the Red Hat OpenShift Container Platform. Log in into the console, and in the left panel, navigate to the Applications → Routes section. Copy the URL of the secure-gpte-kieserver route.

      Open a new browser tab or window, paste the URL in the address bar and append the /docs path. Expect a Swagger UI page to open.

      Ignore the warnings about untrusted certificates, and add security exceptions in order to access the Execution Server.

      The Swagger page documents the REST API exposed by the Execution Server.

      Scroll down in the Swagger UI page until you find the Rules evaluation :: BRM section.

      Click on the POST link to expand the section, and click Try it out on the left.

      In the id field, enter loan-application-rules.

      Under the body field, change the Parameter content type to application/json.

      Under the Execute, change the Response content type to application/json.

      NOTE

      The following JSON file may be downloaded from http://materials.example.com/labs/loan.json.

      Paste the following contents in the body field:

      {
        "lookup": "default-ksession",
        "commands": [
          {
            "insert": {
              "object": {
                "com.loan_application.loan_application_rules.Applicant": {
                  "creditScore":410,
                  "name":"Lucien Bramard",
                  "age":40,
                  "yearlyIncome":90000
                }
              },
              "out-identifier":"applicant"
            }
          },
          {
            "insert": {
              "object": {
                "com.loan_application.loan_application_rules.Loan": {
                  "amount":250000,
                  "duration":10
                }
              },
              "out-identifier":"loan"
            }
          },
          {
            "start-process" : {
              "processId" : "loan-application-rules.LoanApplicationProcess",
              "parameter" : [ ],
              "out-identifier" : null
            }
          }
        ]
      }

      The lookup directive specifies the name of the session to use. This corresponds to the name of the stateless session declared in the project.

      The command directive describes the commands to execute on the Execution Server. In this case two objects are inserted in the working memory of the session, one of type Applicant and another of type Loan. Finally an instance of the ruleflow process is started, which in turn triggers activation and firing of the rules.

      The out-identifier directive is used to indicate that the object should be part of the response. The state of the Applicant and Loan object is changed as result of rule execution, so to be able to inspect the result of the rules they need to be part of the result payload.

      Click the Execute bar to post the request to the execution server.

      The first time you do so, an authentication pop-up appears. The REST API of the execution server is protected with basic authentication. In the pop-up enter the credentials you use for Decision Central (adminUser/test1234!).

      Expect to see the following response in the Server response section:

      {
        "type" : "SUCCESS",
        "msg" : "Container loan-application-rules successfully called.",
        "result" : {
          "execution-results" : {
            "results" : [ {
              "value" : {"com.loan_application.loan_application_rules.Loan":{
        "amount" : 250000,
        "approved" : true,
        "comment" : "sufficient credit score",
        "duration" : 10,
        "interestRate" : 0.72,
        "monthlyRepayment" : 2098.3333333333335
      }},
              "key" : "loan"
            }, {
              "value" : {"com.loan_application.loan_application_rules.Applicant":{
        "name" : "Lucien Bramard",
        "age" : 40,
        "creditScore" : 410,
        "eligible" : true,
        "monthlyIncome" : 7500.0,
        "yearlyIncome" : 90000
      }},
              "key" : "applicant"
            } ],
            "facts" : [ {
              "value" : {"org.drools.core.common.DefaultFactHandle":{
        "external-form" : "0:2:1424229236:1424229236:2:DEFAULT:NON_TRAIT:com.loan_application.loan_application_rules.Loan"
      }},
              "key" : "loan"
            }, {
              "value" : {"org.drools.core.common.DefaultFactHandle":{
        "external-form" : "0:1:268014846:268014846:1:DEFAULT:NON_TRAIT:com.loan_application.loan_application_rules.Applicant"
      }},
              "key" : "applicant"
            } ]
          }
        }
      }

      Note that the approved field of the Loan object is set to true, and the comment is set to sufficient credit score. The calculated interest rate is 0.72, and the monthly repayment amounts to 2098.3333333333335.

      Feel free to change some of the values in the request JSON (loan amount, duration, age, yearly income, credit score) and verify how the outcomes changes when the input parameters change.

    This concludes this guided exercise.

  18. Extra: Implement the Interest Rate Calculation rules as Guided Decision Table

    1. In the loan-application-rules project view, click on the Create New Asset and choose Guided Decision Table from the drop-down menu.

    2. In the Create new Guided Decision Table dialog box, enter InterestRateCalculation as the Guided Decision Table name. Select the com.loan_application.loan_application_rules package. Deselect Wizard. Leave the Hit Policy to None. For Table Format, choose Extended. Click Ok.

    3. The first condition column defines the minimum value of the loan amount range.

      • In the Guided Decision Table view, click on Insert → Insert Column to insert a new column.

      • In the Add a new column dialog box, select Add a condition. Click Next.

      • In the next dialog, click Create a new Fact Pattern. Select Loan as Fact type and loan as binding. Leave the Negate check box unchecked. Click Ok.

      • Back in the main dialog box, click Next.

      • Select Literal Value for the calculation type. Click Next

      • You do not need a binding for the amount field, so click Next.

      • Choose greater then as operator. Click Next.

      • You don’t need a value list or default values for this column, so click Next.

      • Set the header description to Min Amount. Leave the Hide column unchecked. Click Finish.

      • At this point the decision table looks like:

    4. Add a column for the maximum value of the loan amount range. Select the existing Loan[loan] fact pattern, and use less than or equal to as operator for the amount field. Set the header to Max Amount.

    5. Add a column for the duration of the loan. Select the existing Loan[loan] fact pattern, and use equal to as operator for the duration field. Set the header to Duration.

    6. Add an action column to set the interestRate field on the Loan object and calculate the monthly repayment rate:

      • In the Guided Decision Table view, click on Insert → Insert Column to insert a new column.

      • In the Add a new column dialog box, check the Include advanced optionscheck box. Select Add an action BRL fragment. Click Next.

      • In the next dialog, click on the green + icon. In the Add new Action dialog box, select Change field value of loan. Click on the pencil icon next to Loan[loan]. In the Add a field dialog box, select interestRate. Click the pencil icon next to interestRate. Select Template key.

      • Click the green + icon next to THEN to add another fragment. In the Add new Action dialog box, select Change field value of loan. Click on the pencil icon next to Loan[loan]. In the Add a field dialog box, select monthlyRepayment. Click on the pencil icon next to monthlyRepayment. Select Formula. In the formula text box, paste the following contents:

        ((loan.getInterestRate()*loan.getAmount()/100)+loan.getAmount())/(loan.getDuration()*12))
      • Click on the green + icon next to THEN to add another fragment. In the Add new Action dialog box, select Add Free Form DRL. In the DRL text box, add the following contents:

        System.out.println("Rule fired : [" + drools.getRule().getName()+"]");
      • Click Next. In the next dialog, set the Header description to Interest Rate. Leave Hide column unchecked. Click Finish.

    7. Finally, specify that the rules in the decision table belong to the calculation-rules ruleflow-group. This can be done with a hidden attribute column with default values.

      • In the Guided Decision Table view, click Insert → Insert columnto insert a new column.

      • In the Add a new column dialog box, check the Advanced Options checkbox. Select Add an Attribute column. Click Next.

      • In the Select an Attribute dialog box, select Ruleflow-Group. Click Finish.

      • Back in the Guided Decision Table editor, open the Columns tab, and expand the Attribute columns section

      • In the Default value text box, enter calculation-rules. Check the Hide column check box.

        • The default value is required to make sure that the ruleflow-group value is set automatically whenever a new rule row is added.

    8. Add the first rule row to the decision table.

      • In the Guided Decision Table view, click on Insert → Append row to append a row to the table.

      • Fill in the following values:

        • Description: Small - 7 years.

        • Min Amount: leave blank

        • Max amount: 300000

        • Duration: 7

        • Interest rate: 0.47

      • At this point the decision table looks like:

    9. Add the remainder of the rows according to the following table:

      NameMin AmountMax AmountDurationInterest Rate
      Small - 7 years300000 70.47
      Large - 7 years30000060000070.70
      Very Large - 7 years600000 70.98
      Small - 10 years300000 100.72
      Large - 10 years300000600000100.90
      Very Large - 10 years600000 101.10
      Small - 12 years300000 120.87
      Large - 12 years300000600000121.06
      Very Large - 12 years600000 121.31
      Small - 15 years300000 151.06
      Large - 15 years300000600000151.20
      Very Large - 15 years600000 151.45
      Small - 20 years300000 201.25
      Large - 20 years300000600000201.39
      Very Large - 20 years600000 201.65
      Small - 25 years300000 251.45
      Large - 25 years300000600000251.65
      Very Large - 25 years600000 251.85
    10. In the Guided Decision Table view, click Validate to validate the decision table. The validation should be successful.

    11. To see the DRL rules generated from the decision table, click on the Source tab.

    12. Optionally, you can create test scenarios for the calculation rules.

      • As an example, a test scenario for the Small - 7 years rule could look like:

This concludes the guided exercise.