07-27-2017 02:29 AM
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();
}
}
}
08-01-2017 01:10 AM
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.
08-07-2017 02:03 AM
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...
Explore our Alfresco products with the links below. Use labels to filter content by product module.