2017/07/06

Make use of rules to drive your cases

In case management that was recently released with jBPM version 7, there is a change in the way we look at cases. They are more data driven than flow driven. Of course users are free to define parts of the case definition to be process fragments (see the attached sample) but what is important is the look at cases as data that are handled.

The steps required to resolve a case are mainly driven by data - that can be people involved in the case (based on the available data take certain actions) or the system itself can decide based on that data to trigger further actions.

This article is about the later case - system is taking decisions for further actions. And what is better to take this than business rules :)

Let's have a look at simple scenario, where we have basic car insurance case definition that looks like this


There are two roles involved:

  • insured 
  • insuranceRepresentative
At any given point in time data can be inserted into the case instance - to be precise its case file. CaseFile data is under constant supervision of the rule engine and thus we can build up rules that will react to the data that our case instance contains.

To provide very simple scenario, let's assume that at some point there is a need for more information to be collected from the insured. This simple case could also be handled by a human actor e.g. person who takes the role of insurance representative in particular case instance. Though for the sake of example we can just make a business rule that will react immediately once the data of the case instance indicate there is a decision to ask for more details. It will automatically create human task assigned to the insured.


rule "ask user for details"

when 
    $caseData : CaseFileInstance()
    String(this == "AskForDetails") from $caseData.getData("decision")
          
then 
    $caseData.remove("decision");
    CaseService caseService = (CaseService) ServiceRegistry.get().service(ServiceRegistry.CASE_SERVICE);
    Map<String, Object> parameters = new HashMap<>();
    parameters.put("reason", "How did it happen?");
    caseService.addDynamicTask($caseData.getCaseId(), caseService.newHumanTaskSpec("Please provide additional details", "Action", "insured", null, parameters));
    
end


So that simple rule will do exactly that. If there is a decision in the case file that is set to AskForDetails, then the rule will:
  • remove the decision from the case to avoid rule loop
  • use ServiceRegistry to get hold of case service instance
  • configure task input parameters
  • finally add dynamic task to the case instance that is assigned to use who has role insured in the case instance
That's all, as simple as that :) Obviously this is simplistic use case but it opens the door for integration between rules and case management to make it even more powerful for the users. Since that is all about dealing with data, combination of rules and case management is a perfect fit.

Note, ServiceRegistry is part of jbpm-services-api module so make sure that is available on the class path. When building project (kjar) in workbench there is no need to add anything else but if you would like to build it outside of workbench make sure you add following dependencies to your project - both in scope provided.
  • org.jbpm:jbpm-services-api
  • org.jbpm:jbpm-case-mgmt-api
ServiceRepository can also be used for regular processes in exact same way. Here are the services that are automatically registered in the registry:

org.jbpm.services.api.DefinitionService
org.jbpm.services.api.DeploymentService
org.jbpm.services.api.ProcessService
org.jbpm.services.api.RuntimeDataService
org.jbpm.services.api.UserTaskService
org.jbpm.services.api.admin.ProcessInstanceAdminService
org.jbpm.services.api.admin.ProcessInstanceMigrationService
org.jbpm.services.api.admin.UserTaskAdminService
org.jbpm.services.api.query.QueryService
org.jbpm.casemgmt.api.CaseRuntimeDataService
org.jbpm.casemgmt.api.CaseService


ServiceRegistry has public static members for all out of the box services so that is the recommended way to look them up in the registry. If for whatever reason you prefer to use string based it's the simple name of the interface listed above e.g. DefinitionService or CaseService.

One final note, this comes with jBPM 7.1 which is just behind the corner...