Skip to content

Commit

Permalink
[JBPM-8896] NPE during Process Migration when Boundary Timer is fired…
Browse files Browse the repository at this point in the history
… but UserTask not completed
  • Loading branch information
Enrique Gonzalez Martinez committed Jan 9, 2020
1 parent 8a04073 commit 4e3295b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 14 deletions.
Expand Up @@ -32,6 +32,8 @@
import org.drools.core.spi.Activation;
import org.drools.core.time.TimeUtils;
import org.drools.core.time.impl.CronExpression;
import org.drools.core.time.impl.DefaultJobHandle;
import org.drools.core.time.impl.DefaultTimerJobInstance;
import org.drools.core.util.MVELSafeHelper;
import org.jbpm.process.core.ContextContainer;
import org.jbpm.process.core.context.variable.Variable;
Expand Down Expand Up @@ -345,9 +347,20 @@ private void triggerTimer(TimerInstance timerInstance) {
for (Map.Entry<Timer, DroolsAction> entry : getEventBasedNode().getTimers().entrySet()) {
if (entry.getKey().getId() == timerInstance.getTimerId()) {
executeAction((Action) entry.getValue().getMetaData("Action"));

// self remove timer instance from this node as it will remove itself
// from timer service once is triggered and there is no next
if (!(timerInstance.getJobHandle() instanceof DefaultJobHandle)) {
return;
}
DefaultTimerJobInstance defaultTimerInstance = (DefaultTimerJobInstance) ((DefaultJobHandle) timerInstance.getJobHandle()).getTimerJobInstance();
if (defaultTimerInstance.getTrigger().hasNextFireTime() == null) {
timerInstances.remove(timerInstance.getId());
}
return;
}
}

}

@Override
Expand Down
Expand Up @@ -16,11 +16,6 @@

package org.jbpm.runtime.manager.impl.migration;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -39,7 +34,6 @@
import org.jbpm.services.task.identity.JBossUserGroupCallbackImpl;
import org.jbpm.test.listener.process.NodeLeftCountDownProcessEventListener;
import org.jbpm.test.util.AbstractBaseTest;
import org.kie.test.util.db.PoolingDataSourceWrapper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -63,7 +57,12 @@
import org.kie.internal.runtime.manager.context.EmptyContext;
import org.kie.internal.runtime.manager.context.ProcessInstanceIdContext;
import org.kie.internal.task.api.UserGroupCallback;
import org.kie.test.util.db.PoolingDataSourceWrapper;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.kie.api.runtime.process.ProcessInstance.STATE_ACTIVE;
import static org.kie.api.runtime.process.ProcessInstance.STATE_COMPLETED;

Expand Down Expand Up @@ -566,7 +565,7 @@ public void testMigrateUserTaskCompletedBoundaryTimerProcessInstance() throws Ex
pid = startProcessTillBoundaryTimer(countdownListener);
completeUserTask(managerV1, USER_JOHN);

migrateProcessUserTaskBoundary();
migrateProcessUserTaskBoundary(managerV1);

//Only needs to complete Mary's task after migration
completeUserTask(managerV2, USER_MARY);
Expand All @@ -580,7 +579,7 @@ public void testMigrateUserTaskNotCompletedBoundaryTimerProcessInstance() throws

pid = startProcessTillBoundaryTimer(countdownListener);

migrateProcessUserTaskBoundary();
migrateProcessUserTaskBoundary(managerV1);

//Needs to complete both user tasks after migration
completeUserTask(managerV2, USER_JOHN);
Expand Down Expand Up @@ -669,13 +668,14 @@ private void createRuntimeManager(RuntimeEnvironment environment, RuntimeEnviron

private long startProcessTillBoundaryTimer(NodeLeftCountDownProcessEventListener countdownListener) {
auditService = new JPAAuditLogService(emf);

createRuntimeManagers("migration/v1/BPMN2-UserTaskBoundary-v1.bpmn2", "migration/v2/BPMN2-UserTaskBoundary-v2.bpmn2", countdownListener);
runtime = managerV1.getRuntimeEngine(EmptyContext.get());

long pid = startProcess(runtime, USERTASK_BOUNDARY_TIMER_ID_V1);
checkProcess(pid, USERTASK_BOUNDARY_TIMER_ID_V1, DEPLOYMENT_ID_V1, STATE_ACTIVE);

managerV1.disposeRuntimeEngine(runtime);
//wait for boundary timer
countdownListener.waitTillCompleted();
countdownListener.reset("Goodbye v2", 1);
Expand All @@ -700,11 +700,11 @@ private void checkProcess(long pid, String processId,
assertEquals(status, log.getStatus().intValue());
}

private void migrateProcessUserTaskBoundary() {
managerV1.disposeRuntimeEngine(runtime);

private void migrateProcessUserTaskBoundary(RuntimeManager manager) {
RuntimeEngine runtime = manager.getRuntimeEngine(EmptyContext.get());
manager.disposeRuntimeEngine(runtime);
MigrationSpec migrationSpec = new MigrationSpec(DEPLOYMENT_ID_V1, pid, DEPLOYMENT_ID_V2, USERTASK_BOUNDARY_TIMER_ID_V2);

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

Expand Down

0 comments on commit 4e3295b

Please sign in to comment.