7 Replies Latest reply on Jan 27, 2012 1:21 PM by jemmerling

    Trying to set ActorId in On Entry Action - work item is null

    jemmerling

      Hi,

       

      I am trying to implement an On Entry Action to set the ActorId for a work item.

       

      More generally, what I am trying to do is to assign a task to a specific actor under certain circumstances. In the process definition, the ActorId is empty for the node however GroupId is specified. So ordinarily, some member of a group will claim the task, however given a certain condition, I want the task to be assigned to a specific actor.

       

      This is probably the wrong way to do it, but I hope I am close.

       

      So I implemented this On Entry Action, I can access the node instance but there is no work item (as opposed to the situation encountered in an On Exit Action):

       

      System.out.println("* * * * * * * * * manager: " + manager + " * * * * * * * * * * * * * * * * ");

      if (manager != null)
      {
      System.out.println("* * * * * * * * * setting ActorId to " + manager + " * * * * * * * * * * * * * * * * ");
      WorkItemNodeInstance nodeInstance = (WorkItemNodeInstance)kcontext.getNodeInstance();
      if (nodeInstance != null)
      {
        WorkItem workItem = nodeInstance.getWorkItem();
        if (workItem != null)
        {
         System.out.println("* * * * * * * * * about to set ActorId to " + manager + " * * * * * * * * * * * * * * * * ");
         workItem.setParameter("ActorId", manager);
         String actorId = (String) workItem.getParameter("ActorId");
         System.out.println("* * * * * * * * * ActorId was set to " + actorId + " * * * * * * * * * * * * * * * * ");
        }
        else
        {
         System.out.println("* * * * * * * * * workItem was null * * * * * * * * * * * * * * * * ");
        }
      }
      else
      {
        System.out.println("* * * * * * * * * nodeInstance was null * * * * * * * * * * * * * * * * ");
      }
      }
      else
      {
      System.out.println("NOT setting ActorId");
      }

       

      Here is what is written to stdout:

       

      * * * * * * * * * manager: pmanager2 * * * * * * * * * * * * * * * *

      * * * * * * * * * setting ActorId to pmanager2 * * * * * * * * * * * * * * * *

      * * * * * * * * * workItem was null * * * * * * * * * * * * * * * *

       

      Can anybody see what I am trying to do and tell me what is the correct approach?

       

      Thanks!

       

      --JE

        • 1. Re: Trying to set ActorId in On Entry Action - work item is null
          swiderski.maciej

          Yes, on onEntry event work item is not yet created - unfortunately.

           

          Just wondering what you are trying to achieve with the code above... since if you use group id as main assignment criteria and then add actor id (meaning there will be both group and actor) it wil not assign the task to that actor only. Task will be available for all of them.

           

          I can see two options here:

          • use a XOR gateway and two user tasks (one for manager and one for group)
          • use one userTask and make it only group assignable and one of the group will be a manager's group (with possible only one member) and make GroupId to be set from process variable that you can modify during process instance flow.

           

          HTH

          • 2. Re: Trying to set ActorId in On Entry Action - work item is null
            jemmerling

            What I am trying to achieve:

             

            The node definition specifies a group. Ordinarily, when a new task is created, it can be claimed by any member of that group.

             

            However, when the process instance progresses to the next node, the actor working on that (subsequent) task may reject what the previous actor (i.e. the one who claimed the previous task in the flow) did and send it back to that actor to redo. In this case, I would want it to be the same node.

             

            I didn't know what is the effect of specifying ActorId and GroupId and I'm not certain this is well understood in general. So given what you have said, I would want to not only set ActorId but remove GroupId from that instance of the node (or task). But hopefully the same node. So it should be immediately reserved by that actor without their having to claim it.

             

            As far as setting GroupId from a process variable, could you possibly give an example how to do that? I haven't found a good reference for the EL and the examples are scattered so I can't remember where to go for the example I need to emulate.

             

            So anyway, let's assume that I want to specify eithor GroupId or ActorId (or both) on the fly in this situation, how can I do that? Can I do it in an On Entry Action or a Script Task or by using an expression in the BPMN2 node definition?

             

            Thanks!

             

            --JE

            • 3. Re: Trying to set ActorId in On Entry Action - work item is null
              swiderski.maciej

              Thanks for more details about your case. If I got it right, you have two user tasks: one for group of workers and the other for approver(s). So when first one is completed the approver verifies the work and if (s)he is not happy with outcome you would like to get the task back to the user who completed it. Is my understanding correct?

               

              If so, you can't get back to the same task instance, once it is completed it cannot be reopened, it will create new instance of the same task node. I would see this case as follows:

              • one task for group of workers (assigned with group id)
              • once task for approver (assigned either with potential owner or with group id)
              • third task for rework (assigned with potential owner)

               

              So, whenever approver is not happy it moves the flow into the third user task that is kind of a copy of the first one but can be assigned to only one potential owner, the one who completed first task. So it will operate on the same data and most likely with the same forms. Of course some would say it is duplication of tasks but in my opinion that keeps the model clean and easy to follow from business perspective.

               

              Regarding usage of group assignment, I believe this could be great starting point, thanks to Demian

               

              HTH

              • 4. Re: Trying to set ActorId in On Entry Action - work item is null
                jemmerling

                Sorry, I believe the terminology can cause some confusion.

                 

                What I am trying for is (in the scenario given) 2 tasks and 3 task instances in this case. I will use letters to designate tasks and numbers to designate task instances.

                 

                Also I cannot see a strong distinction between a node and a task other than to argue that not all nodes are tasks. So when I say (human) task I could also mean node. When I say task instance I could also mean node instance. Also I will confess that I am not entirely certain just what a work item is as opposed to a task or a node instance. I suppose I will only understand fully when I have looked at enough code (which so far has been a fairly productive way of learning).

                 

                So task A and task B are as you described them (worker/approver) although the real-world problem I want to address is more complicated. Both have GroupId specified in their static definition and neither has ActorId specified (in fact in our model, we would never want to have to think about a given individual).

                 

                So the scenario is:

                 

                1.) Task A -> Task Instance 1: Actor 1 (member of Task A's group) claims this task instance, works on it, and completes it.

                                              ..also Actor 1's ID is saved as a process variable so we know who completed this task instance

                2.) Task B -> Task Instance 2: Actor 2 (member of Task B's group) claims this and "rejects" it by not setting an "approved" variable (which is a process variable).

                                              ..so the sequence branches at an XOR gateway which in the BPMN model leads back to Task A

                3.) Task A -> Task Instance 3: Actor 1 now sees that the task has been assigned to them immediately, they will not need to claim it; it is already reserved for them to work on.

                                              ..Steps 2.) and 3.) could repeat an arbitrary number of times but will eventually lead to a hypothetical step 4.) which should involve Task C or be an end node.

                 

                This same pattern will in reality occur 4 or more times in the real-life business process so I don't want to have to define a Task A', B', etc. for every task just to allow for "rework".

                 

                Of course, an administrator would always have the ability to reassign any task instance to a different actor, but of course that would require said administrator's intervention.

                 

                However, suppose I did go with the A', B'..Z' approach as you seem to be suggesting. Then I would still need to know how to assign the ActorId from a process variable. Would I use some expression such as #{variable}?

                 

                And I would still like to know if there is a way to programmatically override the ActorId and/or GroupId specification for a task/node using either MVEL or Java, within a script node or within a entry or exit action. If you know how this would be accomplished, could you please refer me to an example!

                 

                Thanks!

                 

                --JE

                 

                • 5. Re: Trying to set ActorId in On Entry Action - work item is null
                  swiderski.maciej

                  Agree, I used to many terms that could make the solution bit fuzzy.... let me put it here:

                  • node is a definition of a particular logic in the process (bpmn)
                  • node instance is a runtime element of process instance build based on node
                  • task is a special representation of a node
                  • task instance is an instance created based on task and maintained by Task Server that has its life cycle as defined in WS-HumanTask spec
                  • actor id is a potential owner defined in bpmn - as potential owner is kept as ActorId in work item properties
                  • group id that is rather self explanatory

                   

                  With that in mind, when Task A is entered it creates task instance A (based on Task A), when it is completed engine creates task instance B (based on task B), assuming that approver rejects the task instance A outcome, it will create task instance C (based on Task A), meaning worker that completed task instance A will work on brand new task instance.

                  What I suggested was that instead of going back to Task A (and create task instance based on it for rework) add new Task C that will be dedicated to rework. In general it does not change much in the concept, it simplifies user assignment as it differs based on the process state. Task A and Task B assign users based on groups and task C assigns individual who completed Task A (instances of those tasks).

                   

                  Regarding assignments, yes, you can use process variables to assign users, #{variable}, take a look at the example from my previous post where group id is assigned based on process variable. So that would mean following:

                  • Task A assigns users based on group with #{worker-group} process variable
                  • Task B assigns users based on group with #{approvers} process variable
                  • Task C assigns user based on potential owner with process variable #{TaskA-actualOwner}

                   

                  Does that sound suitable for your case?

                   

                  Hope this time I cleared some things ....

                   

                  Cheers

                  • 6. Re: Trying to set ActorId in On Entry Action - work item is null
                    jemmerling

                    So when trying your suggestions:

                     

                    I tried using a process variable to specify GroupId for a task. I would like to ask whether you have done this successfully; if so, I will try harder! At present it seems to fail. Note this is jBPM 5.2.

                     

                    So the name of the group to which I want to associate this task is "managers". I had specified GroupId as "managers" (without quotes) in the task definition and this worked as expected.

                     

                    I tried using a process variable to specify ActorId. This also clearly worked. Also I believe I found some JUnit test in the source distribution that exercises this.

                     

                    So I changed the GroupId specification to "#{managersGroup}" plus I defined a process variable with this name.

                     

                    To assign a value to this variable, I created a Script Node (that executes right after the process is instantiated) that assigns the value:

                     

                    System.out.println("** ** ** ** ** managers: " + managersGroup + " ** ** ** ** ** ** **");
                    managersGroup = "managers";
                    System.out.println("** ** ** ** ** managers: " + managersGroup + " ** ** ** ** ** ** **");

                     

                    I see the messages written to stdout that indicate the variable has this value assigned.

                     

                    However, when a member of the managers group looks at their task list, it is empty. Setting a breakpoint, I see that when this method in TaskServiceSession is called:

                     

                    public List<TaskSummary> getTasksAssignedAsPotentialOwner(finalString userId, List<String> groupIds, final String language, final int firstResult, int maxResults)

                     

                    groupIds is an empty list (or null, now I forget which).

                     

                    So please just let me know if you have ever gotten this to work. If you have an example, please show how you specified GroupId.

                     

                    Thanks!

                     

                    --JE

                    • 7. Re: Trying to set ActorId in On Entry Action - work item is null
                      jemmerling

                      I posted separately about the GroupId and got a response that led me to making my own example work.

                       

                      As everything else you have said was good, I am marking this question "answered".

                       

                      Cheers!

                       

                      --JE