Open Editions

Open Editions

Come for answers. Stay for best practices. All we’re missing is you.

 View Only

Using custom WorkItemHandlers in BAMOE 9.2.1 release

By Abhijit Humbe posted 2 days ago

  

In BAMOE, a WorkItem represents a task or activity in a process that needs to be performed, often outside the standard BPMN tasks, for example,calling REST API, DB operations, consuming SOAP webservices,etc. Custom Work Item Handler is a user-defined Java class that implements custom logic for a specific task execution in a business process. It extends the capabilities of standard BPMN tasks (like service tasks) by allowing developers to plug in custom code to handle particular business needs that aren't covered by out-of-the-box functionality.

  • Creating a BAMOE maven project structure. use following command to create a project:
     git clone https://github.com/IBM/bamoe-canvas-quarkus-accelerator -b 9.2.1-ibm-0005-quarkus-full my-business-service-project

  • In project pom.xml add following dependency:

    <dependency>
         <groupId>org.kie.kogito</groupId>
         <artifactId>kogito-api</artifactId>
      </dependnecy>

  • BAMOE 9 application tries to load a *.wid file in two locations by default:
    • Within the project’s top-level global/ directory.
    • Within the project’s src/main/resources/ directory or at any level of a Java package. A *.wid file can be created at a resource directory location src/main/resources/  or at a package level src/main/resources/com/ibm/.
  • WorkItem icon files can be places in the same directory where *.wid file is created:

    [
            [
                "name" : "MyConcatDefinitions",
                "displayName" : "MyConcatDefinitions",
                "category" : "myconcatworkitem",
                "description" : "",
                "defaultHandler": "mvel: new com.ibm.MyConcatWorkItemHandler()",  
                "parameters" : [
                            "FirstName" : new StringDataType(),
                            "LastName" : new StringDataType()

                ],
                "results" : [
                          "FullName" : new StringDataType()
                ],
                "icon" : "MyConcatDefinitions.png"
            ]
    ]

  • Create the new BPMN file with name CustomTaskDemo.bpmn in project resources directory and add customTask(MyConcatDefinitions) from pallet:

  • In created process definition define process variables to accept input from end user while starting process instance:

  • Define DataInput and DataOutput assignment for custom workItem/node so that values of the process variables will be assigned to task variables:

  • To create a custom workItemHandler, create a MyConcatWorkItemHandler class that extends org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler class.

    import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
    import org.kie.kogito.internal.process.workitem.KogitoWorkItemHandler;
    import org.kie.kogito.internal.process.workitem.KogitoWorkItemManager;
    import org.kie.kogito.internal.process.workitem.WorkItemTransition;
    import org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler;
    import org.slf4j.LoggerFactory;

    public class MyConcatWorkItemHandler extends DefaultKogitoWorkItemHandler {

        private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(MyConcatWorkItemHandler.class);

        @Override
        public Optional<WorkItemTransition> activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) {

            for (String parameter : workItem.getParameters().keySet()) {
                LOG.info(parameter + " = " + workItem.getParameters().get(parameter));
            }

            Map<String, Object> results = new HashMap<String, Object>();

            String firstName = (String) workItem.getParameter("FirstName");
            String lastName = (String) workItem.getParameter("LastName");
            String fullName = firstName + " " + lastName;

            results.put("FullName", fullName);

            return Optional.of(handler.completeTransition(workItem.getPhaseStatus(), results));

        }
        @Override
        public Optional<WorkItemTransition> abortWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler handler, KogitoWorkItem workItem, WorkItemTransition transition) {
            LOG.info("Aborting work item " + workItem);
            return Optional.of(this.workItemLifeCycle.newTransition("abort", workItem.getPhaseStatus(), workItem.getResults()));
        }
    }


    In WorkItemHandler's activateWorkItemHandler(...) method we can add business logic. This might be mean interacting with a web service, database, or other technical component and will mark workitem is completed successfully and  abortWorkItemHandler(...) methods will abort the workitem execution. In BAMOE 8, custom WorkItemHandler implemented the interface org.kie.api.runtime.process.WorkItemHandler and uses  executeWorkItem(...) and abortWorkItem(...) methods, but in BAMOE v9 these methods are not supported.

  • In order to use custom workItemHandler in process instance, it's necessary to register the work item handler before starting the process. This makes the engine aware of your WorkItemHandler so that the engine can use it for the particular node.  In BAMOE v9 to register custom workItemHandler create a class which extends org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig 

    import org.kie.kogito.process.impl.DefaultWorkItemHandlerConfig;
    import jakarta.enterprise.context.ApplicationScoped;

    @ApplicationScoped
    public class CustomWorkItemHandlerConfig extends DefaultWorkItemHandlerConfig {

        {
            register("MyConcatDefinitions", new MyConcatWorkItemHandler());
        }
    }

 

  • Build and execute the project using following command

    mvn clean package
    java -jar target/quarkus-app/quarkus-run.jar

  • Start the process using following curl command: 

    curl -X 'POST' 'http://localhost:8080/CustomTaskDemo' \
      -H 'accept: */*' -H 'Content-Type: application/json' \
      -d '{ "FirstName": "Alex", "LastName": "Tom" }'


  • In the log file we can see custom Task is executed 

    13:18:15,826  INFO  [com.sample.MyConcatWorkItemHandler:22] (executor-thread-1) FirstName = Alex
    13:18:15,826  INFO  [com.sample.MyConcatWorkItemHandler:22] (executor-thread-1) LastName = Tom
    13:18:15,826  INFO  [com.sample.MyConcatWorkItemHandler:22] (executor-thread-1) TaskName = MyConcatDefinitions
    13:18:15,826  INFO  [com.sample.MyConcatWorkItemHandler:22] (executor-thread-1) NodeName = MyConcatDefinitions
    13:18:15,826  INFO  [com.sample.MyConcatWorkItemHandler:22] (executor-thread-1) UNIQUE_TASK_ID = _E2D196C3-0F09-490A-9E26-F4F4BA04BD8C
    Full name:Alex Tom

0 comments
21 views

Permalink