A Slight Briefing
Oracle Business Rules is a high performance and lightweight business rules product that is part of the Oracle Fusion Middleware Suite that can be used in both SOA and BPM suite.
To have a business process more agile and coherent with the changing demands of Business, Oracle Business rules is a must for any design. Also it should act as a central component where all process rules are located.
With OBR 11g one added advantage of business rules is that they can be exposed as any other web service. This makes it an instant hit as it becomes hot pluggable.
Here in this example blog i would show how to create a complex rule in JDeveloper and test it out through multiple ways. This is intended to be a zero lecture hands on so i would skip the talk.
Prerequisites
-
SOA Suite 11gPS2 or PS3 is installed in your local machine.
-
A SOA Domain (either an all in one or standard) is created in your local machine.
http://wiki.oracle.com/page/Oracle+SOA+Suite+11g%3A+Hown+To+Create+All+In+One+AdminServer -
JDeveloper is installed in your local machine.
-
An Oracle Database (11g preferably) is accessible from the SOA domain.
The Scenario
A high school needs a web service implemented as a rule in Oracle that calculates the grades of students.
The service would take some basic candidate information and an array of subjects/marks that the candidate has obtained. The rules engine will have to allocate the candidate Grades on the basis of the following logic.
Average Marks | Grade Allotted |
<40 | FAIL |
40-60 | FAIR |
60-80 | GOOD |
80-90 | VERY GOOD |
90-100 | OUTSTANDING |
For the sake of this demonstration we would use an XSD definition for CandidateInformation and CandidateGrade.
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="<a href="http://www.w3.org/2001/XMLSchema"">http://www.w3.org/2001/XMLSchema"</a> xmlns="<a href="http://www.example.org"">http://www.example.org"</a> targetNamespace="<a href="http://www.example.org"">http://www.example.org"</a> elementFormDefault="qualified"> <xsd:element name="CandidateInformation" type="CandidateInformationType"/> <xsd:element name="CandidateGrade" type="CandidateGradeType"/> <xsd:complexType name="CandidateInformationType"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="rollNumber" type="xsd:string"/> <xsd:element name="class" type="xsd:string"/> <xsd:element name="section" type="xsd:string"/> <xsd:element name="remarks" type="xsd:string"/> <xsd:element name="subject" type="SubjectType" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="CandidateGradeType"> <xsd:sequence> <xsd:element name="overallGrade" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="SubjectType"> <xsd:sequence> <xsd:element name="subjectName" type="xsd:string"/> <xsd:element name="subjectCode" type="xsd:string"/> <xsd:element name="subjectMark" type="xsd:int"/> </xsd:sequence> </xsd:complexType> </xsd:schema>
Save it somewhere as GradesAllocation.xsd
The Solution
- Open JDeveloper and Create a New SOA Application.
- Name the application as BusinessRulesApplication and click on Next.
- Name the project as BusinessRulesProject and again click Next. Make sure ‘SOA’ is selected under ‘Project Technologies’
- Choose ‘Composite with Business Rule’ and click on ‘Finish’.
- You would see that a window pops out to create a rule and specify the inputs and output for the rule.
- Name the rule as ‘GradeAllocationRule’ and click on the ‘+’ icon to specify the Input and Output types for the rule. Select ‘CandidateInformation’ from the GradeAllocation.xsd as the input and CandidateGrade as the output.
- Wait for the wizard to create the rule definition. Click on the Ruleset at the top and rename it to ‘GradeAllocation’.
- Click on ‘Bucketsets’ link in the left most panel and Add a ‘List of Ranges’.
- Name the bucketset as ‘markRange’ and create a list of ranges as under.
- Click OK to save changes to the bucketset and click on GradeAllocation ruleset.
- Select ‘Create Decision Table’ from the two options. Remember that we can either create an ‘if-then-else’ rule or a decision table. A decision table is implicitly evaluated as an ‘of-then-else’ rule only but gives a better manageability to rule definitions.
- Name the decision function as ‘decideGrade’ and check ‘Advanced Mode’ to be true.
- Click on ‘Insert Pattern’ in the workspace below.
- Right Click on the ‘variable’ block and click on ‘Surround with’ and click on ‘Pattern Block’
- Click on the auto generated expression and from the dropdown select ‘aggregate’
- Now click on variabe and define a variable named ‘averageMarks’, Click on ‘functions’ to select ‘average’ from the dropdown. Click on ‘fact type’ to select ‘SubjectType’ element as the fact. Name this as ‘subjectType’. Click on ‘expression’ now to select ‘subjectType.subjectMark’ as we are interested in the average marks across all subjects. The overall construct should look like below :
- Click on ‘insert condition’ in the panel below and then click ‘edit condition’ to select ‘averageMarks’ from the option. Choose the bucketset ‘marksRange’ from the dropdown ‘Local List of Ranges’.
- Click on the ‘+’ icon adjacent to the range dropdown and keep adding a rule for each of the range. Remember you have to add six distinct rule. Select a distinct value defined in the bucketset each time. Here is how to define the rules.
- Now go to the ‘Actions’ panel and click on ‘insert action’. Select ‘Assert new’. Double click on the action and click on ‘CandidateGradeType’ under Facts. Check the option ‘Parameterized’ for the property ‘overallGrade’
- Now click on each of the option box in the Grid to define a value for the outcome. Since overallGrade is a String type, assign a grade in string for each of the condition as under
- Save all projects and files in JDeveloper. With this we are done with the Rules creation part. So here is a summary of what we did.
- Created a bucketset for a list of mark ranges and grade type associated with them.
- Created a decision table for a set of rules. Initialized a variable for ‘averageMarks’ and using a pattern block assigned it as an average of all subject marks.
- Now for each condition for the rule asserted the outcome for ‘CandidateGrade.overallGrade’ with the grade that has to be assigned.
- Pretty simple. Isn’t it?
Testing the Rules
Creating business rules isn’t just enough. There has to be a mechanism to test them. Remember Oracle Rules engine is a inference based rules engine i.e rules are all evaluated at runtime. For more information on how rules are evaluated refer to Oracle Business rules architecture. Here I would show how rules can be tested using three ways.
Testing Rules by Creating a Debug RL function
- Click on the ‘Functions’ link and add a new function and name it to ‘DebugRule’. Select boolean under both Return Type and Bucketset.
- For the body part of the function we would right an RL construct to initialize CandidateInformationType (input to the rule) and pass some dummy values to it.
- Check the screen snap below and create a body exactly like the one below
- Now if you are familiar with any programming language understanding the above construct should be like a cakewalk.
- You would now see that the ‘Test’ link for the function becomes enabled. Click on it to test the rule output.
- Here you go. You can see that the output grade is ‘OUTSTANDING’. Has to be since the dummy value of marks assigned were 100 and 100. You can now change the marks in the subjects or add a new subject type to test the rule again for a different output.
- You can create as many Rulesets as you may for evaluating more complex conditions and add them to the Decision Functions in the order you would need their evaluation to come up with complex business scenarios.
Testing Rules from EM console
- Deploy the BusinessRulesProject to a domain server extended with soa suite. Boot up the em console and browse to the project composite.
- Click on the ‘Test’ icon for the composite to launch the EM test wizard for the composite.
- You would see a Tree View for the request message for the composite wherein you can input sample values
- Fill in any random values for the type bpelInstance. The only important value would be the attribute ‘NCName’. Make sure you put the name of your Decision Function there.
- Fill the request wizard with CandidateInformation as under
- Click on Test Web Service button on top left of the page to test the Rules decision service.
- Expand the CandidateGrade in the Response tab to see the overallGrade for the student.
- You can click on ‘Launch Flow Trace’ to view the execution trace for the Decision Service.
- You can see how easily we can test out our Business rules from the EM console.
Testing Rules from SOAP UI
More than often in real life scenarios we would like to create some kind of a unit testing suite for out business rules. Ag you might have already made note that in SOA suite 11g Business rules are exposed as standard web services that can be invoked from anywhere. See the demonstration below to see how Business rules can be externalized as web service and invoked through third parties even.
- Go to the BusinessRulesProject composite in the EM console.
- Click on the ‘Service Icon’ to copy the WSDL endpoint for the rules service.
- Create a SOAPUI project based on this WSDL.
- Fill the mock service request with actual values
- Run the test and you should see the outcome from the Rules decision function.
Now you can build a test suite to create mock requests for various scenarios and assert the responses.
The JDeveloper project used in this example can be downloaded from here.
Pingback: Testing Oracle Business Rules using Java « Oracle Technologies Premier
Awesome document!! can’t ask for more for beginners on Oracle Business Rules.
LikeLike
Outstanding post. Really helpful to one and all soa beginners.
Rajasekhar Yandrapu
LikeLike
Is it possible to integrate Oracle service Bus with Oracle Business Rule ,please suggest me some site/samples/reference or provide steps for same if possible.
LikeLike
There are two ways you can do it.
1. Oracle Business Rules can be exposed as standard soap based web-services that can be consumed in OSB through Business Services. Proxy Services in OSB can call these BS created out of the rules services in their message pipelines.
2. Second option is to use DIRECT-BINDING to communicate between a Rule based Composite and OSB. Direct Binding optimizes the communication between OSB and SOA servers at the transport level.
Here is a post that talks how you can use Direct Binding.
http://biemond.blogspot.com/2009/11/calling-soa-suite-direct-binding.html
LikeLike
Excellent article for soa begineers
LikeLike
Thanks Prakash. Appreciate your feedback.
LikeLike
Pingback: Automating Business Rules Testing in Oracle SOA Suite 11g « Oracle Technologies Premier
I tried testing the rule using DebugRule function, i am not able to get expression call candidateInformation.subject.append(stringvalue). Am i missing something or any additional steps needs to be done
LikeLike
Well, I would be able to help you, if you can upload a picture or paste the test function that u are using.
Cheers
LikeLike
Many thanks for sharing such (not well documented) knowledge and building wonderful demonstrations. Are you aware if it is possible to extend the default Business Rules functions, by invoking some custom Java classes? This capability, would enrich the shipped function set and would make it fit into complex customer needs, where assistance of existing code assets is needed, for evaluating some rules.
LikeLike
Thanks for the feedback. There is definetely a support for writing custom rule functions with the RL language. It is pretty much similar to JAVA and if you know Java, then writing RL expressions will not be a problem.
LikeLike
Hi , in the above example the facts your are using is xml facts ….instead xml facts i need one sample of RL facts and using RL facts how we are going to test function and test suite.
LikeLike
If you are using a rule based on RL fact types then you will need to create a test RL function for pass the RL facts to invoke your rule.
LikeLike
Your blog is just what I needed. You have no idea how long
I have been pondering the same thing! I am so pleased that I
am not alone.
LikeLike
Pingback: Unit Testing Business Processes in Oracle BPM Suite 11g | Oracle Technologies Premier
Hi ,
Nice post . But when i added the jaxb classes to the library and classpath . But when i was trying to run the application , it is not able to deploy because it could not find these class files while deploying . What could be the issue ?
Tahnks
LikeLike
Great document!! donot nedd more for beginners on Oracle Business Rules
LikeLike
Thanks Eva.
LikeLike
Wonderful post – but using JDev 11.1.1.7, I am unable to complete the RL Debug function. I get an error at the point that I enter “assign new List grade = GradeAllocationRule_decideGrade(candidateInformation)” – error reads “RUL 05716 – function ‘GradeAllocationRule_decideGrade’ is not valid here”. Any thoughts? Thanks!
LikeLike
Hi David,
Thanks for your comment. When i wrote this blog, I guess the product version was 11.1.1.4 or 11.1.1.5. There may have been some slight modifications since then. I will have to re validate the application for PS6.
Thanks
LikeLike
Hi Arun,
I am trying to code a business rule like below. Can you pls give an idea on how to proceed.
Was trying to use decision table for this.
if ((a =1 and b=2) or (c = 3 and d = 4)){
if (d = 5 and e = 6){
action a1;
}
} else {
action a2;
}
LikeLike
Hi, I have one scenario where my request xsd has only one element “keyvaluepair”. This “keyvaluepair” is unbounded means it can occur any number of times in the request. It has two child elements viz “key” and “value”. I want to know how many elements have come in request and read all those keys and values. I will have number of rules in ruleset based on these keys and values. I created a function. In that function I created a HashMap and stored all keys values in that map. I am facing issues while accessing map elements in rules. Please provide some suggestion.
LikeLike
Hi Aamir,
Oracle Business Rules has functions that allow you to iterate over a collection. Did you try to explore it as opposed to using a map function?
LikeLike
Reblogged this on Black Hole Of My Memory.
LikeLike
Pingback: Oracle Business Rules – { Desarrollo JAVA }