At the beginning of the second decade of the twenty-first century we can still claim that smart humans are more clever than average machines. On the other hand, we probably have to admit that any machine is more reliable as a scheduler and reminder than an average human. So, when we face a task that requires human intervention in order to be completed, it feels natural to be able to set up a machine to periodically warn the human that his clever assistance is required to fulfill the task on time. That’s precisely the purpose of Kogito task deadlines functionality.
The basic idea behind deadlines is that when they expire, a notification is triggered. Hence, a deadline is composed of an expiration date, the type of occurrence and notification information.
The expiration date will either be an exact date (just one notification) or a period interval: bounded (by establishing a maximum number of notifications) or unbounded (no limit of notifications). It is worth mentioning that when authoring the BPMN process, the human designer associates a deadline date to the task with the help of a graphical tool, but that internally the BPMN process is stored as a string following ISO 8601 format. That’s the reason why the tool also allows advanced users, familiar with ISO 8601 syntax, to directly type it.
The deadline type can be “notStarted” or “notCompleted”. When the deadline date is reached, if type is “notStarted”, a notification is triggered if no phase transition has been performed over the task. “notCompleted” deadline types are triggered if the task is not completed. So we are essentially covering the two most common branches of human laziness: a task that has not been worked at all and a task that was started but left uncompleted.
The notification information is the data that will be included in the notification if it is eventually fired, which leads us to the question: what happens when a notification is triggered?. Kogito is handling the notification as a specific type of event: UserTaskDeadline. That event will contain task information plus the deadline notification information, which is a list of key-value pairs. These values might contain MVEL expressions to be evaluated against the task information. Combining arbitrary information with the power of an expression language, the task notification event might be used for multiple purposes.
In fact, the way the task notification event is handled depends on the add-ons that are configured. By default Kogito does nothing, but it provides two addons to publish the event on a message broker: task-notification-quarkus-addon and task-notification-springboot-addon. Once it is published, someone should consume the notification event to do something useful with it. Kogito provides another pair of add-ons to send an email using notification information included in the deadline: mail-quarkus-addon and mail-springboot-addon.
On summary, when task-notification and email addon are included in the project pom.xml for our target platform (Quarkus or Springboot) and a deadline is configured in the BPMN process, if a task is left unattended for a while, an email will be send. Let’s see how it works extending the approvals example from previous posts.
As you probably recall, approvals process defines a task called firstLineApproval. We are going to configure Kogito, using Quarkus as target platform, to send an email every minute till the firstLineApproval human task instance that is created at process startup is completed.
The first thing to do is to update the bpmn process through the graphical editor. In the notification window associated with the firstLineApproval task, we can provide details about the deadline date plus the data needed to send an email.
As previously mentioned in the introduction, although the window is designed for email notifications, notifications are generic, meaning that fields specified in the graphical interface are internally handled as a generic key value pair list. This will allow developing custom extensions different from the email addon we are going to use in this example.
As you can see in the screenshots, we are telling Kogito to fire a notification every minute till the task is completed. When the period expires, an email to firstname.lastname@example.org will be sent, reminding that lazy user that something needs to be done with the task.
Once bpmn is properly configured, we still need to set up the addons. Approvals project pom already has a notification profile that includes these dependencies.
<profile> <id>notification</id> <dependencies> <dependency> <groupId>org.kie.kogito</groupId> <artifactId>mail-quarkus-addon</artifactId> </dependency> <dependency> <groupId>org.kie.kogito</groupId> <artifactId>task-notification-quarkus-addon</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId> </dependency> </dependencies> </profile>
As you can see, we are selecting task-notification-quarkus-addon, which uses smallrye messaging library to define a channel called kogito-deadline-events, where an event containing the notification data is published. Since we are going to configure that channel to use Kafka, we also include quarkus-smallrye-reactive-messaging-kafka dependency
We configure the publishing channel to use Kafka by adding these properties to application.properties.
mp.messaging.outgoing.kogito-deadline-events.connector=smallrye-kafka mp.messaging.outgoing.kogito-deadline-events.topic=kogito-deadline-events mp.messaging.outgoing.kogito-deadline-events.value.serializer=io.quarkus.kafka.client.serialization.ObjectMapperSerializer
Once we have notification events being published into Kafka, we need to set up a listener that sends the email upon event reception. We do that by including mail-quarkus-addon into project pom. This add-on will listen for events on a smallrye channel named kogito-deadline-consumer and send an email using the information contained in the message received by that channel.
In order to setup the incoming channel, we need to mimic the configuration provided for the publishing channel. As you correctly guessed, we also do that in the same application.properties file.
mp.messaging.incoming.kogito-deadline-consumer.connector=smallrye-kafka mp.messaging.incoming.kogito-deadline-consumer.topic=kogito-deadline-events mp.messaging.incoming.kogito-deadline-consumer.value.deserializer=org.kie.kogito.mail.DeadlineEventDeserializer
Finally, we need to tell the mail addon the details of the smtp server to be used to send email. We do that by adding following properties to application.properties
quarkus.mailer.host=localhost quarkus.mailer.port=25 quarkus.mailer.mock=false quarkus.mailer.ssl=false quarkus.mailer.start-tls=disabled
In this particular example, since I’m using Fedora Linux, I’m setting up a local postfix mail server. A complete configuration reference for quarkus mailer, the underlying library being used for the mail addon, can be found here.
When all this configuration is in place, once the process instance is started, if nothing else is done, after a minute the following e-mail appears in my account.
In this post we have learnt how to set up Kogito to send an email when a task has not been completed for a while. We also learned that this is just the tip of the iceberg, because task deadline notifications can be used for many other purposes, only limited by the creativity of developers willing to implement more addons.