In my previous post I’ve shown how to create a composite in the Oracle SOA Suite with a simple decision table in a Business Rule Engine component. For that post I had used quite a simple data model resulting in a small xml/xsd tree. For our project I wanted to repeat the exercise with the real data model, so a larger xml tree defined by multiple imported xsd files. Unfortunately it wasn’t as easy as I hoped for. In this second blog post about the Business Rule Engine I’ll show you about the difficulties I had and how I’ve solved them.
In the simple exercise of my previous blog the decision table contains a rule on the status, where the status field is a direct child element of the input. In the larger data model of our project, the status field is located just one level deeper in the xml tree:
We want to check on the status name, which is a child element of the status element. The problem is that the status element does not unfold, so we can not select it! See picture below:
To solve this problem I first imported the status xml type, which is located in a different xsd, as a XML Fact. Navigate to the xsd and after selecting the xsd file, don’t forget to check the checkbox:
For MDS users: unfortunately you can not uncheck ‘do not import’ option you normally get! The xsd file is copied from your MDS to your local project in the xsd folder inside your composite (which you don’t want):
To solve this, close JDeveloper and edit the BusinessRule source file ‘by hand’ (I’ve used Notepad++) replacing local xsd reference in the “Source” tag by your MDS reference on two locations (object itself and it’s object factory):
Ok, back to the decison table. I was hoping that the status child element of the NominationDetails (input) would now unfold, but it still doesn’t! However we can select the nominationStatusName from the TNominationStatus Fact, we’ve just imported:
But this also doesn’t work as you can read from the Business Rule Validation messages. Apart from messages about the type differences (the first two), which we might be able to solve, the most alarming message is the last one. It says that the fact we’re using (TNominationStatus) is not part of the input!
I’ve been able to solve this by using Functions. I’ve written a function which accepts the status element from the input fact as function parameter and returns a string containing the value of child element nominationName. From the decision table you can only pass a Object or List type, so to be able to reference to the status element in the function, I had to cast the input parameter to the type we’ve imported, TNominationStatus. So the import wasn’t without purpose! Here is the result of the custom getStatus function:
I’ve done the same for the nomination transfer values, which is a list of transfers. I’ve imported the transfer type as XML Fact and written custom function getTotalTransferVolume. This function loops over the transfers and calculates the total transfer volume:
Again back to the decision table. Now we can use you our custom functions in the decision table. Not only as Conditions, but also as parameters in the Action custom functions which are used to create the result:
The validateOK and validateNOK functions are described in my previous post, as well as how to create a Bucketset and define Globals (e.g. MaxTransferAmount used in this example).
I’m curious if somebody knows if there are other ways to solve this problem, so please let me know.