alfrescoactivitiaps

Activiti and candidate groups


In APS 1.8.1, I have defined a process where each task has a candidate group.

When I login in with a user that belongs to a candidate group, I cannot see the process instance.

I have found out that when I try to access the process instances, APS executes the following query in the database:

select distinct RES.* , DEF.KEY_ as PROC_DEF_KEY_, DEF.NAME_ as PROC_DEF_NAME_, DEF.VERSION_ as PROC_DEF_VERSION_, DEF.DEPLOYMENT_ID_ as DEPLOYMENT_ID_
    from ACT_HI_PROCINST RES
    left outer join ACT_RE_PROCDEF DEF on RES.PROC_DEF_ID_ = DEF.ID_
        left join ACT_HI_IDENTITYLINK I_OR0 on I_OR0.PROC_INST_ID_ = RES.ID_
     WHERE  RES.TENANT_ID_ = 'tenant_1'
        and 
        (  (
              exists(select LINK.USER_ID_ from ACT_HI_IDENTITYLINK LINK where USER_ID_ = '1003' and LINK.PROC_INST_ID_ = RES.ID_)
            )
            or (
              I_OR0.TYPE_ = 'participant'
              and
              I_OR0.GROUP_ID_ IN ('1','2','2023','2013','2024','2009','2025','2026','2027','2028','2029','2007','2018','2020','2017','2015','2012','2003','2021','2019','2004','2002','2005','2030','2031','2032','2011','2006','2008','2014','2010','2016','2022','2033','2034','2035','2036','2037','1003')
            ) ) 
     order by RES.START_TIME_ desc 
    LIMIT 50 OFFSET 0

This query does not return any record for two reasons:

  1. In my ACT_HI_IDENTITYLINK no tasks have both the group_id_ and the proc_inst_id_ set.
  2. The type of the record is "candidate" but the query is looking for "participant"

    select * fro m ACT_HI_IDENTITYLINK;
    -[ RECORD 1 ]-+----------
    id_           | 260228
    group_id_     | 
    type_         | starter
    user_id_      | 1002
    task_id_      | 
    proc_inst_id_ | 260226
    -[ RECORD 2 ]-+----------
    id_           | 260294
    group_id_     | 2006
    type_         | candidate
    user_id_      | 
    task_id_      | 260293
    proc_inst_id_ | 
    -[ RECORD 3 ]-+----------
    id_           | 260300
    group_id_     | 2009
    type_         | candidate
    user_id_      | 
    task_id_      | 260299
    proc_inst_id_ | 
    -[ RECORD 4 ]-+----------
    id_           | 262503
    group_id_     | 
    type_         | starter
    user_id_      | 1002
    task_id_      | 
    proc_inst_id_ | 262501
    -[ RECORD 5 ]-+----------
    id_           | 262569
    group_id_     | 2016
    type_         | candidate
    user_id_      | 
    task_id_      | 262568
    proc_inst_id_ | 
    -[ RECORD 6 ]-+----------
    id_           | 262575
    group_id_     | 2027
    type_         | candidate
    user_id_      | 
    task_id_      | 262574
    proc_inst_id_ | 
    

Why the query is looking only for "participant" and why the records that have type_ = 'candidate' do not have any proc_inst_id_ set ?

UPDATE: The problem with the constraint "participant" has a simple workaround: it would be enough to add the same candidate group as a participant. See also Feature allowing "Participant" configuration in BPM Modeler

Unfortunately this is not enough to solve the second problem. The record is still not returned because the column proc_inst_id_ is not set.

I tried to update the column manually on the "participant" record and I have verified that doing so the page is accessible and works well.

Does anyone know why the column is not set ?


Solution

  • A possible solution (or workaround until ACTIVITI-696 is fixed) is to add each group added as candidate to a task as a participant of the process instance.

    There is a REST API that does it:

    POST /enterprise/process-instances/{processInstanceId}/identitylinks
    

    What this API does should be done by a task listener that will automatically add the candidate groups of the created task as participant of the process instance.

    To add the new identity link, use in the listener the following lines:

    ActivitiEntityEvent aee = (ActivitiEntityEvent)activitiEvent;
    TaskEntity taskEntity = (TaskEntity)aee.getEntity();
    List<IdentityLinkEntity> identities = taskEntity.getIdentityLinks();
    if (identities != null) {
        for (IdentityLinkEntity identityLinkEntity : identities) {
            String groupId = identityLinkEntity.getGroupId();
            runtimeService.addGroupIdentityLink(activitiEvent.getProcessInstanceId(), groupId, "participant");
        };
    }