Go to Code
See the code in github. You can downlaod and run the project.
Use-Case
Ordering use case is focused on demonstrating the ordering process through Web Based UI, Notifications and Camunda workflow. The ordering process models have several human review steps where a approval or rejection can happen and systems integration steps where communication with API’s happens.
Below is a collaboration diagram illistrating how the different particpants interact with each other. Notice this is not a technical diagram and is soley for understanding. Camunda Cawemo was used to model this BPMN diagram. The technical models that are deployed are in ./src/main/resources/processes
The above process use case is initiated when product inventory becomes available. The Inventory Notification Process is activated by a scheduled job BPMN Timer event, which is fired off every day. The notification process checks the inventory levels and determines if there are eligible employees for the existing inventory.
The eligibility is determined by information queried from the entitlement system as well as a DMN Business Rule table. Once eligibility is established then an email is sent to the eligible employees with links to the Ordering application.
An order is started in the custom ordering UI. The order can be saved at any point in the order cache/db. When the order is complete it is sent for approval. The Order Approval Process is started and waits for a manager to approve the order. Once approved the the Local inventory is updated and notification of approval is sent to the employee.
The Stock Replenishment Process is also initiated by a BPMN start timer event, once a day. It checks the product inventory levels and notifies the inventory manager when inventory is low and reorders inventory upon approval the sends a request to the Inventory Provider to create more inventory. Which subsequently updates the local inventory. Which of course potentially starts the entire process over.
Running the use-case
Option 1. Use spring-boot at the command line
mvn spring-boot:run -Dspring.profiles.active=ordering,email,gui,cors
Option 2. Use docker-compose
This should allow you to simple run the in a self contained manner. You must have docker installed on the machine.
docker-compose up
Option 3. Use Kuberneties
This is still in progress.
Using Profiles
Profiles can be specified at the command line when the application starts. The notation is as follows.
-Dspring.profiles.active=ordering,gui,email,cors
Or you can use the application.properties file to specify the profile.
spring.profiles.active: ordering,gui,email,cors
Initalizing Data
Important
|
for the Ordering use-case to run properly some data must be initialized. |
-
Contact(s) - must be initialized
-
Stock Items - must be initialized
Both can be initialized by running the appropriate Postman scripts
-
Contact Object - run POST stock-items script a few times
-
Stock Items - run POST contact script once
The postman collection is located in the postman directory. Import the collection into Postman and run the appropriate script.
TODO: Auto-initalize upon initialization
See it running
Visit http://<server>:<port>/app.html
to access the React app.
Steps to run the Demo
1) Initialize the data with Postman
2) Open Cockpit Observe the Approve PM Order workflow
3) Run the Order in React UI
4) Open Cockpit Observe the Approve PM Order workflow again
5) Open the MailSluper UI http://localhost:9090/# Click the links in the email to approve the task
6) Open Cockpit Observe the Approve PM Order workflow and view the history
Using Enterprise Camunda
Important
|
Using Camunda Enterprise - it’s necessary to request a Camunda Enterprise License. |
Update the settings.xml file in the project home with the credentials that you get from Camunda. This will allow you to pull the enterprise artifacts from our nexus repository.
Note
|
You may need to configure a proxy to reach our repository. See the example in the settings.xml. |
Testing with Postman
Use the postman collections in the postman
folder.
With post-man you can move through the processes simulating REST requests to the app.
-
starting the processes
-
completing user tasks
-
correlating messages
-
loading test data
Architecture
The diagram above illustrates the interactions and logical components of the app. Note the app is all packed together into one artifact for easier development and PoC ing. But each component could be easily it’s own deployable artifact.
Note the Custom UI is not depicted. For all intents an purposes it is a completely seperate app and is not depended on the workflow. The interaction between the Ordering UI and the workflow is asynchronous. Since the Notification workflow simple directs the user to the Order UI which then allows a user to complete the order without interacting with the workflow.
Once an order is complete the Approval Workflow is started but is not dependent on the order UI in any way. The approval workflow interacts with users and the inventory API.
Purple lines signify point-to-point synchronous HTTP/REST interactions with the workflow and other components.
This application utilizes mostly synchronous blocking API calls to the JAVA and REST API’s. Though as explained prevoiusly there are some subtle but important asynchronous and choreographed interactions.
UI Integration
ReactJS Integration
The Maven frontend-maven-plugin configured in pom.xml is used to build the ReactJS app. The plugin creates a bundle.js file which ends up in src/main/resources/static/built/bundle.js
. The static directory makes static resources such as JS and HTML available to the java app.
The Java application boot-straps the ReactJS App through Thymeleaf a java/spring frontend framework. The templates directory src/main/resources/templates/app.html
has a HTML file app.html which calls the React app through a <script />
tag loading the HTML into the react div <div id="react"></div>
Thymeleaf ties the Java frontend together using a Spring controller. src/main/java/com/camunda/poc/starter/use-case/service.request/controller/ui/UIServicerequestController.java
. Mapping the app context to /sr and calling the app.html.
The React Components are organized under the src\main\js\reactjs
folder into a use-case folder then subdivided by component.
Webpack and package.json define the structure and dependencies for the React App that allow and build the app into the bundle.js which is later placed in the static directory as explained previously. Allowing our frontend to load the plain EcmaScript.
Foundation CSS is used for styling https://get.foundation/sites/docs/index.html
Note
|
The react app is built in this manner, wrapped in spring-boot app, for convenience and consistency. This makes dev-ops, demoing and getting started easier and may not be appropriate for other technology stacks and dev-ops scenarios. |
Handling Business Data and UI Integration
Tip
|
see the pattern described in the Camunda Best Practices https://camunda.com/best-practices/handling-data-in-processes/ and https://camunda.com/best-practices/enhancing-tasklists-with-business-data/ |
Often and for numerous reasons we need to consolidate data from different sources. In this app I use JPA and Spring REST with some of springs features to build a custom API. Primarily for making integration with the UI easier. Here are few reasons why I take this approach.
-
Reduce queries the UI does to the backend
-
Make it easier to build UI components
-
Create abstraction layer that can be used to integrate other technical and business requirements like reporting and security.
-
Have a source of truth for process meta-data
Note
|
Also keep in mind I want to keep every-thing self contained for PoC purposes. Think in logical terms and that these components could be another technology or several other technologies depending on the specific needs. |
Camunda REST API
Camunda has a powerful rest API. This code repository has many examples of interacting with the CAMUNDA REST API from the custom UI and using postman. See the postman
folder in the project home.
Import the postman collection and take a look at the queries to start the workflow and correlate messages.
see more CAMUNDA REST API
JPA Spring Data Repositories
A separate API and logically separate data-store is used to query order data.
We can guarantee the data is updated in the data store with the workflow. See the section above on the JavaDelegates that implement the publishing functionality.
Spring Data JPA is the technology used for business data. Spring Data allows for an easy way to create API’s that are easy for a UI to query. Also an easy way to combine data into a useful form for the UI to consume.
Developing with this PoC Starter Project
Setting up React for Dev
Configure the api endpoint. This is the backend URI for the spring-boot server where the react app gets data
In the .env file in the project home directory change the environment variables to match the spring-boot server context.
Note
|
If running the react app as a standalalone and not on localhost configure the API_HOST and API_POST environment vars as follows inserting your host and port for the spring-boot server. You should only need to do this if you cannot access the spring-boot server on localhost and you plan to run the React App standalone. |
API_HOST=http://127.0.0.1 API_PORT=8080 API_ROOT=api
Important
|
You will need to use the cors profile in this setup and potentially modify the cors config in the spring-boot app. |
Run node and server.js by starting a node server in the home directory of the project. You may need to run npm install
first.
nodemon server.js
Run the web-pack watch in the project home so you can update the bundle as you modify reactjs
webpack -w
Important
|
You may need to install nodejs, nodemon and webpack depending on your environment setup |
Running the server for Dev
Note
|
you need to run the cors profile when using nodemon |
Note
|
you can enable spring-dev-tools to build front and back-end component in dev mode providing faster restarts and live-reload. |
If you are developing only front-end components than you can user docker-compose and follow the React setup above.
cd to the docker-compose directory and run
docker-compose up
For development on the backed use run the spring-boot app on command line
You can also run the app in dev mode by uncommenting spring-dev-tools in pom.xml
Warning
|
spring-dev-tools affects the way Camunda serializes objects into process vars and will cause serialization errors in some cases. So it is commented out in pom.xml by default. |
run the following with the appropriate profiles
mvn spring-boot:run mvn spring-boot:run -Dspring.profiles.active=ordering,gui,email,cors
Mail Slurper
Use mail slurper consuming mail messages sent by the workflow. This is an easy way to test email integrations.
cd into /dev-tools/mailslurper-1.14.1-<dist>
execute ./mailslurper
Mail slurper is configured by editing the /dev-tools/mailslurper-1.14.1-linux/config.json
The app is configured to use mail slurper in the application-mail.properties