11 Replies Latest reply on Oct 12, 2005 9:44 AM by kukeltje

    Using groups and swimlanes

      Hi,

      I am trying to use a group in a swim lane but when I execute the app through the web it says that the assignee is null. Am I using the wrong syntax. Also, where would I find the latest JPDL syntax. I remember the syntax was explained very well for version JBPM ver1 but the ver 3.0 documentation is not as detailed. The group Agents has two members Agent1 and Agent2.

      <?xml version="1.0" encoding="UTF-8"?>
      <process-definition name="MyProcess">
       <!-- SWIMLANES (= process roles) -->
       <swimlane name="buyer" />
      
       <swimlane name="Agents">
       <assignment expression="group(Agents)" />
       </swimlane>
      
       <start-state name="create new process">
       <task swimlane="buyer">
       <controller>
       <variable name="CustomerName" />
       <variable name="Address" />
       </controller>
       </task>
       <transition to="Evaluate" />
       </start-state>
      
       <task-node name="Evaluate">
       <task swimlane="Agents">
       <controller>
       <variable name="CustomerName" />
       <variable name="Address" access="write"/>
       </controller>
       </task>
       <transition to="end" />
       </task-node>
      
       <end-state name="end" />
      </process-definition>
      

      This is the content of my identity.db.xml
      <identity>
       <user name="cookie monster" email="cookie.monster@sesamestreet.tv" password="crunchcrunch" />
       <user name="ernie" email="ernie@sesamestreet.tv" password="canthereyoubert,theresabananainmyear" />
       <user name="bert" email="bert@sesamestreet.tv" password="ernie,theresabananainyourear" />
       <user name="grover" email="grover@sesamestreet.tv" password="mayday mayday" />
       <user name="Agent1" email="agent1@sesamestreet.tv" password="Agent1" />
       <user name="Agent2" email="agent2@sesamestreet.tv" password="Agent2" />
       <group name="Agents" />
       <membership user="Agent1" group="Agents" />
       <membership user="Agent2" group="Agents" />
      </identity>
      

      My second question is - how do I specify variables of type date, boolean etc in the processdefinition.xml

      thanks
      Neal

        • 1. Re: Using groups and swimlanes

          If you're using the starter-kit web app it's normal, I think it doesn't managed pooled actors.


          Regards,
          David

          • 2. Re: Using groups and swimlanes

            I implemented a test case for the process and executed it using junit but I am seeing the same problem. It does not seem to be a webapp related limitation.

            I also looked at the code for the Pooled actors and it does not seem to be resolving the users from the group.

            I am inclined to believe that I am missing something since this is a very basic requirement for any process.

            thanks
            Neal

            • 3. Re: Using groups and swimlanes
              icyjamie

              How should the engine know which user to choose from the group? Round-robin? Skill-based? Workloadbased?

              It is possible to write an assignmentHandler for this.

              You could also try to use the assignment expressions explained in 9.9.2

              • 4. Re: Using groups and swimlanes
                stembol

                Do we need to write an assignementHandler for this?

                I expected that the task will be visible for all users in the group. Then when one user selects the task, you have to set the actorId of the taskInstance and thus set the responsible for the task.

                Am I wrong?

                • 5. Re: Using groups and swimlanes
                  stembol

                  I'm a little bit confused: in PooledActor, actorId is the group name specified in expression=group(...)
                  I was thinking actorId was one of the user from the group???

                  • 6. Re: Using groups and swimlanes
                    brittm

                    JBPM's engine really doesn't have any internal distinction between our concept of "user" and "group" that I'm aware of. When we set the actorId in PooledActor, that could be a group or an individual user--jbpm doesn't care. It is the responsibility of an "organization management" piece to make that determination and handle it in the UI appropriately (JBPM comes with such a piece for demonstration and development use, but it's not currently robust, and most enterprises will use their own existing database or LDAP tree).

                    You will know the user who is logged in, and you should be able to look up all the groups to which he belongs (pools) in whichever user/group database you're using. Calling taskMgmtSession.findTaskInstances(userName) returns all tasks assigned to your user, and calling taskMgmtSession.findPooledTaskInstances(groupName) should find all tasks with an association to the named "pooledActor" (group) that has been set.

                    If I don't try anything fancy, and use an AssignmentHandler, everything works fine for me. We use Active Directory for organization data rather than JBPM's built in piece, so I haven't tried to make assignments with "expressions".

                    However, there are some issues with pooled actor assignments that haven't been completely worked out yet:
                    http://www.jboss.com/index.html?module=bb&op=viewtopic&t=69980
                    http://jira.jboss.com/jira/browse/JBPM-375
                    http://jira.jboss.com/jira/browse/JBPM-378
                    http://jira.jboss.com/jira/browse/JBPM-395

                    If you're experiencing problems, you might want to check these links and see if what you're doing falls into any of those issues.

                    -Britt

                    • 7. Re: Using groups and swimlanes
                      stembol

                      Thank you Britt for your response.

                      I have still one question concerning users and roles.:
                      I would like to set 'start' privileges i.e. filter the list of process definitions to start based on the user's privileges.

                      graphSession.findLatestProcessDefinitions();


                      I see that we can specify a swimlane with the start task:

                      <swimlane name="role-start" >
                       <assignment expression="group(aisi)" />
                       </swimlane>

                      <start-state name="launch">
                       <task swimlane="role-start"><controller/></task>
                      ...
                      </start-state>


                      and then try to get the assignment:

                      Task startTask = processDefinition.getTaskMgmtDefinition().getStartTask();
                      Delegation delegation = startTask.getAssignmentDelegation();


                      but delegation is null since the start task is not created yet.

                      Could you please tell me how I can filter the list of process definitions?

                      • 8. Re: Using groups and swimlanes
                        brittm

                        All of JBPM's swimlane assignments are completely "internal" to each executing process. To control who can start a process, I believe you will need to create your own mechanism by handling those "initiator" roles/privilidges entirely in your UI.

                        If you wanted to, you could probably specify a swimlane name based on an actual user group, such as "sales_agent", and then assign that swimlane to a processes definition's Start task. You would then likely have to write a Hibernate query to return all processes definitions that have a Start state with a Task assigned to a Swimlane who's name is the same as one of the groups to which your user belongs. This is something of a hack, and it requires you to use a Task in the Start state of each process, but it might work for you.

                        -Britt

                        • 9. Re: Using groups and swimlanes
                          stembol

                          Thanks Britt--

                          For those who are interested in the solution:

                          /**
                           * Checks if the actor is authorized to start the process.
                           *
                           * @param userRole the user role
                           * @return boolean
                           */
                           public boolean hasStartPermission(String[] userRoles) {
                          
                           final String localMethodName = Process.class.getName()
                           + ".hasStartPermission(String[] userRoles)";
                          
                           if (userRoles == null)
                           return false;
                          
                           Task startTask = processDefinition.getTaskMgmtDefinition().getStartTask();
                           Swimlane swimlane = startTask.getSwimlane();
                          
                           if (swimlane == null && swimlane.getName() == null)
                           return false;
                          
                           for (int i = 0; i < userRoles.length; i++) {
                           if (userRoles == null)
                           continue;
                           if (userRoles.equalsIgnoreCase(swimlane.getName()))
                           return true;
                           }
                          
                           return false;
                          
                           }


                          • 10. Re: Using groups and swimlanes
                            stembol

                            Better version

                            /**
                             * Checks if the actor is authorized to start the process.
                             * <p>
                             * The actor is authorized if he belongs to a group specified in the
                             * swimlane relative to the start task.
                             *
                             * @param userRoles the list of roles
                             * @return boolean
                             */
                             public boolean hasStartPermission(String[] userRoles) {
                            
                             final String localMethodName = Process.class.getName()
                             + ".hasStartPermission(String[] userRoles)";
                            
                             if (userRoles == null)
                             return false;
                            
                             Task startTask = processDefinition.getTaskMgmtDefinition().getStartTask();
                             Swimlane swimlane = startTask.getSwimlane();
                            
                             if (swimlane == null || swimlane.getName() == null)
                             return false;
                            
                             Delegation delegation = swimlane.getAssignmentDelegation();
                             String expression = delegation.getConfiguration();
                            
                             int start = expression.indexOf("group(");
                             int end = expression.indexOf(")", start);
                            
                             String group = null;
                             if (start > 0 && end > start)
                             group = expression.substring(start+6, end);
                            
                             for (int i = 0; group != null && i < userRoles.length; i++) {
                             if (userRoles == null)
                             continue;
                             if (userRoles.equalsIgnoreCase(group))
                             return true;
                             }
                            
                             return false;
                            
                             }


                            • 11. Re: Using groups and swimlanes
                              kukeltje

                              I'll add this to the default webapp. Lots of additions comming up.