cancel
Showing results for 
Search instead for 
Did you mean: 

Bug in workflowService.getTaskDefinitions?

arnoldschrijve1
Champ on-the-rise
Champ on-the-rise
I am using CE 4.0.b and noticed what looks like a bug in using the workflowService to retrieve the WorkflowTaskDefinition of a task defined as multi-instance in the BPMN workflow definition.

The problem occurs when using the workflow service and calling workflowService.getTaskDefinitions(workflowDefinitionId) on the workflow. Returned results for the multi-instance tasks are incorrect.

During the construction of the returned list, when encountering the multi-instance task it first goes wrong in ActivitiWorkflowEngine.getFormKey() because the task does not derive from UserTaskActivityBehavior (it instead derives from ).
The formkey is set to the localname of the type (variable startId) and there is another chance for a namespace prefix to be looked up in WorkflowObjectFactory.getTaskTypeDefinition(). However, the qNameConverter doesn’t resolve the namespace.
You'll get a 'type not found' warning in the logs (from DictionaryDAOImpl.getType). The WorkflowObjectFactory will now fall back to the defaultStartType (activitiStartTask) instead.

I created a sample project that demonstrates the issue (can't include it to this post). Here are some code fragments:

The activity bpmn should have a multi-instance task e.g. like in the standard Parallel Review and Approve workflow:


        <userTask id="reviewTask" name="Review Task"
            activiti:formKey="wf:activitiReviewTask">
           <extensionElements>
               <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
                  <activiti:field name="script">
                     <activiti:string>
                        if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate
                        if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
                     </activiti:string>
                  </activiti:field>
               </activiti:taskListener>
               <activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
                  <activiti:field name="script">
                     <activiti:string>
                        if(task.getVariableLocal('wf_reviewOutcome') == 'Approve') {
                             var newApprovedCount = wf_approveCount + 1;
                             var newApprovedPercentage = (newApprovedCount / wf_reviewerCount) * 100;
                            
                             execution.setVariable('wf_approveCount', newApprovedCount);
                             execution.setVariable('wf_actualPercent', newApprovedPercentage);
                        }
                     </activiti:string>
                  </activiti:field>
               </activiti:taskListener>
           </extensionElements>
          
           <humanPerformer>
                <resourceAssignmentExpression>
                    <formalExpression>${reviewAssignee.properties.userName}</formalExpression>
                </resourceAssignmentExpression>
           </humanPerformer>
          
           <!– For each assignee, task is created –>
           <multiInstanceLoopCharacteristics isSequential="false">
              <loopDataInputRef>bpm_assignees</loopDataInputRef>
              <inputDataItem name="reviewAssignee" />
              <completionCondition>${wf_actualPercent >= wf_requiredApprovePercent}</completionCondition>
           </multiInstanceLoopCharacteristics>
        </userTask>

And then create a java-backed webscript to get to the task definitions:


   @Override
   protected Map<String, Object> executeImpl(WebScriptRequest req, Status status) {
      
      Map<String, Object> model = new HashMap<String, Object>();
      
      // Original version of parallel review task
      String workflowDefinitionId = "activiti$activitiParallelReview:1:16";
      
      // Copy of parallel review task but now in SomeCo namespace.
      //String workflowDefinitionId = "activiti$activitiParallelReview:2:4310";
      
      // Look up the id in the workflow console.
      WorkflowDefinition definition = workflowService.getDefinitionById(workflowDefinitionId);   
      
      if (definition != null) {
          List<WorkflowTaskDefinition> tasks = workflowService.getTaskDefinitions(definition.getId());
          List<String> taskIds = new LinkedList<String>();
          for (WorkflowTaskDefinition task : tasks) {
              taskIds.add(task.getId());
          }
         
          model.put("taskIds", taskIds);
      }

      return model;
   }

A simple ftl like this:


<#escape x as jsonUtils.encodeJSONString(x)>
{
    "tasks":
    [
       <#list taskIds as taskId>      
            "${taskId}"<#if taskId_has_next>,</#if>
       </#list>
    ]
}
</#escape>

results in this output:


{
    "tasks":
    [      
            "wf:submitParallelReviewTask",      
            "reviewTask",      
            "wf:approvedParallelTask", 
            "wf:rejectedParallelTask"      
    ]
}

If this is indeed a bug I will create an issue in the Jira…
2 REPLIES 2

arnoldschrijve1
Champ on-the-rise
Champ on-the-rise
I created a JIRA issue for this at https://issues.alfresco.com/jira/browse/ALF-14224

arnoldschrijve1
Champ on-the-rise
Champ on-the-rise
Wow, the issue was resolved and fixed immediately (fix version 4.0.3, revision 36719). Thank you Frederik Heremans!
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.