From 31ebc4a950dc9bff931b76943c76162bab620905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Mu=C3=B1oz?= Date: Thu, 31 Aug 2023 17:10:04 +0200 Subject: [PATCH] [JBPM-10192] SLA timers are not migrated after migrating process instances --- .../impl/migration/MigrationManager.java | 78 +++++-- .../migration/TimerMigrationManagerTest.java | 217 ++++++++++++++++-- .../migration/v1/BPMN2-ProcessSLA-v1.bpmn2 | 158 +++++++++++++ .../migration/v1/BPMN2-SLAOnTask-v1.bpmn2 | 127 ++++++++++ .../migration/v2/BPMN2-ProcessSLA-v2.bpmn2 | 165 +++++++++++++ .../migration/v2/BPMN2-SLAOnTask-v2.bpmn2 | 127 ++++++++++ 6 files changed, 829 insertions(+), 43 deletions(-) create mode 100644 jbpm-runtime-manager/src/test/resources/migration/v1/BPMN2-ProcessSLA-v1.bpmn2 create mode 100644 jbpm-runtime-manager/src/test/resources/migration/v1/BPMN2-SLAOnTask-v1.bpmn2 create mode 100644 jbpm-runtime-manager/src/test/resources/migration/v2/BPMN2-ProcessSLA-v2.bpmn2 create mode 100644 jbpm-runtime-manager/src/test/resources/migration/v2/BPMN2-SLAOnTask-v2.bpmn2 diff --git a/jbpm-runtime-manager/src/main/java/org/jbpm/runtime/manager/impl/migration/MigrationManager.java b/jbpm-runtime-manager/src/main/java/org/jbpm/runtime/manager/impl/migration/MigrationManager.java index 9e131161b5..8620891c00 100644 --- a/jbpm-runtime-manager/src/main/java/org/jbpm/runtime/manager/impl/migration/MigrationManager.java +++ b/jbpm-runtime-manager/src/main/java/org/jbpm/runtime/manager/impl/migration/MigrationManager.java @@ -587,8 +587,18 @@ public Map> execute(Context context) { WorkflowProcessInstanceImpl processInstance = (WorkflowProcessInstanceImpl) kieSession.getProcessInstance(migrationSpec.getProcessInstanceId()); Collection activeInstances = processInstance.getNodeInstances(true); + + TimerInstance processSlaTimer = cancelSla(processInstance.getSlaTimerId(), timerManager, processInstance.getId()); + if (processSlaTimer != null) { + result.put(-1L, Arrays.asList(processSlaTimer)); //-1 as key is for process, not node + } for (org.jbpm.workflow.instance.NodeInstance active : activeInstances) { + TimerInstance nodeSlaTimer = cancelSla(((NodeInstanceImpl) active).getSlaTimerId(), timerManager, processInstance.getId()); + if (nodeSlaTimer != null) { + result.put(active.getId(), Arrays.asList(nodeSlaTimer)); + break; + } if (active instanceof TimerNodeInstance) { TimerInstance timerInstance = timerManager.getTimerMap().get(((TimerNodeInstance) active).getTimerId()); @@ -623,6 +633,16 @@ public Map> execute(Context context) { } } + protected TimerInstance cancelSla(Long slaTimerId, TimerManager tm, long pid) { + if (slaTimerId != null && slaTimerId != -1L) { + TimerInstance timer = tm.getTimerMap().get(slaTimerId); + logger.debug("cancelling SLA timer, "+timer); + tm.cancelTimer(pid, timer.getId()); + return timer; + } + return null; + } + protected void rescheduleTimersAfterMigration(RuntimeManager manager, Map> timerMigrated) { RuntimeEngine engine = manager.getRuntimeEngine(ProcessInstanceIdContext.get(migrationSpec.getProcessInstanceId())); try { @@ -639,45 +659,67 @@ public Void execute(Context context) { for (Entry> entry : timerMigrated.entrySet()) { + if (entry.getKey()==-1L) { //Process SLA are stored with key -1 + setSlaProcessTimer(timerManager, processInstance, entry.getValue().get(0)); + break; + } + org.jbpm.workflow.instance.NodeInstance active = processInstance.getNodeInstance(entry.getKey(), true); + + if (((NodeInstanceImpl) active).getSlaTimerId() != -1L) { //Process SLA for nodes + setSlaNodeTimer(timerManager, processInstance, entry.getValue().get(0), (NodeInstanceImpl) active); + break; + } + if (active instanceof TimerNodeInstance) { TimerInstance timerInstance = entry.getValue().get(0); - - long delay = timerInstance.getDelay() - (System.currentTimeMillis() - timerInstance.getActivated().getTime()); - timerInstance.setDelay(delay); - - updateBasedOnTrigger(timerInstance); - - timerManager.registerTimer(timerInstance, processInstance); + registerTimer(timerManager, processInstance, timerInstance); ((TimerNodeInstance) active).internalSetTimerId(timerInstance.getId()); } else if (active instanceof StateBasedNodeInstance) { - List timerInstances = entry.getValue(); List timers = new ArrayList<>(); for (TimerInstance timerInstance : timerInstances) { - long delay = timerInstance.getDelay() - (System.currentTimeMillis() - timerInstance.getActivated().getTime()); - timerInstance.setDelay(delay); - - updateBasedOnTrigger(timerInstance); - - timerManager.registerTimer(timerInstance, processInstance); + registerTimer(timerManager, processInstance, timerInstance); timers.add(timerInstance.getId()); } ((StateBasedNodeInstance) active).internalSetTimerInstances(timers); - } } return null; } - }); } finally { - manager.disposeRuntimeEngine(engine); } } + protected void setSlaProcessTimer(TimerManager timerManager, WorkflowProcessInstanceImpl processInstance, TimerInstance timerInstance) { + registerTimer(timerManager, processInstance, timerInstance); + processInstance.internalSetSlaTimerId(timerInstance.getId()); + processInstance.internalSetSlaDueDate(new Date(System.currentTimeMillis() + getDelay(timerInstance))); + processInstance.internalSetSlaCompliance(ProcessInstance.SLA_PENDING); + logger.debug("Setting new process SLA timer: "+timerInstance); + } + + protected void setSlaNodeTimer(TimerManager timerManager, WorkflowProcessInstanceImpl processInstance, TimerInstance timerInstance, NodeInstanceImpl node) { + registerTimer(timerManager, processInstance, timerInstance); + node.internalSetSlaTimerId(timerInstance.getId()); + node.internalSetSlaDueDate(new Date(System.currentTimeMillis() + timerInstance.getDelay())); + node.internalSetSlaCompliance(ProcessInstance.SLA_PENDING); + logger.debug("Setting new node SLA timer: "+timerInstance); + } + + protected void registerTimer(TimerManager timerManager, WorkflowProcessInstanceImpl processInstance, TimerInstance timerInstance) { + timerInstance.setDelay(getDelay(timerInstance)); + updateBasedOnTrigger(timerInstance); + timerManager.registerTimer(timerInstance, processInstance); + } + + protected long getDelay(TimerInstance timerInstance) { + return timerInstance.getDelay() - (System.currentTimeMillis() - timerInstance.getActivated().getTime()); + } + protected void updateBasedOnTrigger(TimerInstance timerInstance) { Trigger trigger = ((DefaultJobHandle)timerInstance.getJobHandle()).getTimerJobInstance().getTrigger(); if (trigger instanceof IntervalTrigger && timerInstance.getPeriod() > 0) { @@ -696,5 +738,5 @@ protected void updateBasedOnTrigger(TimerInstance timerInstance) { timerInstance.setDelay(delay); } } - + } diff --git a/jbpm-runtime-manager/src/test/java/org/jbpm/runtime/manager/impl/migration/TimerMigrationManagerTest.java b/jbpm-runtime-manager/src/test/java/org/jbpm/runtime/manager/impl/migration/TimerMigrationManagerTest.java index 0c7da595c9..c4e76b5623 100644 --- a/jbpm-runtime-manager/src/test/java/org/jbpm/runtime/manager/impl/migration/TimerMigrationManagerTest.java +++ b/jbpm-runtime-manager/src/test/java/org/jbpm/runtime/manager/impl/migration/TimerMigrationManagerTest.java @@ -20,6 +20,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.kie.api.runtime.manager.audit.NodeInstanceLog.TYPE_ENTER; +import static org.kie.api.runtime.manager.audit.NodeInstanceLog.TYPE_EXIT; +import static org.kie.api.runtime.process.ProcessInstance.SLA_MET; +import static org.kie.api.runtime.process.ProcessInstance.SLA_PENDING; +import static org.kie.api.runtime.process.ProcessInstance.SLA_VIOLATED; import static org.kie.api.runtime.process.ProcessInstance.STATE_ACTIVE; import static org.kie.api.runtime.process.ProcessInstance.STATE_COMPLETED; @@ -34,6 +39,8 @@ import javax.persistence.EntityManagerFactory; import org.jbpm.process.audit.JPAAuditLogService; +import org.jbpm.process.audit.NodeInstanceLog; +import org.jbpm.process.audit.ProcessInstanceLog; import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler; import org.jbpm.runtime.manager.impl.DefaultRegisterableItemsFactory; import org.jbpm.runtime.manager.impl.jpa.EntityManagerFactoryManager; @@ -41,7 +48,9 @@ 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.jbpm.workflow.instance.NodeInstance; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -56,9 +65,9 @@ import org.kie.api.runtime.manager.RuntimeEnvironmentBuilder; import org.kie.api.runtime.manager.RuntimeManager; import org.kie.api.runtime.manager.RuntimeManagerFactory; -import org.kie.api.runtime.manager.audit.ProcessInstanceLog; import org.kie.api.runtime.process.ProcessInstance; import org.kie.api.runtime.process.WorkItemHandler; +import org.kie.api.runtime.process.WorkflowProcessInstance; import org.kie.api.task.TaskService; import org.kie.api.task.model.TaskSummary; import org.kie.internal.io.ResourceFactory; @@ -114,6 +123,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 PROCESS_SLA_ID_V1 = "processSLA-V1"; + private static final String PROCESS_SLA_ID_V2 = "processSLA-V2"; + + private static final String SLA_ON_TASK_ID_V1 = "SLAOnTask-v1"; + private static final String SLA_ON_TASK_ID_V2 = "SLAOnTask-v2"; + private JPAAuditLogService auditService; private RuntimeEngine runtime; private long pid; @@ -157,14 +173,14 @@ public void testMigrateTimerProcessInstance() throws Exception { assertNotNull(managerV1); assertNotNull(managerV2); - RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get()); + runtime = managerV1.getRuntimeEngine(EmptyContext.get()); KieSession ksession = runtime.getKieSession(); assertNotNull(ksession); ProcessInstance pi1 = ksession.startProcess(TIMER_ID_V1); assertNotNull(pi1); assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState()); - JPAAuditLogService auditService = new JPAAuditLogService(emf); + auditService = new JPAAuditLogService(emf); ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId()); assertNotNull(log); assertEquals(TIMER_ID_V1, log.getProcessId()); @@ -191,7 +207,6 @@ public void testMigrateTimerProcessInstance() throws Exception { countdownListener.waitTillCompleted(); log = auditService.findProcessInstance(pi1.getId()); - auditService.dispose(); assertNotNull(log); assertEquals(TIMER_ID_V2, log.getProcessId()); assertEquals(DEPLOYMENT_ID_V2, log.getExternalId()); @@ -206,14 +221,14 @@ public void testMigrateBoundaryTimerProcessInstance() throws Exception { assertNotNull(managerV1); assertNotNull(managerV2); - RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get()); + runtime = managerV1.getRuntimeEngine(EmptyContext.get()); KieSession ksession = runtime.getKieSession(); assertNotNull(ksession); ProcessInstance pi1 = ksession.startProcess(BOUNDARY_TIMER_ID_V1); assertNotNull(pi1); assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState()); - JPAAuditLogService auditService = new JPAAuditLogService(emf); + auditService = new JPAAuditLogService(emf); ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId()); assertNotNull(log); assertEquals(BOUNDARY_TIMER_ID_V1, log.getProcessId()); @@ -240,7 +255,6 @@ public void testMigrateBoundaryTimerProcessInstance() throws Exception { countdownListener.waitTillCompleted(); log = auditService.findProcessInstance(pi1.getId()); - auditService.dispose(); assertNotNull(log); assertEquals(BOUNDARY_TIMER_ID_V2, log.getProcessId()); assertEquals(DEPLOYMENT_ID_V2, log.getExternalId()); @@ -255,14 +269,14 @@ public void testMigrateEventSubprocessTimerProcessInstance() throws Exception { assertNotNull(managerV1); assertNotNull(managerV2); - RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get()); + runtime = managerV1.getRuntimeEngine(EmptyContext.get()); KieSession ksession = runtime.getKieSession(); assertNotNull(ksession); ProcessInstance pi1 = ksession.startProcess(EVENT_SUBPROCESS_TIMER_ID_V1); assertNotNull(pi1); assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState()); - JPAAuditLogService auditService = new JPAAuditLogService(emf); + auditService = new JPAAuditLogService(emf); ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId()); assertNotNull(log); assertEquals(EVENT_SUBPROCESS_TIMER_ID_V1, log.getProcessId()); @@ -289,7 +303,6 @@ public void testMigrateEventSubprocessTimerProcessInstance() throws Exception { countdownListener.waitTillCompleted(); log = auditService.findProcessInstance(pi1.getId()); - auditService.dispose(); assertNotNull(log); assertEquals(EVENT_SUBPROCESS_TIMER_ID_V2, log.getProcessId()); assertEquals(DEPLOYMENT_ID_V2, log.getExternalId()); @@ -305,14 +318,14 @@ public void testMigrateTimerProcessInstanceRollback() throws Exception { assertNotNull(managerV1); assertNotNull(managerV2); - RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get()); + runtime = managerV1.getRuntimeEngine(EmptyContext.get()); KieSession ksession = runtime.getKieSession(); assertNotNull(ksession); ProcessInstance pi1 = ksession.startProcess(TIMER_ID_V1); assertNotNull(pi1); assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState()); - JPAAuditLogService auditService = new JPAAuditLogService(emf); + auditService = new JPAAuditLogService(emf); ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId()); assertNotNull(log); assertEquals(TIMER_ID_V1, log.getProcessId()); @@ -345,7 +358,6 @@ public void testMigrateTimerProcessInstanceRollback() throws Exception { countdownListener.waitTillCompleted(); log = auditService.findProcessInstance(pi1.getId()); - auditService.dispose(); assertNotNull(log); assertEquals(TIMER_ID_V1, log.getProcessId()); assertEquals(DEPLOYMENT_ID_V1, log.getExternalId()); @@ -360,7 +372,7 @@ public void testMigrateTimerCycleProcessInstance() throws Exception { assertNotNull(managerV1); assertNotNull(managerV2); - RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get()); + runtime = managerV1.getRuntimeEngine(EmptyContext.get()); KieSession ksession = runtime.getKieSession(); assertNotNull(ksession); @@ -368,7 +380,7 @@ public void testMigrateTimerCycleProcessInstance() throws Exception { ProcessInstance pi1 = ksession.startProcess(CYCLE_TIMER_ID_V1, params); assertNotNull(pi1); assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState()); - JPAAuditLogService auditService = new JPAAuditLogService(emf); + auditService = new JPAAuditLogService(emf); ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId()); assertNotNull(log); assertEquals(CYCLE_TIMER_ID_V1, log.getProcessId()); @@ -407,7 +419,6 @@ public void testMigrateTimerCycleProcessInstance() throws Exception { managerV2.disposeRuntimeEngine(runtime); log = auditService.findProcessInstance(pi1.getId()); - auditService.dispose(); assertNotNull(log); assertEquals(CYCLE_TIMER_ID_V2, log.getProcessId()); assertEquals(DEPLOYMENT_ID_V2, log.getExternalId()); @@ -422,7 +433,7 @@ public void testMigrateTimerCycleProcessInstanceBeforeFirstTrigger() throws Exce assertNotNull(managerV1); assertNotNull(managerV2); - RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get()); + runtime = managerV1.getRuntimeEngine(EmptyContext.get()); KieSession ksession = runtime.getKieSession(); assertNotNull(ksession); @@ -431,7 +442,7 @@ public void testMigrateTimerCycleProcessInstanceBeforeFirstTrigger() throws Exce ProcessInstance pi1 = ksession.startProcess(CYCLE_TIMER_ID_V1, params); assertNotNull(pi1); assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState()); - JPAAuditLogService auditService = new JPAAuditLogService(emf); + auditService = new JPAAuditLogService(emf); ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId()); assertNotNull(log); assertEquals(CYCLE_TIMER_ID_V1, log.getProcessId()); @@ -466,7 +477,6 @@ public void testMigrateTimerCycleProcessInstanceBeforeFirstTrigger() throws Exce managerV2.disposeRuntimeEngine(runtime); log = auditService.findProcessInstance(pi1.getId()); - auditService.dispose(); assertNotNull(log); assertEquals(CYCLE_TIMER_ID_V2, log.getProcessId()); assertEquals(DEPLOYMENT_ID_V2, log.getExternalId()); @@ -481,14 +491,14 @@ public void testMigrateTimerWithLoopProcessInstance() throws Exception { assertNotNull(managerV1); assertNotNull(managerV2); - RuntimeEngine runtime = managerV1.getRuntimeEngine(EmptyContext.get()); + runtime = managerV1.getRuntimeEngine(EmptyContext.get()); KieSession ksession = runtime.getKieSession(); assertNotNull(ksession); ProcessInstance pi1 = ksession.startProcess(LOOP_TIMER_ID_V1); assertNotNull(pi1); assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState()); - JPAAuditLogService auditService = new JPAAuditLogService(emf); + auditService = new JPAAuditLogService(emf); ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId()); assertNotNull(log); assertEquals(LOOP_TIMER_ID_V1, log.getProcessId()); @@ -545,7 +555,6 @@ public void testMigrateTimerWithLoopProcessInstance() throws Exception { countdownListener.waitTillCompleted(); log = auditService.findProcessInstance(pi1.getId()); - auditService.dispose(); assertNotNull(log); assertEquals(LOOP_TIMER_ID_V1, log.getProcessId()); assertEquals(DEPLOYMENT_ID_V1, log.getExternalId()); @@ -589,6 +598,96 @@ public void testMigrateUserTaskNotCompletedBoundaryTimerProcessInstance() throws checkProcessCompleted(countdownListener); } + + @Test(timeout=10000) + public void testMigrateSLAProcessTimer() throws Exception { + SLAViolationCountDownProcessEventListener countdownListener = new SLAViolationCountDownProcessEventListener(1); + ProcessInstance pi = startSLAProcess("migration/v1/BPMN2-ProcessSLA-v1.bpmn2", + "migration/v2/BPMN2-ProcessSLA-v2.bpmn2", + PROCESS_SLA_ID_V1, + countdownListener); + migrate(pi, PROCESS_SLA_ID_V2); + + //wait till timer fires because SLA is violated + countdownListener.waitTillCompleted(); + + assertSLAProcessCompliance(pi, SLA_VIOLATED); + } + + @Test(timeout=10000) + public void testMigrateAfterSLAProcessTimer() throws Exception { + SLAViolationCountDownProcessEventListener countdownListener = new SLAViolationCountDownProcessEventListener(1); + ProcessInstance pi = startSLAProcess("migration/v1/BPMN2-ProcessSLA-v1.bpmn2", + "migration/v2/BPMN2-ProcessSLA-v2.bpmn2", + PROCESS_SLA_ID_V1, + countdownListener); + + //wait till timer fires because SLA is violated, before migration + countdownListener.waitTillCompleted(); + + migrate(pi, PROCESS_SLA_ID_V2); + assertSLAProcessCompliance(pi, SLA_VIOLATED); + } + + @Test(timeout=10000) + public void testMigrateAndCompleteSLAProcessTimer() throws Exception { + NodeLeftCountDownProcessEventListener countdownListener = new NodeLeftCountDownProcessEventListener("Script Task 2", 1); + ProcessInstance pi = startSLAProcess("migration/v1/BPMN2-ProcessSLA-v1.bpmn2", + "migration/v2/BPMN2-ProcessSLA-v2.bpmn2", + PROCESS_SLA_ID_V1, + countdownListener); + migrate(pi, PROCESS_SLA_ID_V2); + assertSLAProcessCompliance(pi, SLA_PENDING); + + completeUserTask(managerV2, USER_JOHN); + // wait till process is completed + countdownListener.waitTillCompleted(); + assertSLAProcessCompliance(pi, SLA_MET); + } + + @Test(timeout=10000) + public void testMigrateSLAOnTaskTimer() throws Exception { + SLAViolationCountDownProcessEventListener countdownListener = new SLAViolationCountDownProcessEventListener(1); + ProcessInstance pi = startSLAProcess("migration/v1/BPMN2-SLAOnTask-v1.bpmn2", + "migration/v2/BPMN2-SLAOnTask-v2.bpmn2", + SLA_ON_TASK_ID_V1, + countdownListener); + migrate(pi, SLA_ON_TASK_ID_V2); + + //wait till timer fires because SLA is violated + countdownListener.waitTillCompleted(); + assertSLAOnTaskCompliance(pi, TYPE_ENTER, SLA_VIOLATED); + } + + @Test(timeout=10000) + public void testMigrateAfterSLAOnTaskTimer() throws Exception { + SLAViolationCountDownProcessEventListener countdownListener = new SLAViolationCountDownProcessEventListener(1); + ProcessInstance pi = startSLAProcess("migration/v1/BPMN2-SLAOnTask-v1.bpmn2", + "migration/v2/BPMN2-SLAOnTask-v2.bpmn2", + SLA_ON_TASK_ID_V1, + countdownListener); + //wait till timer fires because SLA is violated, before migration + countdownListener.waitTillCompleted(); + + migrate(pi, SLA_ON_TASK_ID_V2); + assertSLAOnTaskCompliance(pi, TYPE_ENTER, SLA_VIOLATED); + } + + @Test(timeout=10000) + public void testMigrateAndCompleteSLAOnTaskTimer() throws Exception { + NodeLeftCountDownProcessEventListener countdownListener = new NodeLeftCountDownProcessEventListener("Script Task 2", 1); + ProcessInstance pi = startSLAProcess("migration/v1/BPMN2-SLAOnTask-v1.bpmn2", + "migration/v2/BPMN2-SLAOnTask-v2.bpmn2", + SLA_ON_TASK_ID_V1, + countdownListener); + migrate(pi, SLA_ON_TASK_ID_V2); + assertSLAOnTaskCompliance(pi, TYPE_ENTER, SLA_PENDING); + + completeUserTask(managerV2, USER_JOHN); + // wait till process is completed + countdownListener.waitTillCompleted(); + assertSLAOnTaskCompliance(pi, TYPE_EXIT, SLA_MET); + } protected void createRuntimeManagers(String processV1, String processV2, ProcessEventListener...eventListeners) { RuntimeEnvironment environment = RuntimeEnvironmentBuilder.Factory.get() @@ -703,7 +802,7 @@ private void checkProcess(long pid, String processId, } private void migrateProcessUserTaskBoundary(RuntimeManager manager) { - RuntimeEngine runtime = manager.getRuntimeEngine(EmptyContext.get()); + runtime = manager.getRuntimeEngine(EmptyContext.get()); manager.disposeRuntimeEngine(runtime); MigrationSpec migrationSpec = new MigrationSpec(DEPLOYMENT_ID_V1, pid, DEPLOYMENT_ID_V2, USERTASK_BOUNDARY_TIMER_ID_V2); @@ -714,7 +813,7 @@ private void migrateProcessUserTaskBoundary(RuntimeManager manager) { } private void completeUserTask(RuntimeManager manager, String user) { - RuntimeEngine runtime = manager.getRuntimeEngine(EmptyContext.get()); + runtime = manager.getRuntimeEngine(EmptyContext.get()); TaskService taskService = runtime.getTaskService(); List tasks = taskService.getTasksAssignedAsPotentialOwner(user, "en-UK"); assertNotNull(tasks); @@ -735,7 +834,75 @@ private void checkProcessCompleted(NodeLeftCountDownProcessEventListener countdo countdownListener.waitTillCompleted(); checkProcess(pid, USERTASK_BOUNDARY_TIMER_ID_V2, DEPLOYMENT_ID_V2, STATE_COMPLETED); + } + + protected ProcessInstance startSLAProcess(String processV1, String processV2, String processId, ProcessEventListener countdownListener) { + createRuntimeManagers(processV1, processV2, countdownListener); + assertNotNull(managerV1); + assertNotNull(managerV2); - auditService.dispose(); + runtime = managerV1.getRuntimeEngine(EmptyContext.get()); + KieSession ksession = runtime.getKieSession(); + assertNotNull(ksession); + + ProcessInstance pi1 = ksession.startProcess(processId); + assertNotNull(pi1); + assertEquals(ProcessInstance.STATE_ACTIVE, pi1.getState()); + auditService = new JPAAuditLogService(emf); + ProcessInstanceLog log = auditService.findProcessInstance(pi1.getId()); + assertNotNull(log); + assertEquals(processId, log.getProcessId()); + assertEquals(DEPLOYMENT_ID_V1, log.getExternalId()); + + managerV1.disposeRuntimeEngine(runtime); + return pi1; + } + + protected void migrate(ProcessInstance pid, String processId) { + MigrationSpec migrationSpec = new MigrationSpec(DEPLOYMENT_ID_V1, pid.getId(), DEPLOYMENT_ID_V2, processId); + + MigrationManager migrationManager = new MigrationManager(migrationSpec); + MigrationReport report = migrationManager.migrate(); + + assertNotNull(report); + assertTrue(report.isSuccessful()); + } + + protected void assertSLAProcessCompliance(ProcessInstance pi, int compliance) { + ProcessInstanceLog log = auditService.findProcessInstance(pi.getId()); + assertNotNull(log); + + assertEquals(PROCESS_SLA_ID_V2, log.getProcessId()); + assertEquals(DEPLOYMENT_ID_V2, log.getExternalId()); + assertEquals(compliance, (int)log.getSlaCompliance()); + } + + protected void assertSLAOnTaskCompliance(ProcessInstance pi, int type, int compliance) { + ProcessInstanceLog log = auditService.findProcessInstance(pi.getId()); + assertNotNull(log); + + assertEquals(SLA_ON_TASK_ID_V2, log.getProcessId()); + assertEquals(DEPLOYMENT_ID_V2, log.getExternalId()); + + Collection activeNodes = ((WorkflowProcessInstance)pi).getNodeInstances(); + assertEquals(1, activeNodes.size()); + + int sla = getSLAComplianceForNodeInstance(auditService, pi.getId(), + (org.jbpm.workflow.instance.NodeInstance) activeNodes.iterator().next(), + type); + assertEquals(compliance, sla); + } + + protected int getSLAComplianceForNodeInstance(JPAAuditLogService logService, long processInstanceId, NodeInstance nodeInstance, int logType) { + int slaCompliance = -1; + List logs = logService.findNodeInstances(processInstanceId); + if (logs != null) { + for (NodeInstanceLog log : logs) { + if (log.getType() == logType && log.getNodeInstanceId().equals(String.valueOf(nodeInstance.getId()))) { + return log.getSlaCompliance(); + } + } + } + return slaCompliance; } } diff --git a/jbpm-runtime-manager/src/test/resources/migration/v1/BPMN2-ProcessSLA-v1.bpmn2 b/jbpm-runtime-manager/src/test/resources/migration/v1/BPMN2-ProcessSLA-v1.bpmn2 new file mode 100644 index 0000000000..f76a09560e --- /dev/null +++ b/jbpm-runtime-manager/src/test/resources/migration/v1/BPMN2-ProcessSLA-v1.bpmn2 @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SequenceFlow_1 + + + + + + + + _1B1A6982-058C-4ABE-91FB-0C0E77A86A50 + + + + + + + + _1B1A6982-058C-4ABE-91FB-0C0E77A86A50 + _C7E0225D-0F85-474C-8B35-B32D7F47D6B3 + + + + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_TaskNameInputX + _7B93533E-C018-4DEA-A603-2B63E8878A29_SkippableInputX + DataInput_6 + + + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_TaskNameInputX + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_TaskNameInputX + + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_SkippableInputX + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_SkippableInputX + + + + DataInput_6 + + en-UK + DataInput_6 + + + + + john + + + + + + + + + + _C7E0225D-0F85-474C-8B35-B32D7F47D6B3 + SequenceFlow_1 + System.out.println("End of SLA Timer 1"); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jbpm-runtime-manager/src/test/resources/migration/v1/BPMN2-SLAOnTask-v1.bpmn2 b/jbpm-runtime-manager/src/test/resources/migration/v1/BPMN2-SLAOnTask-v1.bpmn2 new file mode 100644 index 0000000000..063fffab88 --- /dev/null +++ b/jbpm-runtime-manager/src/test/resources/migration/v1/BPMN2-SLAOnTask-v1.bpmn2 @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + _1-_2 + + + + + 2s + + + + + + System.out.println("Entering on Hello v1"); + + + _1-_2 + SequenceFlow_1 + + + + DataInput_8 + + + + + DataInput_8 + + en-UK + DataInput_8 + + + + + john + + + + + + + + + + SequenceFlow_2 + + + + + + + + + + SequenceFlow_1 + SequenceFlow_2 + System.out.println("Goodbye v1"); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jbpm-runtime-manager/src/test/resources/migration/v2/BPMN2-ProcessSLA-v2.bpmn2 b/jbpm-runtime-manager/src/test/resources/migration/v2/BPMN2-ProcessSLA-v2.bpmn2 new file mode 100644 index 0000000000..eef6cd9362 --- /dev/null +++ b/jbpm-runtime-manager/src/test/resources/migration/v2/BPMN2-ProcessSLA-v2.bpmn2 @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SequenceFlow_1 + + + + + + + + _1B1A6982-058C-4ABE-91FB-0C0E77A86A50 + + + + + + + + _1B1A6982-058C-4ABE-91FB-0C0E77A86A50 + _C7E0225D-0F85-474C-8B35-B32D7F47D6B3 + + + + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_TaskNameInputX + _7B93533E-C018-4DEA-A603-2B63E8878A29_SkippableInputX + DataInput_6 + + + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_TaskNameInputX + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_TaskNameInputX + + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_SkippableInputX + + + _7B93533E-C018-4DEA-A603-2B63E8878A29_SkippableInputX + + + + DataInput_6 + + en-UK + DataInput_6 + + + + + john + + + + + + + + + + _C7E0225D-0F85-474C-8B35-B32D7F47D6B3 + SequenceFlow_1 + System.out.println("End of SLA Timer 2"); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jbpm-runtime-manager/src/test/resources/migration/v2/BPMN2-SLAOnTask-v2.bpmn2 b/jbpm-runtime-manager/src/test/resources/migration/v2/BPMN2-SLAOnTask-v2.bpmn2 new file mode 100644 index 0000000000..0ad27f91f9 --- /dev/null +++ b/jbpm-runtime-manager/src/test/resources/migration/v2/BPMN2-SLAOnTask-v2.bpmn2 @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + _1-_2 + + + + + 2s + + + + + + System.out.println("Entering on Hello v2"); + + + _1-_2 + SequenceFlow_1 + + + + DataInput_8 + + + + + DataInput_8 + + en-UK + DataInput_8 + + + + + john + + + + + + + + + + SequenceFlow_2 + + + + + + + + + + SequenceFlow_1 + SequenceFlow_2 + System.out.println("Goodbye v2"); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file