tree: e375e1139b834a5224f9ab160f9d545177515119 [path history] [tgz]
  1. docker-compose/
  2. docs/
  3. env/
  4. src/
  5. .gitignore
  6. docker-compose.yml
  7. install.js
  8. package.json
  9. pom.xml
  10. process-compact-architecture.iml
  11. README.md
examples/process-compact-architecture/README.md

Process Compact Architecture Quarkus Example

This example showcases a basic implementation of a Hiring Process that drives a Candidate through different interviews until they get hired. It features simple User Task orchestration including the use of DMN decisions to generate the candidate's offer and timers to skip interviews.

Additionally, this example also demonstrates how to configure the whole environment using the new Compact Architecture, simplifying the communication among services, removing the need of events (Kafka/HTTP) between them. This is achieved using the following Quarkus addons:

  • kogito-addons-quarkus-data-index-postgresql: enables the Kogito Runtime persisting directly into the Data-Index database.
  • kogito-addons-quarkus-jobs: enables collocating the Jobs Service inside the Kogito Runtime.

The “Hiring” Process (BPMN)

The process handles the following Variables:

VariableTypeTagsDescription
candidateDataorg.acme.CandidateDatainputThe candidate data
offerorg.acme.OfferoutputThe generated candidate offer
hr_approvalBooleaninternalDetermines that HR department approves the hiring
it_approvalBooleaninternalDetermines that IT department approves the hiring

The process starts receiving the CandidateData as an input and storing it into the candidateData variable, and if the candidate meets two minimal requirements, the process will continue and reach the Generate base offer, otherwise the candidate application will be denied and the process will complete without sending the offer to the candidate.

The Generate base offer is a Business Rule Task that will use the New Hiring Offer decision defined in the NewHiringOffer.dmn to generate the an Offer based on the candidate experience and skills. The task takes the candidateData as an input and will produce an instance of org.acme.Offer that will be stored in the offer variable.

After the offer has been generated, the process will jump into the HR Interview User Task, where the candidate we'll be interviewed by the HR department. The task takes the candidateData and offer as inputs and as an output will produce the hr_approve boolean and an updated offer.

The HR Interview User Task also has a Boundary Timer Event that will prevent the task to delay and will cancel the task after certain time (for example purpose just 3 minutes). This Boundary Timer Event will schedule a Job in the Jobs Service that when trigger will notify the Kogito Runtime to cancel the task and deny the application.

If HR Interview successfully completed, the process will jump into the IT Interview User Task. Again the candidate we'll have a second interview with the IT department. Again, this task will take the candidateData and offer as inputs but as an output will produce the it_approve boolean.

Once both tasks are completed, if the candidate got the approvals from HR & IT (both hr_interview & hr_interview being true) the process will jump into the Send Offer to Candidate Script Task that will notify the candidate about the offer and the process will end.

NOTE: for simplicity, all the User Tasks in this example are assigned to the jdoe user. Despite showing “Anonymous” in the top-right corner, Apache KIE Management Console will always use the first “potential user” defined by the Process Definition.

The “New Hiring Offer” Decision (DMN)

This example makes use of the New Hiring Offer DMN to generate a base offer for the Candidate. The DMN looks like this:

In this simple DMN we have an Offer Decision, that will generate the candidate offer, which has a requirement of a CandidateData Input Data.

The DMN defines the following data types (tCandidateData & tOffer ) matching the Java POJOs defined in the project (CandidateData.java & Offer.java):

As expected, CandidateData Input and Offer Decision have a tCandidateData type

The Offer Decision uses the following Boxed Expression to generate the tOffer:

The Java models

The Hiring process uses two POJOs to handle the process data, both of them can be found in the org.acme package.

The CandidateData POJO is the input of the process. It represents the person that wants to get the job.

public class CandidateData {

    private String name; // Name of the candidate
    private String lastName; // Last name of the candidate
    private String email; // Email of the candidate
    private Integer experience; // Years of experience
    private List<String> skills; // List of technical skills

    // Constructors, setters, getters...
}

The Offer POJO is the output of the process and represents the job offer that will be sent to the candidate. It will be automatically calculated during the process execution depending on the candidate years of experience & skills.

