Hello friends,
in our software we search in the hi_actinst table for some activities and sometimes we need to check (against the endtime) for a completed usertask. But this week we discovered a strange behavior:
if we send a message to usertask (with messageEventReceived) the endtime is set to the activities - we think thats not correct but we dont know exactly
So i made a simple BPMN and a testcase for you to check that behavior.
I hope you can help me with that - currently we got a workaround, so the bug is not critical for us
the test BPMN
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.5.1">
<bpmn:process id="endTimeBugTestBPMN" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>SequenceFlow_05264a4</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="SequenceFlow_05264a4" sourceRef="StartEvent_1" targetRef="Task_0r58ed8" />
<bpmn:endEvent id="EndEvent_0ho3g0v">
<bpmn:incoming>SequenceFlow_1jav8nl</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="SequenceFlow_1jav8nl" sourceRef="Task_0r58ed8" targetRef="EndEvent_0ho3g0v" />
<bpmn:endEvent id="EndEvent_0eicala">
<bpmn:incoming>SequenceFlow_1fo7atn</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="SequenceFlow_1fo7atn" sourceRef="BoundaryEvent_16bcjdl" targetRef="EndEvent_0eicala" />
<bpmn:userTask id="Task_0r58ed8" name="Testtask">
<bpmn:incoming>SequenceFlow_05264a4</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_1jav8nl</bpmn:outgoing>
</bpmn:userTask>
<bpmn:boundaryEvent id="BoundaryEvent_16bcjdl" cancelActivity="false" attachedToRef="Task_0r58ed8">
<bpmn:outgoing>SequenceFlow_1fo7atn</bpmn:outgoing>
<bpmn:messageEventDefinition messageRef="Message_0avzdxe" />
</bpmn:boundaryEvent>
</bpmn:process>
<bpmn:message id="Message_0avzdxe" name="Message_0mqt7n0" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="endTimeBugTestBPMN">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="173" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_05264a4_di" bpmnElement="SequenceFlow_05264a4">
<di:waypoint xsi:type="dc:Point" x="209" y="120" />
<di:waypoint xsi:type="dc:Point" x="275" y="120" />
<bpmndi:BPMNLabel>
<dc:Bounds x="242" y="105" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_0ho3g0v_di" bpmnElement="EndEvent_0ho3g0v">
<dc:Bounds x="443" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="461" y="138" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1jav8nl_di" bpmnElement="SequenceFlow_1jav8nl">
<di:waypoint xsi:type="dc:Point" x="375" y="120" />
<di:waypoint xsi:type="dc:Point" x="443" y="120" />
<bpmndi:BPMNLabel>
<dc:Bounds x="409" y="105" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_0eicala_di" bpmnElement="EndEvent_0eicala">
<dc:Bounds x="318" y="231" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="336" y="267" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1fo7atn_di" bpmnElement="SequenceFlow_1fo7atn">
<di:waypoint xsi:type="dc:Point" x="336" y="178" />
<di:waypoint xsi:type="dc:Point" x="336" y="231" />
<bpmndi:BPMNLabel>
<dc:Bounds x="351" y="204.5" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="UserTask_0wgrwlf_di" bpmnElement="Task_0r58ed8">
<dc:Bounds x="275" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BoundaryEvent_13pb3ld_di" bpmnElement="BoundaryEvent_16bcjdl">
<dc:Bounds x="318" y="142" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="336" y="178" width="0" height="0" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
Junit Testclass with some comments:
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.Optional;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.h2.tools.Server;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
public class EndTimeBugTest {
private static Server h2Server = null;
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
public EndTimeBugTest() {
activitiRule.setConfigurationResource("/resources/activiti.cfg.xml");
}
@Test
@Deployment(resources = { "de/gad/zkm/bpmn/BugDiagram.bpmn" })
public void test() {
RuntimeService rs = activitiRule.getRuntimeService();
TaskService ts = activitiRule.getTaskService();
HistoryService hs = activitiRule.getHistoryService();
// Start new process instance
ProcessInstance processInstance = rs.startProcessInstanceByKey(
"endTimeBugTestBPMN");
assertNotNull(processInstance);
// normal search
Task task = ts.createTaskQuery().singleResult();
assertEquals("Testtask", task.getName());
// look for the historic taskinstance
HistoricTaskInstance hsTask = hs.createHistoricTaskInstanceQuery().singleResult();
// end time should be null
assertNull(hsTask.getEndTime());
// look for the activities
List<HistoricActivityInstance> activities = hs.createHistoricActivityInstanceQuery().list();
assertEquals(2, activities.size());
// Get task of all activities
Optional<HistoricActivityInstance> taskActivity = activities.stream()
.filter(a -> a.getActivityId().equals("Task_0r58ed8")).findFirst();
assertTrue(taskActivity.isPresent());
// end time should be null too
assertNull(taskActivity.get().getEndTime());
// Now do the bug and send a message to Testtask execution
rs.messageEventReceived("Message_0mqt7n0", task.getExecutionId());
// now test again
// look for the historic taskinstance
hsTask = hs.createHistoricTaskInstanceQuery().singleResult();
// end time should be null
assertNull(hsTask.getEndTime());
// look for the activities
activities = hs.createHistoricActivityInstanceQuery().list();
assertEquals(4, activities.size());
// Get task of all activities
taskActivity = activities.stream()
.filter(a -> a.getActivityId().equals("Task_0r58ed8")).findFirst();
assertTrue(taskActivity.isPresent());
// end time should be null too but it was set after i called
// messageEventReceived
assertNull(taskActivity.get().getEndTime()); // Error
}
@BeforeClass
public static void setUpBeforeClass() throws Exception {
try {
// start H2 database
h2Server = Server.createWebServer().start();
System.out.println(h2Server.getURL());
} catch (Exception e) {
System.err.println(e);
}
}
@AfterClass
public static void setUpAfterClass() {
// stop H2 database
if (h2Server != null) {
h2Server.stop();
}
}
}
This is a known issue in 5.x and I have seen a JIRA on this issue sometime ago. I believe it has been fixed in the 6.x branch, however I need to test against V6 to confirm that.
Thanks for your response Currently we use version 5.22
Maybe we switch to 6.x and i will retest that bug again - i will post my results later...
Ask for and offer help to other Alfresco Process Services and Activiti Users and members of the Alfresco team.
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.