The Business Rule component in SOA Suite 11g is used to implement business logic. The logic is extracted from BPM or BPEL process definitions for from Java or other program code, exposed to be invoked from those contexts and defined in a way that makes it accessible to the business. That at least is the theory. Business Rules capture logic that ranges from the very simple – simple IF/THEN rules for allowing or disallowing based on one input parameter – to very complex, performing extensive ns and calculations, for example using the Decision Table. The Decision Table is a smart, compact way of clustering many IF/THEN rules together, as will be demonstrated in this article.
This article demonstrates how the decision table can be put to good use to implement the business logic behind the classical game of Rock, Paper and Scissors. (for a refresher on that game, see: http://en.wikipedia.org/wiki/Rock-paper-scissors).
Before even opening JDeveloper for working on the Business Rule, let’s briefly discuss the game itself: a simple game, played with two players. At the same time, they raise their hand, indicating either a rock, a pair of scissors or a piece of paper. The rules of the game can be expressed using simple IF/THEN rules:
Although we will not be following exactly this matrix , the idea of converting a set of IF/THEN rules to a matrix for enhanced readability is nicely illustrated here.
Preparing the SOA application for a game of Rock, Paper and Scissors
Open JDeveloper. Create new SOA Application RockPaperScissors with a project of the same name, based on the template for an Empty Composite.
Create a new XSD document, called RockPaperScissors.xsd. It should be composed as follows:
The RequestType describes the input that the Business Rule will deal with. It consists of two entries, here labeled with throwOne and throwTwo. Both contain exactly one value from the enumerated list of values rockpaperScisssorsType: rock | paper| scissors. The Response type contains a single element outcome that has one of three values: oneWins | twoWins | tie.
Create and configure the Business Rule that play Rock, Paper and Scissors
Create new Business Rule component:
Set the input and output for the rule based on the Request and Response type defined in the XSD document.
Double click the Business Rule component to edit the rule definition.
o Create XML Facts – go to the Facts tab, click on the green plus icon, select the complex and simple types from the XSD document to have XML Facts created from them
o Verify/Create Bucketsets as illustrated below
o Configure the Decision Function
o Edit default rule set; create a Decision Table
o Create an action: Assert New RockPaperScissorsResponseType. The outcome property is parametrized (always to be determined for the rule), make sure the checkbox Always Selected is checked (to make sure this action is executed for every rule that is triggered) and press the ok button
Add conditions for RockPaperScissorsRequestType.throwOne and RockPaperScissorsRequestType.throwTwo. Both conditions are associated with bucketset RockPaperScissorsType.
o Create a rule with ROCK for its first condition cell and PAPER for the second. Set the outcome property to RockPaperScissorsOutcomeType.TWO_WINS – in the action cell for this rule.
o Create a second rule: with ROCK for its first condition cell and SCISSORS for the second. Set the outcome property to RockPaperScissorsOutcomeType.ONE_WINS – in the action cell for this rule.
o You could now try to use the Gap Analysis feature to get some help in creating the missing rules (PAPER vs. ROCK and SCISSORS and SCISSORS vs. PAPER and ROCK).
Use Split Cell to create separate rules for PAPER and SCISSORS.
Use Split Cell on the cell for Condition 2 in Rule 3, creating new rules for all possible values that Condition 2 may have – or every bucket in bucketset RockPaperScissorsType. Remove rules R4 and R6 that match paper with itself and with null. Continue to create similar rules for SCISSORS in Condition 1.
Specify the correct actions for all these rules.
o Finally add a rule to declare a tie. This rule has a ‘Do not care’ setting for both conditions (that will make it fire for every input). However, through the correct Conflict Resolution setting, we ensure that is only fired when none of the other rules fire. Click on the cell indicating the Conflicts and select Overridden By in each of the cases – indicating that this fall back rule is overridden by every other rule that may fire. Only when none of them is activated, this one will step in and call it a draw.
- Create a function to test the Decision Function based on the Decision Table.
Test the function, by clicking on the Test icon with the function selected. The test results appear in the popup window:
Integrating the Business Rule in the Composite Application
- Add a Mediator to the Composite; call it ExposeRockPaperScissors . This Mediator will expose the RockPaperScissors decision service with a friendly interface.
Select the option to specify the interface later.
Double click on the new mediator to open the mplan-editor.
Click on the green plus icon behind the WSDL URL prompt. This brings up the define Service dialog in which the WSDL can be specified – largely based on XSD definitions.
Select the rockPaperScissorsRequest element as the basis for the Request message format and rockPaperScissorsResponse as the Reply format. Specify callARoundOfRockPaperScissors as the operation name and gameRulings_ptt for the portType.
Create a routing rule in the new Mediator, that invokes target service RockPaperScissorsRuling/RockPaperScissorsRuling_RockPaperScissorsRuling_DecisionService_1.
The next step is mapping the incoming friendly formatted message with a round of Rock, Paper and Scissors to the distinctly less friendly input format desired by the Decision Service component. Especially the fact that the inputParameter element is of XSD type anyType makes life a trifle harder as we cannot use the graphical mapping editor and have to write ‘raw’ XSLT.
The only important value set on the elements shown in the mapping is RockPaperScissorsRuling_RockPaperScissorsRuling_DecisionService_1 for the name attribute on element callFunctionStateless. The data on bpelInstance is not relevant in our case, as the decision service is invoked by a Mediator. Only take care to provide an integer value for instanceId.
The creation of the contents of parameterList has to be coded in XSLT:
The mapping for the reply is somewhat similar – again the value we need to extract to set the outcome, is in an anyType element. We need to hand-code XSLT to get it out of there.
This completes the configuration of the Mediator.
Drag the service exposed by Mediator ExposeRockPaperScissors to the Service lane in the composite.
Drop the service in order to publish the service at the composite level
Live action for Rock, Paper and Scissors
- Deploy the SOA composite application
Click on the option deploy in the context menu for the project and follow the deploy steps.
- Test the Decision Service from the FMW Control
Open The Fusion Middleware Control, locate composite application RockPaperScissors [1.0], and open its dashboard. Click on the Test WebService button. The test page appears. Enter values for the input parameters throwOne and throwTwo.
For rock vs paper we get the ruling that twoWins (or paper beat rock).
Click on Launch Message Flow Trace to inspect the details of what happened:
Download JDeveloper 11g SOA Composite application for Rock Paper Scissors: RockPaperScissors.