Jarvis Pizzeria: Decision Model in the Delivery Process

To make the delivery of the pizzas to our customer, we need to decide how to deliver the pizzas. In our process we’ve already got the order data, so we know what the order is and where it needs to be delivered, but what is the best way to deliver the pizzas?
We will create a decision model in PCS to help us with this decision. In the delivery process we will call the decision model like a service and use the answer to make the correct decision.


The input for the decision model will be the amount of pizzas and the distance to the customer. Based on these data we will decide to either use a bike, moped or car to do the delivery. A very common decision to make in the Netherlands, since we love our bikes and often deliver pizzas by bike rather than by car.


We start with going to the PCS home. All the way out of the jarvis application and on this home menu we click the create button. Here we see that besides new applications, we can also create a new decision model. This means the decision is not coupled directly to the application with our processes, but it is a stand alone decision model.




When creating the decision model a name, description and workspace is entered after which we can open the model.




The Decision Model uses DMN, Decision Model and Notation. For those using Business Rules on-prem, this is very familiar to Business Rules, but slightly different. Oracle advises that if you can use DMN instead of Oracle Business Rules, you should!
DMN is a standard published by the Object Management Group (OMG). It is a standard approach for describing and modeling repeatable decisions within organizations to ensure that decision models are interchangeable across organizations.
There is also an option to use FEEL, Friendly Enough Expression Language. We will explore this option and how to use this in a separate blog. For now we will create a decision table to make the decision for us.


After creating the model, there is a 5 step guideline how to build it. First we need to add the decision, after which we define the input. Based on the input we can start modelling the decision, this is the step where we model the logic, the heart of our decision model.
Before deploying, running and using our decision model, we can test it internally in the tester. After we are satisfied with the results, we can create a service to invoke the decision model.


We start with creating the decision, by clicking the add icon.


In the creation of the decision we will give it a name, description and some general information. On the right we choose Decision Table.




After the creation of the decision, we see a couple of options to use within the decision.


In this case we want to use the Decision Table.


On the top right hand side of the table, there are options to add columns and rows:


However, we start with describing the output to the DeliveryMethod. When clicking on the yellow bar, we get a popup to configure this. We choose a List of Text values, and add the values Bike, Moped & Car.




This results in the following header of the yellow DeliveryMethod column:


After the output, it is time to configure the input. This happens with the help of the input data on the right hand side. When you click the grey arrow in the black bar, the input section will open.




In here we can add the input data, or even special definitions for the input of our decision. In this case, we just need two numbers as input, the distance to the customer and the amount of pizzas within the order.
So we only need the top section of the input data and use the add icon to start adding the input arguments and use the predefined number type for them.


Clicking the add icon will result in a fold out to the left and we can enter the name as well as the Data Type.




The result will be two number typed input arguments within the input data section.


Now that both the input and the output data are in place, it is time to start working on the logic within the decision table. First we add an extra column using the buttons on the top right. After that we use the first column for the amountOfPizzas variable and the second column for the DistanceToCustomer variable.




Now that the columns are all set up, we can start adding rows in the decision table. The table constantly evaluates the expressions & conditions, which can be helpful as well as annoying when working on the logic.


When you think you are done with the logic, make sure all the warnings are gone, especially the gap analysis can be quite helpful within the decision table.


The assumption we use for creating the logic in the decision model is that both the bike and the moped can carry orders up to 5 pizzas. It is just better to do the nearby deliveries on bike and the ones further away on the moped. If the order gets too big, or too far away, we need to use the car!
This results in the following, valid decision table:


Now that we have the logic of our decision table in place and all validations are passed, it is time to test the logic within our model. We can do this by clicking on the play button in the top right corner.


Clicking the play button will launch the tester of the Decision Model. We can enter input data manually, click on the ‘Start Test’ button and the result will be displayed.




For example, we have entered an amount of 4 pizzas and a distance of 1.




This will result in the output ‘bike’.




To use the DeliveryMethod within our process we need to create a service out of it so we can call it as a stand alone service. Expand the Services bar on the left hand side.


In here we click the ‘add’ icon to create a new Service.


As name we enter ‘getDeliveryMethod’.


This generates the following layout in which we need to define the input & output for the service.


We can Drag & Drop the input data from the input section on the right hand side into the input data section of the service. As output, we need to Drag & Drop the DeliveryMethod in the Decision section to the Output Decisions. The result will look like the picture below.


Now we need to deploy this. For this we click the blue ‘Deploy’ button on the top right.


After the Decision Model is successfully deployed, we can start using it from within our process. In the Delivery Process we select the predefined Decision Model.




Pressing the ‘add’ icon on the right of the Decision Model will bring up a popup to select the DM.




Since we’ve only got one DM yet, it is very easy to find and select. We name it the ‘DeliveryDM’. Since this only has one service, the just created ‘getDeliveryMethod’, this is automatically selected.




Now that we have our DM in place, we need to open the Data Associations. In here we need to map the correct data from the payload as input to the DM as well as the output to Data Objects within the process.


After this, the Decision Model is integrated within the Delivery Process and the output can be used in the gateway to decide how to do the delivery of the pizzas to the customer.


Conclusion
In our previous blog we saw how decisions can be implemented with rules. This feels a lot like the on-premises rules we know from Oracle Business Rules. However, now that we also explored the new Decision Model within PCS, it might be worth to shortly compare the two.
We favor the new Decision Model, because this is a stand-alone component, it feels like a microservice that can be developed, test and deployed as a separate component with its own lifecycle.
The Decision Model applies the standard DMN notation from the Object Management Group and it feels like a newly designed and ‘build from the ground’-feature as where the Business Rules feel more as the on-premises implementation that has been shipped with PCS as well.
This, together with the recommendation of Oracle to use DMN if possible, we feel that we could explicitly express to favor the Decision Model over the rules implementation.


Jarvis Pizzeria: Implementing Rules

When the order comes in, payment needs to be made first before we start preparing the pizza. Our order payment process supports three possible payment options:
  • Creditcard: obviously a commonly accepted payment option
  • Cash: although we are a very tech-savvy company we would also like our old-fashioned customers to be able to pay the pizza with cash money
  • Deferred payment: our most trusted customers can pay their order in a deferred way.  Deferred payment means the customer receives an invoice per email and is asked to pay the order within two weeks.


The payment process is depicted below. The first activity in the process is concerned with determining which payment options are available. What component can we use to insert some facts, start reasoning about those facts and give us an answer based on those facts? Of course...Oracle’s own business rules!



In the picture below the business rules component is magnified. As shown in the picture, we attached a boundary event to the business rules activity. The reason is that in case the business rules fail - for whatever reason - the payment process is cancelled instantly and a business fault is thrown to the parent process.
Let’s take a look into the business rules component itself. Interesting to see is what the implementation screens look like and how they differ from the JDeveloper environment we are all familiar with.
When opening the “Rule”-properties and adding a new Business Rule we get the following popup:




We name our business rule “PaymentRules” and give as input parameters the order amount and the customer Id. We expect our business rules to output the allowed payment options in a string separated format.


As eager developers we want to open our business rules editor immediately, hence we leave the checkbox checked.


When the editor opens we start by creating a decision table.
As “Decision Table 1” is not a very convenient name, we first rename the decision table to “PaymentOptions” and leave all the other fields unchanged.


Because it doesn’t make sense to reason about non-feasible facts, we can add a kind of precondition.


Now we can start adding conditions:




All orders up to and including EUR 10 can be paid both with cash and via creditcard and are - in case we have a trusted customer - applicable to deferred payment. We add the value “10” to the list of values:


Note the checkbox which indicates if the value 10 itself would also be included in the range.
Having added the “10” value, we can now select our range from the dropdown menu:




Note that the condition we actually want - orderAmount <= 10 - cannot be chosen from the dropdown menu. So obviously the “Include Endpoint” checkbox was not the option we needed. Adding the value 10 again but without the “Include Endpoint” option, we get the following dropdown list:
And that’s exactly what we want!


Now we can add another rule for all the order amounts that are greater than EUR 10. We don’t want our pizzeria to store large amounts of cash money for security reasons, hence orders that exceed the EUR 10 amount must be paid with creditcard, or, in case the customer is allowed to, paid in a deferred way.


Having defined the ranges of the order amounts, we can now add a condition that checks the id of the customer.
But before we add a condition, it might be convenient to create a list of values first on which we can base our condition. To do that, we click the following icon in the uppermost toolbar.




This brings us to the following screen.
Here we can add our customers.


Now we can go back to the rules and add a condition.




We select our customerId from the list.
But before clicking “Done” we are going to associate a ValueSet to this condition by pressing the pencil at the bottom of the popup.
We select the “CustomerAliases” set.


Using the “Split table” function in the utilities dropdown, the rules editor will generate a table for us with all the possibilities




Note: we are aware that this is far from an ideal way of setting up your business rule. “For the sake of science” justifies a lot :)


Cool, now it’s time to add the actions.
We choose the “Add action - modify” as we want to modify our output parameter.




We select the PaymentRule.out value and check the “With parameters” checkbox.
This results in the following overview:
The v-signs indicate that the specific rule is active.
Now we can start filling in the possible options.


Conclusion
Although this blog just shows a peek of all the possibilities PCS’ business rules has to offer, the goal of this blog was to wander around, get acquainted with the look and feel and see to what extent the PCS business rules deviate from the on-premises implementation we are all so familiar with. The answer can be short and concise: one who is familiar with implementing business rules in JDeveloper is not going to have any difficulties implementing the same rules in PCS. Maybe the closest thing you can compare the editor with is the rules editor of the SOA composer.

Are there things missing? Well, actually, there is one item that lacks in PCS compared to the on-premises business rules: the option to test your business rules design time. Although we’ve never been happy with the setup of the design time test functionality within JDeveloper (creating design-time tests for business rules is a tedious task and gets JDeveloper to run into a frozen screen every now and then), at least it gave us the option to test before we would deploy the whole application. Does PCS offer us any other possibilities to evaluate facts and make decisions? Let’s find out in our next blog!