Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

Designing an event-driven process at scale: Part 3

February 21, 2020
Maurizio Carioli
Related topics:
Event-drivenJava
Related products:
Red Hat OpenShiftRed Hat Enterprise Linux

    In the first article in this series, Designing an event-driven business process at scale: A health management example, Part 1, you found the business use case and data model for a concrete example from the health management industry. You then began implementing the example in jBPM (an open source business automation suite) by creating the Trigger process.

    In the second article, you implemented the Task subprocess and, among other things, you also configured the call parameters for the Reminder and Escalation subprocesses within the Task subprocess. Now you will implement these subprocesses.

    The Reminder subprocess

    You should now create the email reminder subprocess with the properties shown in Figure 1.

    jBPM Diagram properties section filled out for this subprocess
    Figure 1:

    This subprocess needs the variables shown in Figure 2 to be defined.

    jBPM section defining the global and process variables for this subprocess
    Figure 2:

    Now, create the process diagram as shown in Figure 3.

    Create the email reminder subprocess workflow diagram.
    Figure 3: Create the email reminder subprocess workflow diagram.

    Next, you need the timer, which causes the email reminder to be executed at the frequency defined in the reminderFrequency attribute of the Task object, as shown in Figure 4.

    jBPM implementation section with the timer behavior defined
    Figure 4:

    The email reminder consists of the email custom work item handler that comes pre-installed in jBPM. You can see the service task parameters in Figure 5.

    jBPM Email Reminder Data I/O, Data Inputs and Assignments section with the values filled in.
    Figure 5:

    You can use the following on entry action to set the parameters for the email service task:

    Reminder r = (Reminder)kcontext.getVariable("_Reminder");
    kcontext.setVariable("_To",r.getAddress());
    kcontext.setVariable("_Subj",r.getSubject());
    kcontext.setVariable("_Body",r.getBody());
    kcontext.setVariable("_From",r.getFrom());

    Don't forget to catch the signal to stop the reminder, as shown in Figure 6.

    jBPM Implementation/Execution for Signal "stop_reminder"

    The Escalation subprocess

    This process is the simplest of all. It's just a human task as you can see in Figure 7.

    Diagram showing the Escalation subprocess workflow

    The Get the Data service

    The Get the Data service is implemented in the Express framework on node.js and can be cloned from GitHub. This is a simple REST service with hard-coded responses. Its only purpose is to be used in live demos of the business process described in this series. In a future article, I will show you how to implement this service using business rules. That way, this setting will no longer be hard-coded and it will be easy for nontechnical people to configure the "triggers" without involving developer work. Stay tuned!

    Here is the app.js:

    const express = require('express')
    const app = express()
    const bodyparser = require('body-parser')
    const port = process.env.PORT || 3200
    
    app.use(bodyparser.json())
    app.use(
      bodyparser.urlencoded({
        extended: false
      })
    )
    
    app.get('/get_trigger/:trigger_id/:member_id', (req, res) => {
      res.status(200).send([
        /**
        * Getting Provider Info
        */
      {
        task: {
          id: 35,
          origId: 'A490.0',
          suppressed: false,
          suppressionPeriod: '',
          expirationDate: '2020-12-31T12:00:00.000Z',
          close: 'HARD',
          reminderInitiation: 'P15D',
          reminderFrequency: 'R/P15D',
          escalationTimer: 'P30D',
          description: 'Getting provider info'
        },
        assignment: {
          actor: 'Peter',
          channel: 'MCC',
          escalationActor: 'Patricia',
          escalationChannel: 'CCN'
        },
        reminder: {
          address: 'peter@doctor.com',
          body: 'XYZ',
          from: 'PHM@healthinsurance.com',
          subject: 'Reminder'
        }
      },
    /**
    * Getting Community Health Worker Info
    */
    {
      task: {
        id: 58,
        origId: 'B143',
        suppressed: false,
        suppressionPeriod: '',
        expirationDate: '2020-12-31T12:00:00.000Z',
        close: 'HARD',
        reminderInitiation: 'P30D',
        reminderFrequency: 'R/P30D',
        // reminderInitiation : 'PT60S',
        // reminderFrequency : 'R/PT60S',
        escalationTimer: 'P90D',
        // escalationTimer : 'PT60S',
        decription: 'Getting Community Info'
      },
      assignment: {
        actor: 'Charlie',
        channel: 'CCN',
        escalationActor: 'Marc',
        escalationChannel: 'CCN'
      },
      reminder: {
        address: 'charlie@healthinsurance.com',
        body: 'XYZ',
        from: 'PHM@healthinsurance.com',
        subject: 'Reminder'
      }
    },
    /**
    * Getting Member Info
    */
    {
      task: {
        id: 128,
        origId: 'C201',
        predecessor: 'A490.0',
        suppressed: false,
        suppressionPeriod: '',
        expirationDate: '2020-12-31T12:00:00.000Z',
        close: 'SOFT',
        reminderInitiation: 'P7D',
        reminderFrequency: 'R/P7D',
        escalationTimer: 'P30D',
        description: 'Getting member info'
      },
      assignment: {
        actor: 'Mary',
        channel: 'MLP',
        escalationActor: 'Charlie',
        escalationChannel: 'CCN'
      },
      reminder: {
        address: 'mary@mail.com',
        body: 'XYZ',
        from: 'PHM@healthinsurance.com',
        subject: 'Reminder'
      }
    },
    /**
    * Getting Pharmacist Info
    */
    {
             task: {
               id: 112,
               origId: 'C178',
               predecessor: 'A490.0',
               suppressed: false,
               suppressionPeriod: '',
               expirationDate: '2020-12-31T12:00:00.000Z',
               close: 'SOFT',
               reminderInitiation: 'P7D',
               reminderFrequency: 'R/P7D',
               escalationTimer: 'P30D',
               description: 'Geting member info'
              },
              assignment: {
                actor: 'Robert',
                channel: 'CCN',
                escalationActor: 'Matthew',
                escalationChannel: 'CCN'
              },
              reminder: {
                address: 'robert@pharmacy.com',
                body: 'XYZ',
                from: 'PHM@healthinsurance.com',
                subject: 'Reminder'
              }
        }
      ])
    })
    
    app.listen(port, () => {
      console.log(`running at port ${port}`)
    })

    and this is the deployment descriptor in src/main/resources/META-INF/kie-deployment-descriptor.xml:

    <work-item-handler>
        <resolver>mvel</resolver>
        <identifier>new org.jbpm.process.workitem.rest.RESTWorkItemHandler(System.getenv("DEMO_REST_USER"), System.getenv("DEMO_REST_PWD"))</identifier>
        <parameters/>
        <name>Rest</name>
    </work-item-handler>
    

    The Email service

    This is the deployment descriptor for the Email service task:
    <work-item-handler>
        <resolver>mvel</resolver>
        <identifier>new org.jbpm.process.workitem.email.EmailWorkItemHandler(System.getenv("DEMO_SMTP_SERVER"), System.getenv("DEMO_SMTP_PORT),System.getenv("DEMO_SMTP_USER"),System.getenv("DEMO_SMTP_PWD"))</identifier>
        <parameters/>
        <name>Email</name>
    </work-item-handler>
    The SMTP server parameters are passed from the environment variables. When trying this task out, one can use an email test service such as Mailtrap.

    Considerations when using timers

    By default, jBPM uses EJB timer services to implement timers when deployed on a Java EE (Jakarta EE) server. EJB timers are not recommended for high volume situations. Quartz is a better alternative and is also available in a Spring Boot deployment.

    Another option is to use the service-level agreement (SLA) due date property of a node. This blog by Maciej Swiderski covers the SLA due date capability in jBPM.

    Each capability, whether you choose timers or the SLA, has pros and cons. Make your choice depending on the specifics of your use case. Here, while the number of members may be large, the number of PHM triggers per member in a given time period is typically small. The period of each timer is large (weeks), so the chance of many timers triggering at the same instant is not high.

    Forms

    Data entry forms can be automatically generated for each human task, and for each process. These forms are used mostly for the purpose of testing process execution during development. Typically, the production user interface of a human task is custom made. In this specific use case, the actor of each task should enter data using an existing application that passes the data to jBPM through a REST API exposed by jBPM. Therefore, you will not concern yourself with UI development.

    Event listeners

    The jBPM project is configured to use event listeners to trace process and rule information at runtime. If you want to take advantage of event listeners, you need to clone the PHM-Tracing and Tracing projects, and then build two jar files to install in the Kie server's lib directory. Otherwise, just unregister them in the process deployment descriptor:

    <event-listeners>
            <event-listener>
                <resolver>mvel</resolver>
                <identifier>new com.health_insurance.tracing.PHMProcessEventListener()</identifier>
                <parameters/>
            </event-listener>
            <event-listener>
                <resolver>mvel</resolver>
                <identifier>new com.health_insurance.tracing.PHMAgendaEventListener()</identifier>
                <parameters/>
            </event-listener>
        </event-listeners>
        <task-event-listeners>
            <task-event-listener>
                <resolver>mvel</resolver>
                <identifier>new com.health_insurance.tracing.PHMTaskLifeCycleEventListener()</identifier>
                <parameters/>
            </task-event-listener>
        </task-event-listeners>

    Demo users

    A shell script is provided in the directory src/main/sh that creates users and groups to run a few scenarios with this business process. This script is intended to be used with JBoss Wildfly.

    Conclusion

    You have now implemented your own health management demo of an event-driven process with jBPM that is designed to scale with the complexity of the event logic as well as with the volume of events. By now you should better understand several topics through implementing this process:

    • Business process abstraction.
    • Service tasks or work item handlers.
    • REST API calls from within a process.
    • Email sending from within a process.
    • Signal sending and catching.
    • Timer-based reminders and escalations.

    Of course, the design and development of a process are not enough. You certainly would like to see this process in action, as well. The next articles in this series will cover deploying and executing this process.

    Last updated: May 29, 2023

    Recent Posts

    • Red Hat Hardened Images: Top 5 benefits for software developers

    • How EvalHub manages two-layer Kubernetes control planes

    • Tekton joins the CNCF as an incubating project

    • Federated identity across the hybrid cloud using zero trust workload identity manager

    • Confidential virtual machine storage attack scenarios

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.