In the last post, we gave a lightning fast introduction to the elements that make up a CMMN model, with an example model to look at and even download to play with. In this post and following ones, we’ll look at this model in more detail as a way to introduce using CMMN in action, as well as some of the gotchas that inevitably come when you need to make something execute in a scalable and performant way.
I’ll be showing screens from the enterprise trial version, but everything about the execution of what I’ll cover is identical in the community version.
A quick recap of the CMMN model. There are 3 stages that are sequential: you receive a claim, investigate it, then handle the claim. This is modelled by a stage having an entry sentry (diamond shaped) connected to a finishing event (a dashed line) of the prior stage. There’s also a couple of other elements floating around outside of any stage – you don’t need to have a stage but they are generally useful for clustering related items. Stages can be nested too, bringing additional levels of scoping.
A key concept in CMMN is the lifecycle of activation for elements. Again, we’d recommend Bruce Silver’s book to go deep into that. With CMMN we’re always looking at what’s available and can be made active, either automatically or started manually by a user. CMMN is about making the right set of options available to a user, or automatically executed, at the right time and in the right circumstances. The main states in a case element life-cycle are shown in the figure below, there are more states and they vary a bit for certain elements, but these are what you’ll usually be considering.
Anything inside a container (such as a stage) only has a chance to become available if its container becomes active, and the top container for a case is the Case Plan – the big folder icon surrounding everything. When you create an instance of a case, the first thing a CMMN engine does is check what items in the case plan can be available. Anything directly in the case plan is immediately available. However, for any of them to become active, there’s some conditions to be met.
Let’s look at that example CMMN model to see how this works in practice. When an instance of the Claims Case is created, the 3 top-level stages all become available. Two of them have entry sentries that are conditional on events that haven’t happened yet so remain available, but the Receive claim stage has no entry sentry, so immediately becomes active. This means all the items inside that stage can become available (we’ll come back to the exceptions). In that stage there’s a human task Capture claim details without an entry sentry – so, it automatically gets activated too. By creating an instance of this case model, we’ve immediately jumped to its first stage and kicked off a task!
Now, the exception I mentioned. When an available item is marked as manually activated it is instantly made enabled, ready to become active at the click of a button by a user. This is why the human tasks Add incident report from police and Need 3rd party report don’t get started when the Receive claim stage is activated, even though they have no entry sentry. They sit, waiting enabled, until a user action starts one and a task is created.
User event listeners, like Abandon claim and Details completed in the example, are like manually activated tasks in that they wait for a user action to trigger them – the difference is that they’re treated as available rather than enabled (ask someone on the standards committee why, I don’t know). This is what Flowable Work looks like to the user after starting this case.
We’ve created a case instance and got a first task. In our example, there’s also a task Update claimant contact details in the top-level case plan and it’s manually activated. When we created the case, this task is also made enabled but will wait for a user action before being created. The Abandon claim user event listener is also in the top-level case plan, so it too is made available and will show as a user action. In total now, after creating the case, we will have a user task created and four actions available to the user: Abandon claim, Update claimant contact details, Need 3rd party report and Add incident report from police. The Terminate action in the screen above is a global action for all cases and processes, not part of the individual case model.
With the example app, we haven’t added any logic or forms to the tasks, to make it easy to just step through. If we complete the Capture claim details task, its status moves from active to complete (not that surprising). Look at the case diagram and you can see there’s a link from that user task to an entry sentry on a process task. The link represents an event that’s happened to trigger the entry sentry. It’s possible to have a condition expression on the entry sentry (in Flowable we show sentries with conditions by a yellow diamond). In this example, there’s no condition, so when the Capture claim details is completed by a user, the complete event triggers the Need additional information process to become enabled (it’s manually triggered, so will wait for a user to start it). It wasn’t enabled before now, so you’ll find a new user action visible to you.
The Details completed event listener is connected to an exit sentry (black diamond) on the stage. In the same way that an entry sentry can trigger and control things becoming active, and exit sentry can trigger something to exit, or finish. At this point, we could select the Details completed action and force the stage to exit, which in turn would trigger the event to the entry sentry on the Investigate claim stage and start it. However, we’re not going to yet, we’re going to look at the strange looking relationship between the other tasks in the Receive claim case, which illustrate something that isn’t possible with BPMN without coding or convoluted signal throwing – but that’s for the next post in this series!