public class Offer {

    private String category; // Job category based on the candidate experience
    private Integer salary; // Salary based on the candidate experience and skills

    // Constructors, setters, getters...
}

Infrastructure requirements

To help bootstrapping the Infrastructure Services, the example provides a docker-compose.yml file. This quickstart provides three ways of running the example application. In development (“development”) mode, the user can start a minimal infrastructure using docker-compose and must run the business service manually. In “example” mode the docker-compose file will start the minimal infrastructure services and the business service, requiring the project to be compiled first to generate the process‘s container images. At least, the docker-compose “container” model will start the minimal infrastructure services, the Kogito application, and Management Console, still requiring the project to be compiled first to generate the process’s container images. To use docker-compose we must first create a .env file in the example root, and it should have the following variables:

PROJECT_VERSION=
MANAGEMENT_CONSOLE_IMAGE=
COMPOSE_PROFILES=
  • PROJECT_VERSION: Should be set with the current Apache KIE version being used: PROJECT_VERSION=
  • MANAGEMENT_CONSOLE_IMAGE: Should be set with the Apache KIE Management Console image docker.io/apache/incubator-kie-kogito-management-console:main
  • COMPOSE_PROFILES: filters which services will run.

Development mode

For development mode, the .env must have the COMPOSE_PROFILES=development:

PROJECT_VERSION=0.0.0
MANAGEMENT_CONSOLE_IMAGE=docker.io/apache/incubator-kie-kogito-management-console:main
COMPOSE_PROFILES=development

Example mode

For example mode, the .env must have the COMPOSE_PROFILES=example:

PROJECT_VERSION=0.0.0
MANAGEMENT_CONSOLE_IMAGE=docker.io/apache/incubator-kie-kogito-management-console:main
COMPOSE_PROFILES=example

Container mode

For container mode, the .env must have the COMPOSE_PROFILES=container:

PROJECT_VERSION=0.0.0
MANAGEMENT_CONSOLE_IMAGE=docker.io/apache/incubator-kie-kogito-management-console:main
COMPOSE_PROFILES=container

Handling services

To start the services use the command above:

docker compose up

To stop the services you can hit CTRL/CMD + C in your terminal, and to clean up perform the command above:

docker compose down

Running

Prerequisites

  • Java 17 installed
  • Environment variable JAVA_HOME set accordingly
  • Maven 3.9.6 installed
  • Docker and Docker Compose to run the required example infrastructure.

Infrastructure Services

This quickstart provides a Docker Compose template that starts all the required services. This setup ensures that all services are connected with a default configuration.

ServicePort @ localhost
PostgreSQL5432
PgAdmin8055
Management Console8280
This example's app8080

Running as containers

First, build the example running the following command on a Terminal:

mvn clean package -Pcontainer

This will build this example's Quarkus application and create a Docker image that will be started in the docker-compose template.

To execute the full example (including Management Console), run the following command inside the docker-compose folder:

docker compose up

IMPORTANT: if you are running this example on macOS and you are not using Docker Desktop, please append the following entry in your /etc/hosts file to enable a good communication between al components.

127.0.0.1 kubernetes.docker.internal

Additionally, if you want to start only the example and the minimal Infrastructure Services (PostgreSQL, Data-Index and Jobs Service), you can manually change the .env file with COMPOSE_PROFILES=example, and them start the Docker compose:

docker compose up
  • development: Starts only the minimal infrastructure to run the example (PostgreSQL, pgadmin)
  • example: Starts the services in dev profile and this example's app. Requires the example to be compiled with mvn clean package -Pcontainer.
  • container (default): includes all the above and Management Console. Requires the example to be compiled with mvn clean package -Pcontainer.

Running in Development mode

In Development mode profile will embed all the needed Infrastructure Services (PostgreSQL, Data-Index & Jobs Service) and won‘t require any extra step. To start this example’s app in Development mode, just run the following command in a Terminal:

mvn quarkus:dev -Pdevelopment

The development profile includes the Process Quarkus Dev UI Extension that exposes a new section in the Quarkus Dev UI page, featuring an embedded, dev-focused Management Console. Quarkus Dev UI is available at http://localhost:8080/q/dev

NOTE: For more information about how to work with Process Quarkus Dev UI Extension, please refer to the Kogito Documentation page.


Using

Starting an instance of the Hiring Process

Once the service is up and running you can make use of the Hiring application by a sending request to http://localhost:8080/hiring.

Sending the following valid CandidateData will start a process instance that will land into the HR Interview task:

{
  "candidateData": {
    "name": "Jon",
    "lastName": "Snow",
    "email": "jon@snow.org",
    "experience": 5,
    "skills": ["Java", "Kogito", "Fencing"]
  }
}

In a Terminal you can execute this curl command to start a Hiring process:

curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST http://localhost:8080/hiring -d '{"candidateData": { "name": "Jon", "lastName": "Snow", "email": "jon@snow.org", "experience": 5, "skills": ["Java", "Kogito", "Fencing"]}}'

If everything went well you may get a response like:

{
  "id": "628e679f-4deb-4abc-9f28-668914c64ef9",
  "offer": {
    "category": "Senior Software Engineer",
    "salary": 40450
  }
}

In the server logs you may find a trace like:

New Hiring has been created for candidate: Jon Snow
###################################
Generated offer for candidate: Jon Snow
Job Category: Senior Software Engineer
Base salary: 40450
###################################

Use the following CandidateData that don't match the minimal candidate requirements, to start a process that will automatically end:

{
  "candidateData": {
    "name": "Jon",
    "lastName": "Snow",
    "email": "jon@snow.org",
    "experience": 0,
    "skills": []
  }
}

In a Terminal you can execute this curl command to start a Hiring process:

curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST http://localhost:8080/hiring -d '{"candidateData": { "name": "Jon", "lastName": "Snow", "email": "jon@snow.org", "experience": 0, "skills": []}}'

If everything went well you may get a response like:

{
  "id": "3659601a-bb59-458d-859e-7892621ad5b7",
  "offer": null
}

In the server log you may find a trace like:

New Hiring has been created for candidate: Jon Snow
###################################
Candidate Jon Snow don't meet the requirements for the position but we'll keep it on records for the future!
###################################

Show active Hiring process instance at Management Console

Management Console is the tool that enables the user to view and administrate process instances in our Kogito application.

In this guide we'll see how to use the Management Console to view the state of the Hiring process instances.

First, you must connect the Management Console to the business service. To do so, open the localhost:8280 url, and click in “Connect to a runtime...” button:

Enter an alias, and the runtime url:

Now, you're connect to the Apache KIE Management Console:

  1. With the example built and all the Infrastructure Services running, let's start an instance of the _Hiring_process. To do so, in a Terminal just run:

    curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST http://localhost:8080/hiring -d '{"candidateData": { "name": "Jon", "lastName": "Snow", "email": "jon@snow.org", "experience": 5, "skills": ["Java", "Kogito", "Fencing"]}}'
    

    If everything went well, you should get a response like:

    {
      "id": "cee61d56-333b-433c-9c0a-32e81ee9fa4b",
      "offer": { "category": "Senior Software Engineer", "salary": 40450 }
    }
    

    Which indicates that a new process instance with id cee61d56-333b-433c-9c0a-32e81ee9fa4b has been started.

  2. Now let‘s check the process instance state with the Management Console. To do so, in your browser navigate to http://localhost:8280, and you’ll be redirected to the Process Instances page in the Kogito Management Console. There where you should be able to see the started process instance in active state.

  3. Click on the instance id to navigate into the Process Details page. In there you'll be able to see different panels displaying relevant information about the instance state, such as the Diagram, Timeline, Details, Variables, Jobs...

    Now check the Diagram panel, in there you‘ll se the instance execution path. Notice that it’s stopped HR Interview User Task waiting for some input from the user. The task has Timer that will skip the task if it‘s not completed in a given time (3 minutes in this example). You should be able to see the associated Job in the Jobs panel. Now, let’s wait 3 minutes to see the timer in action.

  4. After 3 minutes, the scheduled Job should have been executed, making the process instance skip the HR Interview task. In the Process Details page, click the Refresh button to see the process instance state.

    Again, check the Diagram panel to see the process instance execution path and the HR Interview task should have been skipped and the process instance continued its execution by following the Application denied path reaching the Completed state.

    Notice in the Jobs panel that the associated Job has the Executed status.

Complete Hiring process instances using Management Console

When a Kogito process reaches a User Task, the process execution stops waiting for the user input that will enable the User Task to finish and allowing the process execution to continue.

Management Console allows admin users to interact with the process User Tasks and provide the necessary data for the process to continue.

In this guide, we'll see how to complete the process User Tasks using Management Console to interact with the process User Tasks.

NOTE: for simplicity, all the User Tasks in this example are assigned to the jdoe user. Despite showing “Anonymous” in the top-right corner, Apache KIE Management Console will always use the first “potential user” defined by the Process Definition.

  1. With the example built and all the Infrastructure Services running, let's start an instance of the _Hiring_process. To do so, in a Terminal just run:

    curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST http://localhost:8080/hiring -d '{"candidateData": { "name": "Jon", "lastName": "Snow", "email": "jon@snow.org", "experience": 5, "skills": ["Java", "Kogito", "Fencing"]}}'
    

    If everything went well, you should get a response like:

    {
      "id": "3cf0d58f-a824-4046-ba6c-c2e79edc1df7",
      "offer": { "category": "Senior Software Engineer", "salary": 40450 }
    }
    

    Which indicates that a new process instance with id 3cf0d58f-a824-4046-ba6c-c2e79edc1df7 has been started.

  2. Let's check the process instance state. Again browse to http://localhost:8280 to access the Kogito Management Console, and in the Process List click the Id column to open the Process Details page.

    As expected, the process instance is stopped in the HR Interview task waiting for some input from the user. Let's try to complete the task.

  3. Now open the Management Console by browsing to http://localhost:8280. Navigate to the Tasks page, which contains the list of Active tasks. In this case you should be able to see only the new HR Interview task.

    Click on the HR Interview task to open the form and complete it!

  4. The Task Form is the main component to interact with User Tasks, it allows the user to provide the data required by the task and transition it to the next phase, allowing the Process to continue. The Task Form is autogenerated based on the User Task data assignments.

    HR Interview Form allows you to edit the actual Offer that will be sent to the Candidate and also approve or deny the job application with the Approve checkbox.

    Now, check the Approve checkbox click the Complete button in order to submit the form and complete the task. If the task could be successfully completed, a notification should appear in the screen and the form will stay in Read-Only mode.

    With the HR Interview task successfully completed the process has moved forward and reached the _IT Interview_task.

    Optionally, you can check the process instance state in the Management Console and verify the current execution path.

  5. Now is time to complete the IT Interview task and complete this Hiring process instance. In **Management Console **, go back to Tasks and, as expected, there you'll see that HR Interview is no longer available and a new * *IT Interview** has appeared.

    As done in Step #3, click in the IT Interview task to open the task form. IT Interview task only needs the candidate Approval to be submitted. Please, check the Approval field and click the Complete button to submit the form.

  6. After the form is submitted the IT Task should be completed and the process should continue, notifying the Candidate that he has successfully finished the Hiring process. Please go back to Tasks to verify there are no other active tasks waiting for you.

    You can also open use Management Console to check the state of the process instance and verify that the instance has been successfully completed.


Apache KIE (incubating) is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the name of Apache Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.

Some of the incubating project’s releases may not be fully compliant with ASF policy. For example, releases may have incomplete or un-reviewed licensing conditions. What follows is a list of known issues the project is currently aware of (note that this list, by definition, is likely to be incomplete):

  • Hibernate, an LGPL project, is being used. Hibernate is in the process of relicensing to ASL v2
  • Some files, particularly test files, and those not supporting comments, may be missing the ASF Licensing Header

If you are planning to incorporate this work into your product/project, please be aware that you will need to conduct a thorough licensing review to determine the overall implications of including this work. For the current status of this project through the Apache Incubator visit: https://incubator.apache.org/projects/kie.html