Wednesday, February 1, 2017

Business Rules with Decision Tables in SOA 11g

In my previous blog, we have seen how to work with business rules using if/else rule sets. I will take the same example/scenario here to show how decision tables in business rules work.
You can find my previous blog about business rules here.


Before we get into the actual implementation, there are some business rules components, we need to get familiar with.
  1. Facts – The data on which the rules will be applied. The input schema/message of the business rules service component usually acts as fact.
  2. Functions – These can be compared to java functions. We can define a custom function which takes inputs, performs complex logic around the data (even looping around the data) and returns some output.
  3. Rule Sets – Set of rules forms this component. Multiple rules can be combined together in an executable sequence. There are 2 types of rule sets – If/Then rule sets and Decision Table.
  4. Globals – These are variables which can be defined as constants or modifiable fields and can be used across rules and rule sets.
  5. Bucket Sets – Bucket Sets contain a set of values which can be used in decision tables. These set of values can be
    1. List of Values derived from the enumeration of a schema
    2. List of Value ranges Eg: 0 – 10, 11 – 60, 61 - 255, etc for ip address ranges
    3. Random LOV types – String LOVs, Integer LOVs, etc
Scenario goes like this - An online order management system takes orders from customers. This business rules project checks if customer is eligible for any discounts or offers, based on various parameters and business rules. Here are the rules 

Repeating customer –
a.    Repeating Customer gets 20% off
b.    If purchase amount >= 50, free shipping
c.    If purchase amount < 50, no free shipping

New customer –
a.    If purchase amount >= 50 and < 100, free shipping
b.    If purchase amount >=100, free shipping + 15% off
c.    If purchase amount <50, not eligible for any offer

Steps to create the project:

1. Create a simple SOA project - OfferCheck.
2. Create an XSD which would hold the fields required for the input and output of this service. I am using the following xsd.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://www.offer.com/pg"
            targetNamespace="http://www.offer.com/pg"
            elementFormDefault="qualified">
  <xsd:element name="CustomerInformation" type="CustomerInformationType"/>
  <xsd:complexType name="CustomerInformationType">
    <xsd:sequence>
      <xsd:element name="RepeatingCustomer" type="xsd:string"/>
      <xsd:element name="PurchaseAmount" type="xsd:double"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:element name="Offer" type="OfferType"/>
  <xsd:complexType name="OfferType">
    <xsd:sequence>
      <xsd:element name="OfferApplied" type="xsd:string"/>
      <xsd:element name="FreeShipping" type="xsd:string"/>
      <xsd:element name="PercentageDiscount" type="xsd:int"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

3. Drag and drop a business rule component and choose CustomerInformation as the input and Offer as output from the above xsd. Make sure that the Expose as Composite Service is checked and click ok.

Business Rule

4. In the Rules editor, you would find several sections. Click on facts. This screen will show you the information (from schemas - input/output) which can be used to create rules.

Facts

5. In the Bucketsets section, by default, you would see the enumeration fields from the schema. If the schema does not have enumeration, this section would be empty. In this scenario, as we need to check the amount spent between ranges, we will create a bucketset as follows.

6. Click on the + icon at the right and choose List of Ranges.Bucketsets

7. By default, you would see an infinity row. On clicking on the = icon further, it will allow you enter the lowest range you want to check. As this scenario, < 50 is the lowest. Hence, we would enter 50 in the end point column of the new row and click enter. The Range and Alias column get defaulted as below. You can add description.
BucketSet


8. As you further click on the + icon, it would add the ranges and you can modify as required. The final Bucketset as per our requirement would be as follows.

9. Now click on the RuleSet section, you would see two options there - If/Then Rule, Decision Table. Click on Create Decision Table.
10. In the decision table, you would find two sections, <insert condition> where the conditions to be checked are inserted, <insert action> where the result is captured.
11. Our first condition is to check if the Customer is repeating or not. Click on + icon on the right top and click on Condition to add a new condition.
12. A new row will get added. The drop down in the conditions row will show you all the value options from which you can frame the condition.

13. Expand CustomerInformationType and click on repeatingCustomer as follows. C1 condition gets added.
Decision Table COndition

14. Click on the Row R1. As we need to check Repeating Customer value as Y, manually enter as "Y".

15. Now to add a new rule, click on the same + icon, and click on Rule. Under Row R2, click as otherwise.

16. Our next condition is on the purchaseAmount. Similar to C1, insert a new condition C2 and choose purchaseAmount from the drop down.

17. Above the conditions section, you will by default see "Local List of Values". Keep condition C2, selected and choose SpentAmount from the "Local List of Values" drop down. As purchaseAmount needs to be checked based on a range, we will use SpentAmount Bucketset here to set the rule for condition C2.

List of Ranges

18. Right click on R1 corresponding to C2 and click Split Selected Cell.

As SpentAmount Bucketset has 3 ranges. The cell would be automatically split into 3 parts and defaulted with all the ranges in the bucketset as follows.


19. Perform the same step with the other rule under C2.
20. Finally you will see all the rules and conditions updated as follows.

21. Next step is to update the output.
22. Under Action, click on <insert action>, assert new.
Assert new action

23. In the pop window, choose OfferType in the Facts and choose all the 3 fields - freeShipping, offerApplied, percentageDiscount as parameterized and click ok.
Actions

24. You would now see all these fields in the actions. Now corresponding to each condition, set the constant output that should be returned.

25. The final screen would look as follows.

26. Deploy the project and test. You would find the results as per the scenario.

These business rules can be changed from SOA composer console without touching the code as shown in my previous blog.


5 comments: