20. Order Management Process
This is a Process Management lab in which will implement an Order Management process. The process will use BPMN2 constructs like Swimlanes, User Tasks, Gateways, combined with decision-based routing based on a DMN Model (Decision Model & Notation). It also introduces more dynamic concepts of the Red Hat Process Automation Manager process engine, like dynamic assignments of tasks based on process instance data.
20.1 Goals
- Create an Order Management project in Red Hat Process Automation Manager.
- Define and create the process' domain model using the platform’s Data Modeller.
- Implement an order management process in the process designer
- Implement decision logic in a DMN model.
- Create forms with the platform’s Form Modeller.
- Deploy the project to the platform’s Execution Server.
- Execute the end-to-end process.
20.2 Pre-reqs
- Successful completion of the Environment Setup Lab or
- An existing, accessible, DM/PAM 7.3+ environment.
20.3 Problem Statement
In this lab we will create an Order Management process that manages the process of ordering a new phone or laptop.
- Start the process by providing the order information.
- The supplier sends an offer stating the expected delivery date and its best offer.
- Depending on the urgency of the urgency and the price, the order can be auto-approved by a DMN decision.
- If the order is not auto-approved, the manager needs to complete an approval step.
21. Create a Project
To define and deploy a business process, we first need to create a new project in which we can store the BPMN2 model, our domain model and the forms required for user interaction. To create a new project:
- Navigate to Business Central
- Login to the platform with the provided username and password.
-
Click on Design to navigate to the Design perspective.
-
In the Design perspective, create a new project. If your space is empty, this can be done by clicking on the blue Add Project button in the center of the page. If you already have projects in your space, you can click on the blue Add Project icon at the top right of the page.
- Give the project the name
order-management
, and the description "Order Management".
With the project created, we can now start building our solution.
22. Solution
22.1 The Domain Model
The business process will collect and carry data through the execution of the process. This data is stored in a data model or domain model. In this lab, we collect two types of data:
OrderInfo
: contains information about the order, like the item and the price.SupplierInfo
: contains information about the supplier, like the name and the expected delivery date.
Next:
-
In your project, click on the Add Asset button in the middle of the screen.
-
In the drop-down menu in the upper-left corner, select
Model
. Click on the Data Object tile. -
Give the Data Object the name
OrderInfo
. Leave the package set to default. -
Add the following fields to the
OrderInfo
data object:Identifier Label Type item item name String urgency urgency String targetPrice target price double managerApproval approved Boolean -
When you’ve added the fields, save the data object by clicking on the Save button in the top menu.
- Use the _breadcrumb` navigator at the top-left of the screen to navigate back to our
order-management
project. - Click on the blue Add Asset button in the top-right corner and create a new Data Object
-
Give it the name
SupplierInfo
-
Give the
SupplierInfo
object the following fields:Identifier Label Type offer best offer double deliveryDate delivery date Date user user String -
We’re done creating our data model.
We can now start with our process design.
22.2 Process Design
With the domain model defined, we can now sketch out the main flow of the process, the actors, the user task nodes and the required automation decisions.
-
Create a new
Business Process
asset. Name itOrderManagement
. -
When the process designer opens, scroll down in the property panel on the right side of the screen, until you see the section Process Data.
-
Expand the Process Data section and add the following 3 Process Variables by clicking on the + sign.
Name |
Data Type |
orderInfo |
OrderInfo |
supplierInfo |
SupplierInfo |
approved |
Boolean |
- In the palette on the left-side of the editor, select the
Lane
component:
- Create the following 3 swimlanes: Supplier , Purchase , Manager
- Create the Start Event node in the
Purchase
swimlane. - Create the
Prepare Offer
User Task node in theSupplier
swimlane and connect it to the Start Event node. Set the following properties on the node via the properties panel on the right side of the screen:- Task Name:
PrepareOffer
- Subject:
Prepare Offer for #{orderInfo.item}
- Actors:
#{supplierInfo.user}
- Assignments:
- Task Name:
Name |
Data Type |
Source |
orderInfo |
OrderInfo |
orderInfo |
supplierInfo |
SupplierInfo |
supplierInfo |
Name |
Data Type |
Target |
supplierInfo |
Supplier Info |
supplierInfo |
- Create the
Auto Approve Order
Business Rule node in thePurchase
swimlane and connect it to thePrepare Offer
node. Set the following properties: - Rule language:
DMN
- Assigments:
Name |
Data Type |
Source |
Order Information |
OrderInfo |
orderInfo |
Supplier Information |
SupplierInfo |
supplierInfo |
Name |
Data Type |
Target |
Approve |
Boolean |
approved |
After we’ve created our DMN Decision Model, we will revisit the configuration of this node to reference this DMN model via it’s name
and namespace
properties.
- Create an X-OR Gateway/Exclusive Gateway in the
Manager
swimlane, below theAuto Approve Order
node and connect it to that node.
- Create the
Approve
User Task in theManager
swimlane and connect it to the X-OR gateway. Set the following properties:- Task Name:
Approve
- Subject:
Approve Order of #{orderInfo.item}
- group:
rest-all
- Assignments:
- Task Name:
Name |
Data Type |
Source |
orderInfo |
OrderInfo |
orderInfo |
supplierInfo |
SupplierInfo |
supplierInfo |
Name |
Data Type |
Target |
orderInfo |
OrderInfo |
orderInfo |
- Create an X-OR Gateway/Exclusive Gateway in the
Manager
swimlane, after theApprove
node and connect it to that node.
- Create another X-OR Gateway/Exclusive Gateway under the
Manager
swimlane (so outside of the swimlane) and connect it to the two other X-OR Gateways/Exclusive Gateways as shown in image below:
- Create the
Place Order in ERP
Script Task under theManager
swimlane (so outside of the swimlanes) and connect it to the X-OR Gateway we created earlier. Set the following script in the node’s properties properties:
- Create an End Event node under the
Manager
swimlane (so outside of the swimlanes) and connect it to thePlace Order in ERP
node. Name itApproved
.
- Create an End Event node in the
Purchase
swimlane and connect it to the X-OR Gateway. Name itRejected
.
- On the Sequence Flow from the X/OR Gateway before the
Approve
node that is connnected ot the other X/OR Gateway, set the following condition, which tells the process engine that this path should be taken when the order is not automatically approved:- Process Variable:
approved
- Condition:
Is true
- Process Variable:
- On the Gateway before the
Approve node
, set the Default Route property toApprove
.
- On the Sequence Flow from the X/OR Gateway after the
Approve
task, which is connected to the X/OR Gateway before thePlace Order in ERP
task, set the following condition:- Process Variable:
orderInfo.managerApproval
- Condition:
Is true
- Process Variable:
- On the X/OR Gateway after the
Approval
node , set the Default Route toRejected
.
- Save the process definition.
With the overall layout of the process definition complete, the routing logic implemented, and the I/O assignments defined, we can now implement the business rules of our automated approval decision.
22.3 Business Rules and Decisions
Our Order Management process contains a Business Rule Task, but we have not yet defined the Decision Model that will be used in the task. In this paragraph we will implement the automatic approval rules in the form of a DMN model.
-
In the main project page, the so called library view, click on the Add Asset button.
-
In the next screen, set the drop-down filter to Decision. Select the DMN asset. Give it the name
order-approval
.
- In the DMN editor, open the property-panel on the right-side of the screen and set the
Namespace property to:
http://www.redhat.com/dmn/demo/order-management-dmn
. First we need to import our data-model, so we can use it in our DMN decisions. In the DMN editor, click on the Data Types tab and click on the Import Data Object button at the right-hand side of the screen:
- Select both the
OrderInfo
andSupplierInfo
objects and click on the Import button:
With the 2 datatypes imported, we need to create a third type that will hold the possible values for the urgency
field of our Order Information
. Click on the blue Add button in the top-right corner.
- In the entry that opens, give the data type the Name
Urgency
and the Typestring
:
- Click on the Add Constraints button, select
Enumeration
as the constraint type, and set the values lowand
high`.
- Click on the blue checkmark button to save the type.
- Navigate back to the model via the Model tab. Add 2
Input
nodes to the model and name themOrder Information
andSupplier Information
- Select the
Order Information
node. Open the properties panel on the right-hand side of the screen, and set the Data type toOrderInfo
.
-
Do the same for the
Supplier Information
node. Set the Data type toSupplierInfo
. Create a newBusiness Knowledge Model
node, name itPrice Tolerance
. -
Click on the node, and click on the Edit button to start editting the node:
- Click in the Edit parameters. An editor will open. Click on Add parameter. Name the parameter
order information
and set the type toOrderInfo
.
- Right click in the empty white cell under the parameter definitions and select Clear. The text Select expression will appear in the cell. Click on the cell and select
Decision Table
.
- Add an input clause to the decision table. The name of the input clause is
order information.urgency
, which references theurgency
attribute of theorder information
parameter. Set the type toUrgency
, which references theUrgency
enumeration we created earlier.
- Set the output clause data type to
number
. Leave the name empty.
- Click on the
Price Tolerance
cell (top cell of the table), and set the data type tonumber
.
- Implement the rest of the decision table as shown below. And save the DMN model.
- Navigate back to the model by clicking on the Back to order-approval link at the top-left of the editor. Create a new Decision Node and name it
Approve
. Connect the 2 input nodes and outPrice Tolerance
busines knowledge model node to the new decision node.
- Select the
Approve
decision node and click on the edit button.
-
Click on _Select Expression, and set the logic type to
Literal Expression
. -
Enter the following expression:
Supplier Information.offer < Price Tolerance(Order Information) * Order Information.targetPrice
- Click on the
Approve
cell (top cell of the table), and set the data type toboolean
.
- Navigate back to the model by clicking on the Back to order-approval link at the top-left of the editor.
- Our DMN model is now complete. Make sure to save your model.
- With our DMN model implemented, we can now revisit our Business Rules Task in our BPMN2 model. Open the
order-management
process definition and click on theAuto Approval Order
node. - Open the node’s properties in the property-panel on the right side of the editor, open the
Implementation/Execution section and set:
- Namespace:
http://www.redhat.com/dmn/lab/order-approval-dmn
- Name:
order-approval
- Namespace:
- In the same properties panel, expand the Data Assignments section and open the Assignments editor
- Implement the following data input and output assignments.
- Our BPMN model is now complete. Make sure to save the model.
Now, we should create implement our forms.
22.4 Forms
In this section we are going to create the process start and user-task forms. We could simply generate these forms with the click of a button, which gives us some standard forms based on the process and task data.
In this lab however, we will be creating these forms using the Form Modeler tool. This allows us to design these forms to our specific needs.
Let’s start with the process start form. We want to create the following form:
-
In the project’s library view, click on Add Asset. Filter on Form, click on the Form tile. Enter the details as shown in the screenshot below:
-
On this form we want to specify the initial order. We therefore require fields from the
orderInfo
andsupplierInfo
process variable. When we expand theModel Fields
section, we can see our 2 process variables (orderInfo
andsupplierInfo
). These are both complex objects. To work with complex objects (as opposed to simple types like integers and booleans), we require a data-form for that specific object. We therefore first need to create a data-form for ourOrderInfo
andSupplierInfo
objects. -
Go back to the project’s library view, click again on Add Asset and create a new form. Use the following details:
- Using the Form Modeler constructs, create the following form:
-
To create this form, drag both the
item
,urgency
andtargetPrice
onto the canvas and configure them as follows. -
List Box:
- Radio Group:
- Decimal Box:
- Save the form and create another new form for our
supplierInfo
. Use the following details.
.
- Using the Form Modeler constructs, create the following form:
- To create this form, drag the
user
field onto the canvas and configure it as follows.
- Save the form and open the
OrderManagement
form (the first form we created). - Drag the
orderInfo
process variable onto the canvas. In the pop-up form, set theOrderManagement-Order
form we just created as the Nested Form:
11. Drag the supplierInfo
process variable ontoo the canvas. In the pop-up form, set the OrderManagement-SupplierInfo
form we just created as the Nested Form:
Next, we will create the form for the Prepare Offer
User Task.
-
Create a new form. Provide the following details:
2. Our aim is to create a form that looks as such:
3. As with the process start form, this user-task form operates on 2 variables, `orderInfo` and `supplierInfo`. And, as with the process start form, we need to create a data-object form for each of these variables. Technically, data-object forms for a certain data-object can be reused in multiple task-forms. However, creating a data-object form per task-form allows us to design these data-object forms aimed for that specific task.
PrepareOffer-OrderInfo
PrepareOffer-SupplierInfo
Finally, we need to create the task form for the Approve
task.
-
Create a new form. Provide the following details.
.
-
Our aim is create a form that looks like this:
- As with the other forms, this user-task form operates on 2 variables,
orderInfo
,supplierInfo
. And, as with the other forms, we need to create a data-object form for each of these variables.
- As with the other forms, this user-task form operates on 2 variables,
Approve-SupplierInfo
Approve-OrderInfo
Don’t forget to save all your forms!!!
The implementation of our process is complete. It’s now time to deploy and test our application.
23. Deploying the Process Service
With our Order Management project’s process, decisions and forms completed, we can now package our project in a Deployment Unit (KJAR) and deploy it on the Execution Server. To do this:
-
Go back to our project’s Library View (for example by clicking on the
Order Management
link in the breadcrumb navigation in the upper-left of the screen). -
Click on the Deploy button in the upper-right corner of the screen. This will package our project in a Deployment Unit (KJAR) and deploy it onto the Execution Server (KIE-Server).
-
Go to the Execution Servers perspective by clicking on "Menu → Deploy → Execution Servers". You will see the Deployment Unit deployed on the Execution Server.
24. Execute the process
In this section, you will execute the process deployed on the Process Execution Server via the Business Central workbench.
-
Navigate to Menu → Manage → Process Definitions. If everything is correct, the
order-management
process will be listed. Click on the kebab icon of theorder-management
process and click on Start. -
In the form that opens, pick the Huawei P10 Phone as the item and set the urgency to low. Set the target price to 700 and set the supplier name to the name of your own Business Central user (e.g.
pamAmdmin
). Click on Submit.3. In the process instance details screen that opens, click on the Diagram tab to open the process instance diagram, which shows the current state of the process.
- The process is in a wait state at the
Prepare Offer
task. Navigateto Menu → Track Task Inbox**. Click on thePrepare Offer
task to open its task window. - Click on the Start button to start working on the task. Because the task has been assigned to a single user (via #{supplierInfo.user}), you don’t have to first claim the task.
-
Select a random delivery date. Set the best offer to 900. Click on Complete.
-
The process will continue to the
Auto Approve Order
decision node. Because of the target prices set, and the offered price, the decision will evaluale tofalse
. Hence, the process will continue to theApprove
task.
- Go back to the Task Inbox and open the
Approve
task. Click on Claim and on Start. In this form we can approve or disapprove the order via the approved checkbox, and specify a rejection reason if we reject the order. Approve the task by checking the approved checkbox and clicking on Complete:
-
Go back to the process instance view and observe that the process instance is gone.
-
Enable the Completed checkbox in the State filter on the left-hand-side of the screen. Observe that we can see our process instance in the list.
-
Open the process instance, open it’s Diagram tab. Observe that the order has been accepted:
Run a couple more process instances with different values to test, for example, the functionality of the Automated Approval Rules
.
25. Correcting problems and errors
During process instance execution, a lot of things can go wrong. Users might fill in incorrect data, remote services are not available, etc. In an ideal world, the process definition takes a lot of these possible problems into account in its design. E.g. the process definition might contain exception handling logic via boundary catching error events and retry-loops. However, there are situations in which an operator or administrator would like to manually change the process to another statem for example, restart an already completed User Task. In the latest version of Red Hat Process Automation Manager this is now possible via the Process Instance interface in Business Central.
-
Start a new process instance of our Order Management process.
-
Complete the
Prepare Offer
task in such a way that the order is not automatically approved and the process will hit theApprove
User Task wait state. -
Go to the Process Instances view and select the process instance. Navigate to the Diagram tab. Observe that the process is waiting in the
Approve
User Task. -
Click on the
Prepare Offer
node to select it. In the Node Actions panel on the left-hand-side of the screen, verify that thePrepare Offer
node is selected and click on Trigger. Observe that thePrepare Offer
User Task has been activated. -
Although we have re-activated the
Prepare Offer
node, we have not yet de-activated theApprove
task. Click on the activeApprove
task and expand the Node Instances section in the Node Actions panel. Click on the kebab icon of the activeApprove
instance and click on Cancel:
6. Open the Task Inbox. Observe that the Approve
User Task is gone and that we have a new Prepare Offer
task.
- Open the
Prepare Offer
task, set the price to a price which will trigger the rules to automatically approve the order, and complete the task. . Go to the process instances view and observe that the process instance has been completed. . Enable the Completed filter in the State filter panel on the left-hand-side of the screen. Open the completed process instance and open its Diagram tab.
26. Execute the process via APIs
The Execution Server provides a rich RESTful API that allows user to interact with the process engine and deployed processes via a REST. This powerful feature allows users to create modern user interface and applications in their technology of choice (e.g. Entando DXP, ReactJS/Redux, AngularJS, etc.) and integrate these applications with the process engine to create modern, process driven, enterprise applications.
The Swagger interface provides the description and documentation of the Execution Server’s RESTful API. At the same time, it allows the APIs to be called from the UI. This enables developers and users to quickly test a, in this case, a deployed business process.
-
Navigate to the KIE Server Swagger Page
-
Locate the Process instances section. The Process Instances API provides a vast array of operations to interact with the process engine.
-
Locate the POST operation for the resource
/server/containers/{containerId}/processes/{processId}/instances
. This is the RESTful operation with which we can start a new process instance. Expand the operation: -
Click on the Try it out button.
-
Set the containerId to
order-management
(in this case we use the alias of the container). -
Set the processId to
order-management.OrderManagement
. -
Set Parameter content type to
application/json
.
-
-
Set the Response content type to
application/json
. -
Set the body to:
json { "orderInfo" : { "com.myspace.order\_management.OrderInfo" : { "item" : "Huawei P10", "urgency" : "low", "price" : 0.0, "targetPrice": "700.0" } }, "supplierInfo" : { "com.myspace.order\_management.SupplierInfo" : { "user" : "pamAdmin" } } }
-
Click on the Execute button.
-
If requested, provide the username and password of your Business Central and KIE-Server user (in this example we have been using u:
pamAdmin
, p:redhatpam1!
). -
Inspect the response. Note that the operation returns the process instance id of the started process.
-
Go back to the Business Central workbench. Go the process instances view and inspect the process instance we have just started.
The RESTful API provides many more operations. Let’s use the API to fetch our Task List and complete the Request Offer
task.
-
In the Swagger API, navigate to the Process queries section.
-
Find the GET operation for the resource
/server/queries/tasks/instances/pot-owners
. Expand the operation and click on the Try it out button. -
Make sure the *Response content type is set to
application/json
. Leave all the other fields set to their default values. -
Click on the Execute button. This will return all the tasks for our user (in the case of this example this is the
pamAdmin
user).
-
We can see the
Prepare Offer
task that is available in our inbox. Let’s complete this task. -
Go to the Task Instances section in the Swagger interface and locate the PUT operation of the
/server/containers/{containerId}/tasks/{taskInstanceId}/states/completed
resource. This is the operation with which we can complete a task.- Set the containerId to
order-management
.
- Set the containerId to
-
Set the taskInstanceId to the id of the task instance you want to complete. The task instance id an be found in the list of task instances we got back from our previous REST operation.
-
Set auto-progress to
true
. This controls the auto progression of the taks through the various states of the task lifecycle (i.e. claimed, started, etc.)- Set the Parameter content type to
application/json
.
- Set the Parameter content type to
-
Set the Response content type to
application/json
.- Set the body to:
json { "supplierInfo": { "com.myspace.order\_management.SupplierInfo" : { "user": "pamAdmin", "offer": "900", "deliveryDate":"2020-03-11T12:00:00.000Z" } } }
- Click on the Execute button. If you’ve entered everything correctly, the task will be completed and the process will move to the next wait state, the
Prepare Offer
task. . Go back to the Business Central workbench. Go to the process instances view. Select the process instance of the task you’ve just completed. Observe that thePrepare Offer
task has been completed and that the process is now waiting on theApprove
User Task.
The rest of the tasks can be completed in the same way via the API.
27. Using the KIE-Server Client
Red Hat Process Automation Manager provides a KIE-Server Client API that allows the user to interact with the KIE-Server from a Java client using a higher level API. It abstracts the data marshalling and unmarshalling and the creation and execution of the RESTful commands from the developer, allowing him/her to focus on developing business logic.
In this section we will create a simple Java client for our Order Management process.
-
Create a new Maven Java JAR project in your favourite IDE (e.g. IntelliJ, Eclipse, Visual Studio Code).
-
Add the following dependency to your project:
<dependency>
<groupid>org.kie.server</groupid>
<artifactId>kie-server-client</artifactId>
<version>7.30.0.Final</version>
<scope>compile</scope>
</dependency>
-
Create a Java package in your
src/main/java
folder with the namecom.myspace.order_management
. -
Download the
OrderInfo.java
file from this location and add it to the package you’ve just created. -
Download the SupplierInfo.java file from this location and add it to the package.
-
Create a new Java class called
Main
. Add apublic static void main(String[] args)
method to your main class. -
Before we implement our method, we first define a number of constants that we will need when implementing our method (note that the values of your constants can be different depending on your environment, model namespace, etc.):
private static final String KIE_SERVER_URL = "http://localhost:8080/kie-server/services/rest/server";
private static final String CONTAINER_ID = "order-management";
private static final String USERNAME = "pamAdmin";
private static final String PASSWORD = "redhatpam1!";
private static final String PROCESS_ID = "order-management.OrderManagement";
- KIE-Server client API classes can mostly be retrieved from the
KieServicesFactory
class. We first need to create aKieServicesConfiguration
instance that will hold our credentials and defines how we want our client to communicate with the server:
KieServicesConfiguration kieServicesConfig = KieServicesFactory.newRestConfiguration(KIE_SERVER_URL, new EnteredCredentialsProvider(USERNAME, PASSWORD));
- To allow the KIE-Server Client’s marshaller to marshall and unmarshall instances of our domain model, we need to add our domain model classes to the
KieServicesConfiguration
.
Set<Class<?>> extraClasses = new HashSet<>();
extraClasses.add(OrderInfo.class);
extraClasses.add(SupplierInfo.class);
kieServicesConfig.addExtraClasses(extraClasses);
-
Next, we create the
KieServicesClient
: -
From this client we retrieve our
ProcessServicesClient
: -
We now create a
Map
which we will use to pass the process input variables. We create a newOrderInfo
instance andSupplierInfo
instance and put them in theMap
.Map<String, Object>inputData = new HashMap<>(); OrderInfo orderInfo = new OrderInfo(); orderInfo.setItem("Huawei P10"); orderInfo.setUrgency("low"); inputData.put("orderInfo", orderInfo); SupplierInfo supplierInfo = new SupplierInfo(); supplierInfo.setUser("pamAdmin"); inputData.put("supplierInfo", supplierInfo);
-
We can now start a new process instance via the
ProcessServicesClient
.
- Finally, we can print the process instance id to
System.out
.
System.out.println("New *Order Management* process instance started with instance-id: " + processInstanceId);
- Compile your project and run it. Observe the output in the console, which should say: New Order Management process instance started with instance-id
The complete project can be found here: https://github.com/DuncanDoyle/order-management-rhpam-lab-client
The KIE-Server Client provides more services to interact with the Execution Server:
-
UserTaskServicesClient
: provides functionality to interact with the UserTask services, for example to claim, start and complete a User Task. -
CaseServicesClient
: provides functionality to interact with the Case Management features of the Execution Server. -
ProcessAdminServicesClient
: provides the administration API for processes. -
etc.
We leave as an exercise to the reader to try to complete a User Task, of the process instance we’ve just created, using the UserTaskServicesClient
.