14 Replies Latest reply on Sep 29, 2016 12:33 PM by richa.khurana

    setActorID for Swimlane in JBPM5

    e3aa3b

      Hi,

       

      How can we dynamically set the actor ID for a Swimlane in JBPM5? Following snippet doesnt persist the information:

       

      =====================

      ProcessInstance pi = ksession.startProcess("com.sample.evaluation1");

                                    Process p = pi.getProcess();

                                    WorkflowProcess wfp = (WorkflowProcess)p;

       

                                    WorkflowProcessInstance wfpi = (WorkflowProcessInstance)pi;

                                    SwimlaneContextInstance slci = (SwimlaneContextInstance)wfpi.getContextInstance(SwimlaneContext.SWIMLANE_SCOPE);

       

                                    SwimlaneContext sc = slci.getSwimlaneContext();

                                    Swimlane s1 = sc.getSwimlane("SL1");

       

                                    s1.setActorId("krisv");

      =====================

       

      Do I need to follow above calls with a persistence call to save the session or something? Any pointers will be really helpful.

       

       

      Thanks

        • 1. Re: setActorID for Swimlane in JBPM5
          swiderski.maciej

          yes, I believe you need to enclose it with Command so it will be executed within transaction and it's status will be persisted. Otherwise you simply change it on a process instance snapshot that is already disconnected and thus does not persist it's state.

           

          HTH

          • 2. Re: setActorID for Swimlane in JBPM5
            e3aa3b

            Thanks Maciej.

             

            By 'Command' do you mean the invocation: ksession.startProcess(<Process_Name>,<params>)? Can you pls refer me to a snippet which maybe helpful in figuring out this problem?

             

            I noticed that in JBPM3 version, there was a way to save the session. A related post in that version: http://web.archiveorange.com/archive/v/AVypsdDazttvKCv1Kk9q

             

            Is there a similar approach possible for JBPM5?

            • 3. Re: setActorID for Swimlane in JBPM5
              swiderski.maciej

              here is how you could define command and execute it on ksession so it gets executed within transaction

              ksession.execute(new GenericCommand<Void>() {
              
                  public Vold execute(Context context) {
              
                      StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
              
                      org.jbpm.process.instance.ProcessInstance processInstance = (org.jbpm.process.instance.ProcessInstance) ksession.getProcessInstance(piId);
              
                      
                        // put your logic here
                  }
              
              });
              

              HTH

              • 4. Re: setActorID for Swimlane in JBPM5
                e3aa3b

                Hi Maciej,

                 

                I tried below, but it still is not able to persist the change:

                 

                <code>

                 

                GenericCommand<Void> genericCommand = new GenericCommand<Void>(){

                                                        public Void execute(Context context){

                 

                                                                  System.out.println("inside execute");

                                                                  StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();

                                                                  ProcessInstance processInstance = ksession.getProcessInstance(pi.getId());

                                                                  WorkflowProcessInstance wfpi = (WorkflowProcessInstance)processInstance;

                                                                  SwimlaneContextInstance slci = (SwimlaneContextInstance)wfpi.getContextInstance(SwimlaneContext.SWIMLANE_SCOPE);

                 

                                                                  SwimlaneContext sc = slci.getSwimlaneContext();

                 

                                                                  Swimlane s1 = sc.getSwimlane("SL1");

                                                                  Swimlane s2 = sc.getSwimlane("SL2");

                 

                                                                  s1.setActorId("krisv");

                                                                  s2.setActorId("mary");

                 

                                                                  //slci.setActorId("SL1", "krisv");

                                                                  //slci.setActorId("SL2", "mary");

                 

                                                                  return null;

                 

                                                        }

                                              };

                 

                                              ksession.execute(genericCommand);

                 

                </code>

                • 5. Re: setActorID for Swimlane in JBPM5
                  swiderski.maciej

                  could you provide bit more details on what you try to do and when do you change the actor on swimlane. Preferably process with test case so I could easily investigate it.

                   

                  Cheers

                  • 6. Re: setActorID for Swimlane in JBPM5
                    e3aa3b

                    Hi Maciej,

                     

                    I am currently trying to work out a POC where I can change the actor on a Swimlane after the process has been started. i.e.

                     

                    ===

                     




                    final ProcessInstance pi = ksession.startProcess("com.sample.evaluation1");

                     

                    ===

                     

                    And then:

                     

                    GenericCommand<Void> genericCommand = new GenericCommand<Void>(){

                    public Void execute(Context context){

                     

                                                                      System.out.println("inside execute");

                                                                      StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();

                                                                      ProcessInstance processInstance = ksession.getProcessInstance(pi.getId());

                                                                      WorkflowProcessInstance wfpi = (WorkflowProcessInstance)processInstance;

                                                                      SwimlaneContextInstance slci = (SwimlaneContextInstance)wfpi.getContextInstance(SwimlaneContext.SWIMLANE_SCOPE);

                     

                                                                      SwimlaneContext sc = slci.getSwimlaneContext();

                     

                                                                      Swimlane s1 = sc.getSwimlane("SL1");

                                                                      Swimlane s2 = sc.getSwimlane("SL2");

                     

                                                                      s1.setActorId("krisv");

                                                                      s2.setActorId("mary");

                     

                    //                                                  WorkflowProcessInstanceUpgrader.upgradeProcessInstance(ksession, processInstance.getId(), "com.sample.evaluation1", null);

                     

                                                                      //slci.setActorId("SL1", "krisv");

                                                                      //slci.setActorId("SL2", "mary");

                     

                                                                      return null;

                     

                                                            }

                                                  };

                     

                    ksession.execute(genericCommand);

                    ================================

                     

                     

                    The intention is that we should be able to dynamically modify/set the actor ID (using setActorID method of Swimlane class).

                     

                     

                    Thanks

                    • 7. Re: setActorID for Swimlane in JBPM5
                      swiderski.maciej

                      just gave it a try on master, here is a test case that uses swimlanes and I added following code to check and change actorId on the swimlane and it worked fine, it was saved. To give that  atry on that test case just replace line 56 with this code

                       

                       

                           ksession.execute(new GenericCommand<Void>(){
                                  public Void execute(Context context){
                                      KieSession ksession = ((KnowledgeCommandContext) context).getKieSession();
                                      ProcessInstance pi = ksession.getProcessInstance(processInstance.getId());
                      
                                      WorkflowProcessInstance wfpi = (WorkflowProcessInstance)pi;
                                      SwimlaneContextInstance slci = (SwimlaneContextInstance)wfpi.getContextInstance(SwimlaneContext.SWIMLANE_SCOPE);
                              
                                      SwimlaneContext sc = slci.getSwimlaneContext();
                              
                                      Swimlane sl = sc.getSwimlane("MyLane");
                                      System.out.println("Before: Current actor id is " + sl.getActorId());
                                      return null;
                                  }});
                              
                              GenericCommand<Void> genericCommand = new GenericCommand<Void>(){
                                  public Void execute(Context context){
                                      KieSession ksession = ((KnowledgeCommandContext) context).getKieSession();
                                      ProcessInstance pi = ksession.getProcessInstance(processInstance.getId());
                      
                                      WorkflowProcessInstance wfpi = (WorkflowProcessInstance)pi;
                                      SwimlaneContextInstance slci = (SwimlaneContextInstance)wfpi.getContextInstance(SwimlaneContext.SWIMLANE_SCOPE);
                              
                                      SwimlaneContext sc = slci.getSwimlaneContext();
                              
                                      Swimlane sl = sc.getSwimlane("MyLane");
                                      System.out.println("Command: Current actor id is " + sl.getActorId());
                                      sl.setActorId("mary");
                                      
                                      return null;
                                  }
                              };
                              ksession.execute(genericCommand);
                              // simulating a system restart
                              ksession = restoreSession(ksession, true);
                              
                              ksession.execute(new GenericCommand<Void>(){
                                  public Void execute(Context context){
                                      KieSession ksession = ((KnowledgeCommandContext) context).getKieSession();
                                      ProcessInstance pi = ksession.getProcessInstance(processInstance.getId());
                      
                                      WorkflowProcessInstance wfpi = (WorkflowProcessInstance)pi;
                                      SwimlaneContextInstance slci = (SwimlaneContextInstance)wfpi.getContextInstance(SwimlaneContext.SWIMLANE_SCOPE);
                              
                                      SwimlaneContext sc = slci.getSwimlaneContext();
                              
                                      Swimlane sl = sc.getSwimlane("MyLane");
                                      System.out.println("After: Current actor id is " + sl.getActorId());
                                      return null;
                                  }});
                      
                      

                      HTH

                      • 8. Re: setActorID for Swimlane in JBPM5
                        e3aa3b

                        Thanks Maciej,

                         

                        If I try above example, the actor ID for the swimlane gets printed fine.

                         

                        However, the task in that Swimlane still doesnt show up in the user queue. i.e. if I set the actor ID to 'mary', the task still doesnt show up in mary's queue. Infact, I dont see the task anywhere (it's not present in any of the configured user's queue).

                        • 9. Re: setActorID for Swimlane in JBPM5
                          swiderski.maciej

                          first of all why do you want to set it manually? swimlane will ensure that all tasks will be assigned to the same actor who was assigner to the first task. So no need to manage that yourself.

                          • 10. Re: setActorID for Swimlane in JBPM5
                            e3aa3b

                            Hi Maciej,

                             

                            The issue that I am facing is that actor is not assigned even the first time. i.e. when the process gets started, the task is not assigned to anyone (since the actor ID and group ID is not set and the same is not passed as a parameter to the start Process). Hence even though the Process gets started, it doesnt show up in any user's queue.

                             

                            To summarize, I want that the task should show up in a user (say Mary's queue) for tasks belonging to Swimlane1 and to another user's queue (say krisv's queue) for tasks belonging to Swimlane2.

                             

                            One of the ways to do that is by using process variable and then setting them before Process instantiation and things work fine in that case. However, if I dont follow Process Variable approach and would like to dynamically assign the Swimlane to an actor using (setActorID API), the task doesn't show up in any user's queue (even though I have set it using setActorID API to krisv/mary).

                             

                             

                            Thanks

                            • 11. Re: setActorID for Swimlane in JBPM5
                              swiderski.maciej

                              I believe that you try to set something on swimlane after task was created and thus change on swimlane does not affect the task any more. What I would suggest here is to assign that to a group, then one of the actors claim it and subsequent tasks will get automatically assigned to the same user. This is how swimlane is used on runtime.

                               

                              HTH

                              • 12. Re: setActorID for Swimlane in JBPM5
                                e3aa3b

                                Thanks Maciej. Yes, that's one possible way to do it.

                                 

                                Under what scenario(s) is setActorID API useful?

                                • 13. Re: setActorID for Swimlane in JBPM5
                                  garethed

                                  Hi,

                                   

                                  Do swimlanes work with groups?

                                   

                                  I have a task that is available to two groups. I would like all tasks in the workflow assigined to the the user that claims the first task.

                                  No actor is specified in the tasks, just groups.

                                   

                                  Gareth.

                                  • 14. Re: setActorID for Swimlane in JBPM5
                                    richa.khurana

                                    Hi,

                                     

                                    I have a similar problem and i want to be able to setActorId to a swimlane. I tried with the GenericCommand with sample code above; the actorId doesnt get persisted with the swimlane. Also tried to lookup the sample code as per the link https://github.com/droolsjbpm/jbpm/blob/master/jbpm-test/src/test/java/org/jbpm/ProcessPersistenceHumanTaskOnLaneTest.ja…  but I receive 404 Not found.

                                     

                                    It will be really helpful if you could kindly let me know how to proceed here as I am stuck with this piece. Another problem with the code is that swimlane actor is being stored with Process and not the process Instance. So with code below, I get same context across 2 separate objects/expected as separate invocations to processInstance.

                                     

                                    SwimlaneContext swimlaneContext = (SwimlaneContext)((RuleFlowProcess)processInstance.getProcess()).getDefaultContext(SwimlaneContext.SWIMLANE_SCOPE);

                                            Swimlane swimlane = swimlaneContext.getSwimlaneContext().getSwimlane(swimlaneName);

                                     

                                     

                                     

                                    Thanks,

                                    Richa