Skip to content

Commit

Permalink
[kie-issues-509] Handle SLA timers during process instance migration (#…
Browse files Browse the repository at this point in the history
…2323)

* [kie-issues-509] Handle SLA timers during process instance migration

* [kie-issues-509] Add tests for process SLA and usertask SLA migration

* [kie-issue-509] fix tests and add SLA process migration

---------

Co-authored-by: Martin Weiler <[email protected]>
  • Loading branch information
elguardian and martinweiler authored Sep 7, 2023
1 parent 543218f commit 814f7c1
Show file tree
Hide file tree
Showing 7 changed files with 803 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,9 @@ public void removeEventListeners() {
}

@Override
protected void triggerCompleted(String type, boolean remove) {
if (this.slaCompliance == org.kie.api.runtime.process.ProcessInstance.SLA_PENDING) {
if (System.currentTimeMillis() > slaDueDate.getTime()) {
protected void triggerCompleted(String type, boolean remove) {
if (this.slaCompliance == org.kie.api.runtime.process.ProcessInstance.SLA_PENDING) {
if (System.currentTimeMillis() > slaDueDate.getTime()) {
// completion of the node instance is after expected SLA due date, mark it accordingly
this.slaCompliance = org.kie.api.runtime.process.ProcessInstance.SLA_VIOLATED;
} else {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.jbpm.services.task.identity.JBossUserGroupCallbackImpl;
import org.jbpm.services.task.impl.TaskDeadlinesServiceImpl;
import org.jbpm.test.listener.process.NodeLeftCountDownProcessEventListener;
import org.jbpm.test.listener.process.SLAViolationCountDownProcessEventListener;
import org.jbpm.test.util.AbstractBaseTest;
import org.junit.After;
import org.junit.Before;
Expand Down Expand Up @@ -114,6 +115,13 @@ public TimerMigrationManagerTest(String strategy) {

private static final String USERTASK_BOUNDARY_TIMER_ID_V1 = "UserTaskBoundary-v1";
private static final String USERTASK_BOUNDARY_TIMER_ID_V2 = "UserTaskBoundary-v2";

private static final String USERTASK_SLA_ID_V1 = "BPMN2-UserTaskSLA-v1";
private static final String USERTASK_SLA_ID_V2 = "BPMN2-UserTaskSLA-v2";

private static final String PROCESS_SLA_ID_V1 = "BPMN2-ProcessSLA-v1";
private static final String PROCESS_SLA_ID_V2 = "BPMN2-ProcessSLA-v2";

private JPAAuditLogService auditService;
private RuntimeEngine runtime;
private long pid;
Expand Down Expand Up @@ -298,7 +306,7 @@ public void testMigrateEventSubprocessTimerProcessInstance() throws Exception {
}

@SuppressWarnings({"unchecked", "rawtypes"})
@Test(timeout=10000)
@Test//(timeout=10000)
public void testMigrateTimerProcessInstanceRollback() throws Exception {
NodeLeftCountDownProcessEventListener countdownListener = new NodeLeftCountDownProcessEventListener("Event", 1);
createRuntimeManagers("migration/v1/BPMN2-Timer-v1.bpmn2", "migration/v2/BPMN2-Timer-v2.bpmn2", countdownListener);
Expand Down Expand Up @@ -590,6 +598,104 @@ public void testMigrateUserTaskNotCompletedBoundaryTimerProcessInstance() throws
checkProcessCompleted(countdownListener);
}

@Test(timeout=10000)
public void testUserTaskSLA() throws Exception {
SLAViolationCountDownProcessEventListener countdownListener = new SLAViolationCountDownProcessEventListener(1);
createRuntimeManagers("migration/v1/BPMN2-UserTaskSLA-v1.bpmn2", "migration/v2/BPMN2-UserTaskSLA-v2.bpmn2", countdownListener);
assertNotNull(managerV1);
assertNotNull(managerV2);

RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get());
KieSession ksession = runtime.getKieSession();
assertNotNull(ksession);

ProcessInstance pi1 = ksession.startProcess(USERTASK_SLA_ID_V1);
assertNotNull(pi1);
assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState());
JPAAuditLogService auditService = new JPAAuditLogService(emf);
ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId());
assertNotNull(log);
assertEquals(USERTASK_SLA_ID_V1, log.getProcessId());
assertEquals(DEPLOYMENT_ID_V1, log.getExternalId());

managerV1.disposeRuntimeEngine(runtime);

MigrationSpec migrationSpec = new MigrationSpec(DEPLOYMENT_ID_V1, pi1.getId(), DEPLOYMENT_ID_V2, USERTASK_SLA_ID_V2);

MigrationManager migrationManager = new MigrationManager(migrationSpec);
MigrationReport report = migrationManager.migrate();

assertNotNull(report);
assertTrue(report.isSuccessful());

log = auditService.findProcessInstance(pi1.getId());
assertNotNull(log);
assertEquals(USERTASK_SLA_ID_V2, log.getProcessId());
assertEquals(DEPLOYMENT_ID_V2, log.getExternalId());
assertEquals(ProcessInstance.STATE_ACTIVE, log.getStatus().intValue());


// wait till timer fires
countdownListener.waitTillCompleted();

log = auditService.findProcessInstance(pi1.getId());
auditService.dispose();
assertNotNull(log);
assertEquals(USERTASK_SLA_ID_V2, log.getProcessId());
assertEquals(DEPLOYMENT_ID_V2, log.getExternalId());
assertEquals(ProcessInstance.STATE_ACTIVE, log.getStatus().intValue());

}

@Test(timeout=10000)
public void testProcessSLA() throws Exception {
SLAViolationCountDownProcessEventListener countdownListener = new SLAViolationCountDownProcessEventListener(1);
createRuntimeManagers("migration/v1/BPMN2-ProcessSLA-v1.bpmn2", "migration/v2/BPMN2-ProcessSLA-v2.bpmn2", countdownListener);
assertNotNull(managerV1);
assertNotNull(managerV2);

RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get());
KieSession ksession = runtime.getKieSession();
assertNotNull(ksession);

ProcessInstance pi1 = ksession.startProcess(PROCESS_SLA_ID_V1);
assertNotNull(pi1);
assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState());
JPAAuditLogService auditService = new JPAAuditLogService(emf);
ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId());
assertNotNull(log);
assertEquals(PROCESS_SLA_ID_V1, log.getProcessId());
assertEquals(DEPLOYMENT_ID_V1, log.getExternalId());

managerV1.disposeRuntimeEngine(runtime);

MigrationSpec migrationSpec = new MigrationSpec(DEPLOYMENT_ID_V1, pi1.getId(), DEPLOYMENT_ID_V2, PROCESS_SLA_ID_V2);

MigrationManager migrationManager = new MigrationManager(migrationSpec);
MigrationReport report = migrationManager.migrate();

assertNotNull(report);
assertTrue(report.isSuccessful());

log = auditService.findProcessInstance(pi1.getId());
assertNotNull(log);
assertEquals(PROCESS_SLA_ID_V2, log.getProcessId());
assertEquals(DEPLOYMENT_ID_V2, log.getExternalId());
assertEquals(ProcessInstance.STATE_ACTIVE, log.getStatus().intValue());


// wait till timer fires
countdownListener.waitTillCompleted();

log = auditService.findProcessInstance(pi1.getId());
auditService.dispose();
assertNotNull(log);
assertEquals(PROCESS_SLA_ID_V2, log.getProcessId());
assertEquals(DEPLOYMENT_ID_V2, log.getExternalId());
assertEquals(ProcessInstance.STATE_ACTIVE, log.getStatus().intValue());

}

protected void createRuntimeManagers(String processV1, String processV2, ProcessEventListener...eventListeners) {
RuntimeEnvironment environment = RuntimeEnvironmentBuilder.Factory.get()
.newDefaultBuilder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpsim="http://www.bpsim.org/schemas/1.0" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:drools="http://www.jboss.org/drools" id="_xI_0QCs8EDy3G-EZm5NgUw" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd http://www.jboss.org/drools drools.xsd http://www.bpsim.org/schemas/1.0 bpsim.xsd http://www.omg.org/spec/DD/20100524/DC DC.xsd http://www.omg.org/spec/DD/20100524/DI DI.xsd " exporter="jBPM Process Modeler" exporterVersion="2.0" targetNamespace="http://www.omg.org/bpmn20">
<bpmn2:itemDefinition id="__2_SkippableInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_PriorityInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_CommentInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_DescriptionInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_CreatedByInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_TaskNameInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_GroupIdInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_ContentInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_NotStartedReassignInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_NotCompletedReassignInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_NotStartedNotifyInputXItem" structureRef="Object"/>
<bpmn2:itemDefinition id="__2_NotCompletedNotifyInputXItem" structureRef="Object"/>
<bpmn2:collaboration id="_5D1B7000-A31C-473F-A542-0A70E294AD83" name="Default Collaboration">
<bpmn2:participant id="_12CADCE6-BF64-4B86-BD88-8CEE522EDFC2" name="Pool Participant" processRef="BPMN2_ProcessSLA_v1"/>
</bpmn2:collaboration>
<bpmn2:process id="BPMN2-ProcessSLA-v1" drools:packageName="com.example" drools:version="1.0" drools:adHoc="false" name="BPMN2-ProcessSLA-v1" isExecutable="true" processType="Private">
<bpmn2:extensionElements>
<drools:metaData name="customSLADueDate">
<drools:metaValue><![CDATA[PT5S]]></drools:metaValue>
</drools:metaData>
</bpmn2:extensionElements>
<bpmn2:sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2"/>
<bpmn2:sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3"/>
<bpmn2:startEvent id="_1" name="StartProcess">
<bpmn2:extensionElements>
<drools:metaData name="elementname">
<drools:metaValue><![CDATA[StartProcess]]></drools:metaValue>
</drools:metaData>
</bpmn2:extensionElements>
<bpmn2:outgoing>_1-_2</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="_2" name="Hello v1">
<bpmn2:extensionElements>
<drools:metaData name="elementname">
<drools:metaValue><![CDATA[Hello v1]]></drools:metaValue>
</drools:metaData>
</bpmn2:extensionElements>
<bpmn2:incoming>_1-_2</bpmn2:incoming>
<bpmn2:outgoing>_2-_3</bpmn2:outgoing>
<bpmn2:ioSpecification>
<bpmn2:dataInput id="_2_TaskNameInputX" drools:dtype="Object" itemSubjectRef="__2_TaskNameInputXItem" name="TaskName"/>
<bpmn2:dataInput id="_2_SkippableInputX" drools:dtype="Object" itemSubjectRef="__2_SkippableInputXItem" name="Skippable"/>
<bpmn2:inputSet>
<bpmn2:dataInputRefs>_2_TaskNameInputX</bpmn2:dataInputRefs>
<bpmn2:dataInputRefs>_2_SkippableInputX</bpmn2:dataInputRefs>
</bpmn2:inputSet>
</bpmn2:ioSpecification>
<bpmn2:dataInputAssociation>
<bpmn2:targetRef>_2_TaskNameInputX</bpmn2:targetRef>
<bpmn2:assignment>
<bpmn2:from xsi:type="bpmn2:tFormalExpression"><![CDATA[Task]]></bpmn2:from>
<bpmn2:to xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_TaskNameInputX]]></bpmn2:to>
</bpmn2:assignment>
</bpmn2:dataInputAssociation>
<bpmn2:dataInputAssociation>
<bpmn2:targetRef>_2_SkippableInputX</bpmn2:targetRef>
<bpmn2:assignment>
<bpmn2:from xsi:type="bpmn2:tFormalExpression"><![CDATA[false]]></bpmn2:from>
<bpmn2:to xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_SkippableInputX]]></bpmn2:to>
</bpmn2:assignment>
</bpmn2:dataInputAssociation>
<bpmn2:potentialOwner id="_xJEFsCs8EDy3G-EZm5NgUw">
<bpmn2:resourceAssignmentExpression id="_xJEFsSs8EDy3G-EZm5NgUw">
<bpmn2:formalExpression>john</bpmn2:formalExpression>
</bpmn2:resourceAssignmentExpression>
</bpmn2:potentialOwner>
</bpmn2:userTask>
<bpmn2:endEvent id="_3" name="EndProcess">
<bpmn2:extensionElements>
<drools:metaData name="elementname">
<drools:metaValue><![CDATA[EndProcess]]></drools:metaValue>
</drools:metaData>
</bpmn2:extensionElements>
<bpmn2:incoming>_2-_3</bpmn2:incoming>
<bpmn2:terminateEventDefinition/>
</bpmn2:endEvent>
</bpmn2:process>
<bpmndi:BPMNDiagram>
<bpmndi:BPMNPlane bpmnElement="BPMN2_ProcessSLA_v1">
<bpmndi:BPMNShape id="shape__3" bpmnElement="_3">
<dc:Bounds height="56" width="56" x="228" y="16"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape__2" bpmnElement="_2">
<dc:Bounds height="48" width="100" x="96" y="16"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape__1" bpmnElement="_1">
<dc:Bounds height="56" width="56" x="16" y="16"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge_shape__2_to_shape__3" bpmnElement="_2-_3">
<di:waypoint x="146" y="40"/>
<di:waypoint x="252" y="40"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge_shape__1_to_shape__2" bpmnElement="_1-_2">
<di:waypoint x="40" y="40"/>
<di:waypoint x="146" y="40"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
<bpmn2:relationship type="BPSimData">
<bpmn2:extensionElements>
<bpsim:BPSimData>
<bpsim:Scenario id="default" name="Simulationscenario">
<bpsim:ScenarioParameters/>
<bpsim:ElementParameters elementRef="_2">
<bpsim:TimeParameters>
<bpsim:ProcessingTime>
<bpsim:NormalDistribution mean="0" standardDeviation="0"/>
</bpsim:ProcessingTime>
</bpsim:TimeParameters>
<bpsim:ResourceParameters>
<bpsim:Availability>
<bpsim:FloatingParameter value="0"/>
</bpsim:Availability>
<bpsim:Quantity>
<bpsim:FloatingParameter value="0"/>
</bpsim:Quantity>
</bpsim:ResourceParameters>
<bpsim:CostParameters>
<bpsim:UnitCost>
<bpsim:FloatingParameter value="0"/>
</bpsim:UnitCost>
</bpsim:CostParameters>
</bpsim:ElementParameters>
<bpsim:ElementParameters elementRef="_1">
<bpsim:TimeParameters>
<bpsim:ProcessingTime>
<bpsim:NormalDistribution mean="0" standardDeviation="0"/>
</bpsim:ProcessingTime>
</bpsim:TimeParameters>
</bpsim:ElementParameters>
</bpsim:Scenario>
</bpsim:BPSimData>
</bpmn2:extensionElements>
<bpmn2:source>_xI_0QCs8EDy3G-EZm5NgUw</bpmn2:source>
<bpmn2:target>_xI_0QCs8EDy3G-EZm5NgUw</bpmn2:target>
</bpmn2:relationship>
</bpmn2:definitions>
Loading

0 comments on commit 814f7c1

Please sign in to comment.