bbarani (8) [Avatar] Offline
#1
I am using Activiti REST api to create a process. I also have created some forms (using formProperty) in my process. Everything seems fine except for the fact that when the custom form is approved, the task is not archived. Is there a way by which I can force the task to get archived?

Please find below my process definition file...

<startEvent id="theStart" activiti:initiator="initiator" />

<sequenceFlow id="flow1" sourceRef="theStart" targetRef="needsApprovalTask" />

<serviceTask id="needsApprovalTask" name="Needs approval" >
activiti:class="com.picturerequest.NeedsApprovalDelegate" />

<sequenceFlow id="flow2" sourceRef="needsApprovalTask" >
targetRef="gateway" />

<exclusiveGateway id="gateway" name="Needs approval?" />

<sequenceFlow id="flow3" sourceRef="gateway" targetRef="confirmApproval">
<conditionExpression xsi:type="tFormalExpression">${needsApproval}
</conditionExpression>
</sequenceFlow>

<sequenceFlow id="flow4" sourceRef="gateway" targetRef="chargeAccount">
<conditionExpression xsi:type="tFormalExpression">${!needsApproval}
</conditionExpression>
</sequenceFlow>

<userTask id="confirmApproval" name="Approve the picture request" >
activiti:assignee="${user}">
<extensionElements>
<activiti:formProperty id="test3" name="Initiator:" >
expression="${initiator}" writable="false" type="string" />

<activiti:formProperty id="test3" name="Description:" >
expression="${description}" readable="true" writable="false" type="string" />

<activiti:formProperty id="test" name="User:" >
expression="${user}" writable="false" type="string" />

<activiti:formProperty id="test2" name="Image:" >
expression="${imageName}" writable="false" type="string" />

<activiti:formProperty id="approvalConfirmed" >
name="approvalConfirmed" type="enum" required="true">
<activiti:value id="true" name="Yes"></activiti:value>
<activiti:value id="false" name="No"></activiti:value>
</activiti:formProperty>
</extensionElements>
</userTask>

<sequenceFlow id="flow5" sourceRef="confirmApproval" >
targetRef="gateway2" />

<exclusiveGateway id="gateway2" name="Is approval confirmed?" />

<sequenceFlow id="flow6" sourceRef="gateway2" targetRef="chargeAccount">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvalConfirmed == 'true'}]]></conditionExpression>
</sequenceFlow>

<sequenceFlow id="flow7" sourceRef="gateway2" targetRef="theEnd">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvalConfirmed == 'false'}]]></conditionExpression>
</sequenceFlow>

<serviceTask id="chargeAccount" name="Charge account" >
activiti:class="com.picturerequest.ChargeDelegate">
<extensionElements>
<activiti:field name="wsdl" >
expression="http://localhost:8291/chargeService?wsdl" />
<activiti:field name="operation" expression="chargeAccount" />
<activiti:field name="parameters" expression="${user}, ${imageName}" />
<activiti:field name="returnValue" expression="myReturn" />
</extensionElements>
</serviceTask>

<sequenceFlow id="flow8" sourceRef="chargeAccount" >
targetRef="theEnd" />
<endEvent id="theEnd" />
tijs.rademakers (494) [Avatar] Offline
#2
Re: Task is not getting archived when using Activiti-REST API
Hi,

What do you mean with "the task is not archived" ?

Best regards,

Tijs
bbarani (8) [Avatar] Offline
#3
Re: Task is not getting archived when using Activiti-REST API
In general when a task is closed, the task is getting archived ( you can view the details of the closed tasks by clicking the archive tab in activiti explorer) but whenever I use form in activiti and close a task (using a form), the closed tasks are not getting archived (Archive tab always shows 0).
bbarani (8) [Avatar] Offline
#4
Re: Task is not getting archived when using Activiti-REST API
In general when a task is closed, the task is getting archived ( you can view the details of the closed tasks by clicking the archive tab in activiti explorer) but whenever I use form in activiti and close a task (using a form), the closed tasks are not getting archived (Archive tab always shows 0).
tijs.rademakers (494) [Avatar] Offline
#5
Re: Task is not getting archived when using Activiti-REST API
This is the query that's being executed for the archived list:

