6 Replies Latest reply on Oct 31, 2013 1:32 AM by bwallis42

    Querying and Sorting Tasks

    bwallis42

      I have a requirement that seems difficult to implement using the JBPM6 human task service and I'm after some advice about how I might do this.

       

      In our existing product based on JBPM 5.1 we have a task list that looks like this

      tasklist.jpg

      The columns priority and status could be task attributes (although at the moment they are our own process variables) but the rest are all process variables specific to this particular workflow.

       

      I need to present a paged list of tasks that can be sorted by any column and that I can search and filter based on the column values. I also can have over 2000 active tasks for this one workflow type. We create 500-700 workflow instances per day and it takes on average 3 days (elapsed time) to complete one going through about 4 tasks.

       

      For other workflow types I would have a different set of columns and query/sort requirements based on the variables defined for those workflow types (so far we only have one workflow type).

       

      At the moment we don't use the jbpm human task list, we have implemented our own that persists the tasks and their variables in its own hibernate based model. With this we can query and sort the list as required.

       

      I would rather not do this. I would much rather use the built in task list management (much better state model than ours). But I don't see how I can efficiently perform the queries and sorting of the list of tasks using the existing API (or at least what I can find in the API).

       

      Are there bits of the API I am unaware of? The only queries that seem to be available are from the TaskService interface.

       

      thanks.

        • 1. Re: Querying and Sorting Tasks
          salaboy21

          Hi Brian,

          If you are mixing data from several components and systems you will need to have an intermediate layer to join all that information and providing a sorting mechanism that will be performant enough for your use case. Just using the queries will not be enough IMO. One of the things that I would like to see happening for 6.1 is to align the task queries to work like the process instances lists (which is based on a audit log instead of the real execution of the processes). Doing so will allows us to decouple the internal storage of information used by the runtime and the external information used by the UI and the rest of the clients. Nowadays you can replace the listeners that externalise the data and replace it for a more performant implementation that uses cached data or more advanced index techniques.

          1 of 1 people found this helpful
          • 2. Re: Re: Querying and Sorting Tasks
            bwallis42

            I'm not mixing data in from other components, just need search/query access to the variables that are sent with the task from the workflow to the human task management. But that said, we do have another store of workflow related data that may become relevant for task management.

             

            So, replacing the listeners sounds interesting. How do I do this? I found code in DefaultRegisterableItemsFactory and tried to replicate that with the following

             

                    RuntimeManager manager = deploymentService.getRuntimeManager(unitId);
            
                    RuntimeEngine engine = manager.getRuntimeEngine(ProcessInstanceIdContext.get());
            
                    TaskService taskService = engine.getTaskService();
                    if(taskService instanceof EventService)
                    {
                        ((EventService)taskService).registerTaskLifecycleEventListener(new TaskEventListener());
                        ((EventService)taskService).registerTaskNotificationEventListener(new TaskNotificationListener());
                        
                        if (engine instanceof Disposable) {
                            ((Disposable)engine).addDisposeListener(new DisposeListener() {
                                
                                @Override
                                public void onDispose(RuntimeEngine runtime) {
                                    if (runtime.getTaskService() instanceof EventService) {
                                        ((EventService)runtime.getTaskService()).clearTaskLifecycleEventListeners();
                                        ((EventService)runtime.getTaskService()).clearTasknotificationEventListeners();
                                    }
                                }
                            });
                        }
                    }
            

             

            But I don't seem to be able to get this to work. The above code is executed just before I call ksession.startProcess() and all of this is inside of a RESTEasy method. The deploymentService is injected into my RESTEasy class (all running inside JBoss EAP 6).

             

                @Inject
                @Kjar
                private DeploymentService deploymentService;
            

             

            I'm testing all this via a simple knockoutJS UI connected to a bunch of REST methods that I use to create and interact with the workflows.

             

            What seems to be happening is that the onDispose() method is called during exit from this REST call. The workflow runs OK, stops at the human task, I can start and complete the task and the workflow completes. But the event listeners are never invoked. I assume this is something to do with the CDI injection of the deployment service and its lifecycle management.

             

            So, the question is, how do I change or add task lifecycle event listeners?

             

            thanks

            • 3. Re: Re: Re: Querying and Sorting Tasks
              bwallis42

              Should mention that I have a Producer for the deployment service like so

               

              @ApplicationScoped
              public class Producer
              {    
                  @Inject
                  @Kjar
                  private DeploymentService deploymentService;
                  
                  /**
                   * Required for human tasks form provider (?)
                   * (See {@link org.jbpm.kie.services.impl.form.FormProviderServiceImpl#deploymentService})
                   */
                  @Produces
                  public DeploymentService getDeploymentService()
                  {
                      return deploymentService;
                  }
              // ...
              }
              

               

              without this I get this error on startup:

               

              12:20:06,191 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC000001: Failed to start service jboss.deployment.unit."simpleflow.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."simpleflow.war".WeldStartService: Failed to start service
                at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1767) [jboss-msc-1.0.4.GA-redhat-1.jar:1.0.4.GA-redhat-1]
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_17]
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_17]
                at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_17]
              Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [DeploymentService] with qualifiers [@Default] at injection point [[field] @Inject private org.jbpm.kie.services.impl.form.FormProviderServiceImpl.deploymentService]
                at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:311)
                at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:280)
                at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:143)
                at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:163)
                at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:382)
                at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:367)
                at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:379)
                at org.jboss.as.weld.WeldStartService.start(WeldStartService.java:64)
                at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.4.GA-redhat-1.jar:1.0.4.GA-redhat-1]
                at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.4.GA-redhat-1.jar:1.0.4.GA-redhat-1]
                ... 3 more
              
              • 4. Re: Re: Querying and Sorting Tasks
                swiderski.maciej

                Brian, since you're in CDI environment you should use CDI based version on RegisterableItemsFactory which is InjectableRegisterableItemsFactory and then you can simple make your listeners CDI-ish and they will be discovered automatically and used for all task events. Here is an example of such an task event listener that is used for audit logging in human task.

                 

                HTH

                • 5. Re: Querying and Sorting Tasks
                  bwallis42

                  Thanks Maciej, Exactly what I was after. Now I can get all of the info I need about the tasks, and with CDI it is just so easy (and slightly magical :-)

                   

                  brian...

                  • 6. Re: Querying and Sorting Tasks
                    bwallis42

                    Can I do something similar for process events, ie: build a CDI class implementing org.kie.api.event.process.ProcessEventListener and have that picked up in InjectableRegisterableItemsFactory?

                     

                    thanks.