historyService.createHistoricTaskInstanceQuery().taskOwner(userId).finished()

The taskOwner is not set by default so that's probably the issue.

Best regards,

Tijs
bbarani (8) [Avatar] Offline
#6
Re: Task is not getting archived when using Activiti-REST API
I tried to invoke a method from activiti sequence flow but I am getting the below error,

<sequenceFlow id="finalTask" name="finalTask" sourceRef="chargeAccount" targetRef="theEnd">
<extensionElements>
<activiti:executionListener >
expression="${EscalationListener.escalate(execution, 'kermit')}"
event="end" />
</extensionElements>
</sequenceFlow>

Error:

Caused by: org.activiti.engine.impl.javax.el.PropertyNotFoundException: Cannot resolve identifier 'EscalationListener' at org.activiti.engine.impl.juel.AstIdentifier.eval(AstIdentifier.java:8

Java code:

import org.activiti.engine.HistoryService;
import org.activiti.engine.delegate.DelegateExecution;

public class EscalationListener {
HistoryService historyService;

public void escalate(DelegateExecution execution, String otherTaskId)
throws Exception {

historyService.createHistoricTaskInstanceQuery().taskOwner(otherTaskId)
.finished();

}

}

Is there a different way to set owner of the task (directly in bpm xml, something like activiti:assignee="${user})?

Thanks,
Barani
tijs.rademakers (494) [Avatar] Offline
#7
Re: Task is not getting archived when using Activiti-REST API
Did you define EscalationListener as a Spring bean? Because that's needed if you use the expression attribute. If you want to invoke it as a Java class then you need to use the class attribute.
No you can't set the owner of a task directly in the BPMN XML. But this would be a valid feature request, so you could raise a JIRA for this.

Best regards,

Tijs
bbarani (8) [Avatar] Offline
#8
Re: Task is not getting archived when using Activiti-REST API
Hi,

Thanks for your reply. I am able to archive the task now using the below code but the custom form properties (in user task) are not getting archived. Is there any other method I need to call to archive those form properties?

public class ArchiveTask implements org.activiti.engine.delegate.JavaDelegate
{
public void execute(DelegateExecution execution) throws Exception {
String assigneeName = (String) execution.getVariable("user");
TaskService taskService = execution.getEngineServices()
.getTaskService();
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee(assigneeName).list();
for (Task task : tasks) {
task.setOwner(assigneeName);

}

}
}
tijs.rademakers (494) [Avatar] Offline
#9
Re: Task is not getting archived when using Activiti-REST API
Hi,

For the form properties to be stored in the history tables you need 2 things:

1. Use the FormService submitTaskFormData method to complete a task and not the TaskService complete method.
2. The history level should be set to at least audit level (this is the default level)

Best regards,

Tijs
bbarani (8) [Avatar] Offline
#10
Re: Task is not getting archived when using Activiti-REST API
Thanks for your response..I am getting multiple errors when I try to submit my task form.

I have a simple workflow as below (with 2 form property)

<process id="pictureRequestNew" name="Testing Complex Approval process">

<startEvent id="theStart" activiti:initiator="initiator" />

<sequenceFlow id="flow1" sourceRef="theStart" targetRef="needsApprovalTask" />

<serviceTask id="needsApprovalTask" name="Needs approval" >
activiti:class="com.picturerequest.NeedsApprovalDelegate" />

<sequenceFlow id="flow2" sourceRef="needsApprovalTask" >
targetRef="gateway" />

<exclusiveGateway id="gateway" name="Needs approval?" />

<sequenceFlow id="flow3" sourceRef="gateway" targetRef="confirmApproval">
<conditionExpression xsi:type="tFormalExpression">
${needsApproval}
</conditionExpression>
</sequenceFlow>

<sequenceFlow id="flow4" sourceRef="gateway" targetRef="Email">
<conditionExpression xsi:type="tFormalExpression">
${!needsApproval}
</conditionExpression>
</sequenceFlow>

<userTask id="confirmApproval" name="Approve the picture request" >
activiti:candidateUsers="${user}" activiti:assignee="${user}">
<extensionElements>

<activiti:formProperty id="initiator" name="Initiator:" >
type="string" />
<activiti:formProperty id="approvalConfirmed" >
name="approvalConfirmed" type="enum" required="true">
<activiti:value id="true" name="Yes"></activiti:value>
<activiti:value id="false" name="No"></activiti:value>
</activiti:formProperty>
</extensionElements>
</userTask>


<sequenceFlow id="flow5" sourceRef="confirmApproval" >
targetRef="gateway2" />

<exclusiveGateway id="gateway2" name="Is approval confirmed?" />

<sequenceFlow id="flow6" sourceRef="gateway2" targetRef="chargeAccount">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvalConfirmed == 'true'}]]></conditionExpression>
</sequenceFlow>

<sequenceFlow id="flow7" sourceRef="gateway2" targetRef="ArchiveTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvalConfirmed == 'false'}]]></conditionExpression>
</sequenceFlow>

<serviceTask id="Email" name="Email Service" >
activiti:class="com.picturerequest.ChargeDelegate">
<extensionElements>
<activiti:field name="wsdl" >
expression="http://localhost:8521/mailService?wsdl" />
<activiti:field name="operation" expression="chargeAccount" />
<activiti:field name="parameters" expression="${user}, ${imageName}" />
<activiti:field name="returnValue" expression="myReturn" />
</extensionElements>
</serviceTask>

<serviceTask id="chargeAccount" name="Charge account" >
activiti:class="com.picturerequest.ChargeDelegate">
<extensionElements>
<activiti:field name="wsdl" >
expression="http://localhost:8291/chargeService?wsdl" />
<activiti:field name="operation" expression="chargeAccount" />
<activiti:field name="parameters" expression="${user}, ${imageName}" />
<activiti:field name="returnValue" expression="myReturn" />
</extensionElements>
</serviceTask>

<sequenceFlow id="flow10" sourceRef="chargeAccount" >
targetRef="ArchiveTask" />

<sequenceFlow id="flow13" sourceRef="Email" targetRef="theEnd" />

<serviceTask id="ArchiveTask" name="serviceTask" >
activiti:class="com.picturerequest.ArchiveTask">
</serviceTask>

<sequenceFlow id="flow8" sourceRef="ArchiveTask" >
targetRef="theEnd" />

<endEvent id="theEnd" />

</process>


My Java class:

public class ArchiveTask implements org.activiti.engine.delegate.JavaDelegate

{
public void execute(DelegateExecution execution) throws Exception {
Map<String, String> properties = new HashMap<String, String>();

String assigneeName = (String) execution.getVariable("user");
boolean approval = (Boolean) execution.getVariable("needsApproval");
TaskService taskService = execution.getEngineServices()
.getTaskService();
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee(assigneeName).list();
for (Task task : tasks) {
task.setOwner(assigneeName);

}

ProcessDefinition definition = execution.getEngineServices().getRepositoryService()
.createProcessDefinitionQuery().processDefinitionKey("pictureRequestNew").singleResult();

FormService formService = execution.getEngineServices()
.getFormService();

List<FormProperty> formList = formService.getStartFormData(definition.getId()).getFormProperties();

System.out.println(formList.size()+" Form List size");
System.out.println(definition.getId()+" Definition Id ");

try {
properties = new HashMap<String, String>();
properties.put("initiator", "kermit");
properties.put("approvalConfirmed", "Yes");
formService.submitTaskFormData(definition.getId(), properties);
} catch (ActivitiException e) {

}


}
}


This list ---> List<FormProperty> formList = formService.getStartFormData(definition.getId()).getFormProperties(); is always 0.

Can you please let me know where I am wrong?

Thanks,
Barani