From 253fb4591f33d3b219ed16ea42f0e7df19befdf8 Mon Sep 17 00:00:00 2001 From: Simon Amport <10498683+amporsim@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:23:13 +0100 Subject: [PATCH] Fix: Add tenantId to the batch jobs where required (#3982) --- .../entity/BatchPartEntityManagerImpl.java | 3 + .../CaseInstanceMigrationManagerImpl.java | 6 + .../migration/AbstractCaseMigrationTest.java | 13 ++ .../CaseInstanceMigrationBatchTest.java | 76 +++++++++++ .../ProcessInstanceMigrationManagerImpl.java | 14 +- .../impl/test/AbstractFlowableTestCase.java | 15 +++ .../ProcessInstanceMigrationBatchTest.java | 124 ++++++++++++++++++ 7 files changed, 247 insertions(+), 4 deletions(-) diff --git a/modules/flowable-batch-service/src/main/java/org/flowable/batch/service/impl/persistence/entity/BatchPartEntityManagerImpl.java b/modules/flowable-batch-service/src/main/java/org/flowable/batch/service/impl/persistence/entity/BatchPartEntityManagerImpl.java index 13948540360..0d81676e0f6 100644 --- a/modules/flowable-batch-service/src/main/java/org/flowable/batch/service/impl/persistence/entity/BatchPartEntityManagerImpl.java +++ b/modules/flowable-batch-service/src/main/java/org/flowable/batch/service/impl/persistence/entity/BatchPartEntityManagerImpl.java @@ -70,6 +70,9 @@ public BatchPartEntity createBatchPart(BatchEntity parentBatch, String status, S batchPartEntity.setBatchSearchKey(parentBatch.getBatchSearchKey()); batchPartEntity.setBatchSearchKey2(parentBatch.getBatchSearchKey2()); batchPartEntity.setStatus(status); + if (parentBatch.getTenantId() != null) { + batchPartEntity.setTenantId(parentBatch.getTenantId()); + } batchPartEntity.setCreateTime(getClock().getCurrentTime()); insert(batchPartEntity); diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java index 8acd0919890..7d331148523 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java @@ -478,6 +478,7 @@ public Batch batchMigrateCaseInstancesOfCaseDefinition(String caseDefinitionId, .searchKey2(caseDefinition.getId()) .status(CaseInstanceBatchMigrationResult.STATUS_IN_PROGRESS) .batchDocumentJson(document.asJsonString()) + .tenantId(caseDefinition.getTenantId()) .create(); JobService jobService = engineConfiguration.getJobServiceConfiguration().getJobService(); @@ -487,6 +488,7 @@ public Batch batchMigrateCaseInstancesOfCaseDefinition(String caseDefinitionId, JobEntity job = jobService.createJob(); job.setJobHandlerType(CaseInstanceMigrationJobHandler.TYPE); + job.setTenantId(caseInstance.getTenantId()); job.setScopeId(caseInstance.getId()); job.setScopeType(ScopeTypes.CMMN); job.setJobHandlerConfiguration(CaseInstanceMigrationJobHandler.getHandlerCfgForBatchPartId(batchPart.getId())); @@ -499,6 +501,7 @@ public Batch batchMigrateCaseInstancesOfCaseDefinition(String caseDefinitionId, TimerJobService timerJobService = engineConfiguration.getJobServiceConfiguration().getTimerJobService(); TimerJobEntity timerJob = timerJobService.createTimerJob(); timerJob.setJobType(JobEntity.JOB_TYPE_TIMER); + timerJob.setTenantId(batch.getTenantId()); timerJob.setRevision(1); timerJob.setRetries(0); timerJob.setJobHandlerType(CaseInstanceMigrationStatusJobHandler.TYPE); @@ -530,6 +533,7 @@ public Batch batchMigrateHistoricCaseInstancesOfCaseDefinition(String caseDefini .searchKey2(caseDefinition.getId()) .status(CaseInstanceBatchMigrationResult.STATUS_IN_PROGRESS) .batchDocumentJson(document.asJsonString()) + .tenantId(caseDefinition.getTenantId()) .create(); JobService jobService = engineConfiguration.getJobServiceConfiguration().getJobService(); @@ -542,6 +546,7 @@ public Batch batchMigrateHistoricCaseInstancesOfCaseDefinition(String caseDefini job.setScopeId(historicCaseInstance.getId()); job.setScopeType(ScopeTypes.CMMN); job.setJobHandlerConfiguration(HistoricCaseInstanceMigrationJobHandler.getHandlerCfgForBatchPartId(batchPart.getId())); + job.setTenantId(historicCaseInstance.getTenantId()); jobService.createAsyncJob(job, false); jobService.scheduleAsyncJob(job); } @@ -554,6 +559,7 @@ public Batch batchMigrateHistoricCaseInstancesOfCaseDefinition(String caseDefini timerJob.setJobHandlerType(CaseInstanceMigrationStatusJobHandler.TYPE); timerJob.setJobHandlerConfiguration(HistoricCaseInstanceMigrationJobHandler.getHandlerCfgForBatchId(batch.getId())); timerJob.setScopeType(ScopeTypes.CMMN); + timerJob.setTenantId(batch.getTenantId()); BusinessCalendar businessCalendar = engineConfiguration.getBusinessCalendarManager().getBusinessCalendar(CycleBusinessCalendar.NAME); timerJob.setDuedate(businessCalendar.resolveDuedate(engineConfiguration.getBatchStatusTimeCycleConfig())); diff --git a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/AbstractCaseMigrationTest.java b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/AbstractCaseMigrationTest.java index c049c3bf987..2e03f9c5dda 100644 --- a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/AbstractCaseMigrationTest.java +++ b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/AbstractCaseMigrationTest.java @@ -73,4 +73,17 @@ protected CaseDefinition deployCaseDefinition(String name, String path) { .singleResult(); } + protected CaseDefinition deployCaseDefinition(String name, String path, String tenantId) { + CmmnDeployment deployment = cmmnRepositoryService.createDeployment() + .name(name) + .addClasspathResource(path) + .tenantId(tenantId) + .deploy(); + + return cmmnRepositoryService.createCaseDefinitionQuery() + .deploymentId(deployment.getId()) + .caseDefinitionTenantId(tenantId) + .singleResult(); + } + } diff --git a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationBatchTest.java b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationBatchTest.java index 596346cf036..022a6cb83d9 100644 --- a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationBatchTest.java +++ b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationBatchTest.java @@ -113,6 +113,82 @@ void testCaseInstanceBatchMigrationSuccess() { cmmnManagementService.deleteBatch(batch.getId()); } + @Test + void testCaseInstanceBatchMigrationWithTenant() { + // GIVEN + CaseDefinition sourceCaseDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/one-task.cmmn.xml", "acme"); + CaseInstance caseInstance1 = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").tenantId("acme").start(); + CaseInstance caseInstance2 = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").tenantId("acme").start(); + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/two-task.cmmn.xml", "acme"); + + CaseInstanceMigrationDocumentBuilder migrationDoc = new CaseInstanceMigrationDocumentBuilderImpl() + .setCaseDefinitionToMigrateTo(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask2")); + + Batch batch = cmmnMigrationService.createCaseInstanceMigrationBuilderFromCaseInstanceMigrationDocument(migrationDoc.build()) + .batchMigrateCaseInstances(sourceCaseDefinition.getId()); + + assertThat(CmmnJobTestHelper.areJobsAvailable(cmmnManagementService)).isTrue(); + + CaseInstanceBatchMigrationResult migrationResultPriorProcessing = cmmnMigrationService.getResultsOfBatchCaseInstanceMigration(batch.getId()); + + // assert created migration result and parts + assertThat(migrationResultPriorProcessing).isNotNull(); + assertThat(migrationResultPriorProcessing.getBatchId()).isEqualTo(batch.getId()); + assertThat(migrationResultPriorProcessing.getStatus()).isEqualTo(CaseInstanceBatchMigrationResult.STATUS_IN_PROGRESS); + assertThat(migrationResultPriorProcessing.getCompleteTime()).isNull(); + assertThat(migrationResultPriorProcessing.getAllMigrationParts()).hasSize(2); + assertThat(migrationResultPriorProcessing.getWaitingMigrationParts()).hasSize(2); + assertThat(migrationResultPriorProcessing.getSuccessfulMigrationParts()).isEmpty(); + assertThat(migrationResultPriorProcessing.getFailedMigrationParts()).isEmpty(); + + for (CaseInstanceBatchMigrationPartResult part : migrationResultPriorProcessing.getAllMigrationParts()) { + assertThat(part.getStatus()).isEqualTo(CaseInstanceBatchMigrationResult.STATUS_WAITING); + assertThat(part.getResult()).isEqualTo(CaseInstanceBatchMigrationResult.STATUS_WAITING); + } + + // WHEN + // We are manually executing because on SQL Server on our CI there is a deadlock exception from SQL Server when multiple threads run + for (Job job : cmmnManagementService.createJobQuery().handlerType(CaseInstanceMigrationJobHandler.TYPE).jobTenantId("acme").list()) { + cmmnManagementService.executeJob(job.getId()); + } + assertThat(CmmnJobTestHelper.areJobsAvailable(cmmnManagementService)).isFalse(); + executeMigrationJobStatusHandlerTimerJob(); + + // THEN + CaseInstanceBatchMigrationResult migrationResult = cmmnMigrationService.getResultsOfBatchCaseInstanceMigration(batch.getId()); + assertThat(migrationResult).isNotNull(); + assertThat(migrationResult.getBatchId()).isEqualTo(batch.getId()); + assertThat(migrationResult.getStatus()).isEqualTo(CaseInstanceBatchMigrationResult.STATUS_COMPLETED); + + CaseInstance caseInstance1AfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance1.getId()) + .caseInstanceTenantId("acme") + .singleResult(); + CaseInstance caseInstance2AfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance2.getId()) + .caseInstanceTenantId("acme") + .singleResult(); + + for (CaseInstanceBatchMigrationPartResult part : migrationResult.getAllMigrationParts()) { + assertThat(part.getStatus()).isEqualTo(CaseInstanceBatchMigrationResult.STATUS_COMPLETED); + assertThat(part.getResult()).isEqualTo(CaseInstanceBatchMigrationResult.RESULT_SUCCESS); + } + + assertThat(cmmnManagementService.createJobQuery().scopeId(caseInstance1.getId()).jobTenantId("acme").list()).hasSize(0); + assertThat(cmmnManagementService.createTimerJobQuery().scopeId(caseInstance1.getId()).jobTenantId("acme").list()).hasSize(0); + assertThat(cmmnManagementService.createDeadLetterJobQuery().scopeId(caseInstance1.getId()).jobTenantId("acme").list()).hasSize(0); + + assertThat(cmmnManagementService.createJobQuery().scopeId(caseInstance2.getId()).jobTenantId("acme").list()).hasSize(0); + assertThat(cmmnManagementService.createTimerJobQuery().scopeId(caseInstance2.getId()).jobTenantId("acme").list()).hasSize(0); + assertThat(cmmnManagementService.createDeadLetterJobQuery().scopeId(caseInstance2.getId()).jobTenantId("acme").list()).hasSize(0); + + assertAfterMigrationState(caseInstance1, destinationDefinition, caseInstance1AfterMigration, 2); + assertAfterMigrationState(caseInstance2, destinationDefinition, caseInstance2AfterMigration, 2); + + cmmnManagementService.deleteBatch(batch.getId()); + } + @Test void testCaseInstanceBatchMigrationWithError() { // GIVEN diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationManagerImpl.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationManagerImpl.java index 3298b85a7b0..33b057d9ac2 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationManagerImpl.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationManagerImpl.java @@ -27,6 +27,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.flowable.batch.api.Batch; +import org.flowable.batch.api.BatchBuilder; import org.flowable.batch.api.BatchPart; import org.flowable.batch.api.BatchService; import org.flowable.bpmn.model.Activity; @@ -332,13 +333,16 @@ public Batch batchMigrateProcessInstancesOfProcessDefinition(String sourceProcDe new ProcessInstanceQueryImpl(commandContext, processEngineConfiguration).processDefinitionId(sourceProcDefId)); BatchService batchService = processEngineConfiguration.getBatchServiceConfiguration().getBatchService(); - Batch batch = batchService.createBatchBuilder().batchType(Batch.PROCESS_MIGRATION_TYPE) + BatchBuilder batchBuilder = batchService.createBatchBuilder().batchType(Batch.PROCESS_MIGRATION_TYPE) .searchKey(sourceProcDefId) .searchKey2(targetProcessDefinition.getId()) .status(ProcessInstanceBatchMigrationResult.STATUS_IN_PROGRESS) - .batchDocumentJson(document.asJsonString()) - .create(); - + .batchDocumentJson(document.asJsonString()); + if (targetProcessDefinition.getTenantId() != null) { + batchBuilder.tenantId(targetProcessDefinition.getTenantId()); + } + Batch batch = batchBuilder.create(); + JobService jobService = processEngineConfiguration.getJobServiceConfiguration().getJobService(); for (ProcessInstance processInstance : processInstances) { BatchPart batchPart = batchService.createBatchPart(batch, ProcessInstanceBatchMigrationResult.STATUS_WAITING, @@ -348,6 +352,7 @@ public Batch batchMigrateProcessInstancesOfProcessDefinition(String sourceProcDe job.setJobHandlerType(ProcessInstanceMigrationJobHandler.TYPE); job.setProcessInstanceId(processInstance.getId()); job.setJobHandlerConfiguration(ProcessInstanceMigrationJobHandler.getHandlerCfgForBatchPartId(batchPart.getId())); + job.setTenantId(processInstance.getTenantId()); jobService.createAsyncJob(job, false); job.setRetries(0); jobService.scheduleAsyncJob(job); @@ -361,6 +366,7 @@ public Batch batchMigrateProcessInstancesOfProcessDefinition(String sourceProcDe timerJob.setRetries(0); timerJob.setJobHandlerType(ProcessInstanceMigrationStatusJobHandler.TYPE); timerJob.setJobHandlerConfiguration(ProcessInstanceMigrationJobHandler.getHandlerCfgForBatchId(batch.getId())); + timerJob.setTenantId(batch.getTenantId()); BusinessCalendar businessCalendar = processEngineConfiguration.getBusinessCalendarManager().getBusinessCalendar(CycleBusinessCalendar.NAME); timerJob.setDuedate(businessCalendar.resolveDuedate(processEngineConfiguration.getBatchStatusTimeCycleConfig())); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/test/AbstractFlowableTestCase.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/test/AbstractFlowableTestCase.java index 777568a7123..249a40b38be 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/test/AbstractFlowableTestCase.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/test/AbstractFlowableTestCase.java @@ -509,6 +509,21 @@ protected ProcessDefinition deployProcessDefinition(String name, String path) { return processDefinition; } + protected ProcessDefinition deployProcessDefinition(String name, String path, String tenantId) { + Deployment deployment = repositoryService.createDeployment() + .name(name) + .addClasspathResource(path) + .tenantId(tenantId) + .deploy(); + + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() + .deploymentId(deployment.getId()) + .processDefinitionTenantId(tenantId) + .singleResult(); + + return processDefinition; + } + protected void completeProcessInstanceTasks(String processInstanceId) { List tasks; do { diff --git a/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/runtime/migration/ProcessInstanceMigrationBatchTest.java b/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/runtime/migration/ProcessInstanceMigrationBatchTest.java index 58904a701a7..3005040a9d3 100644 --- a/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/runtime/migration/ProcessInstanceMigrationBatchTest.java +++ b/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/runtime/migration/ProcessInstanceMigrationBatchTest.java @@ -71,6 +71,130 @@ protected void tearDown() { deleteDeployments(); } + @Test + public void testProcessMigrationBatchWithTenant() { + ProcessDefinition version1ProcessDef = deployProcessDefinition("my deploy", + "org/flowable/engine/test/api/runtime/migration/two-tasks-simple-process.bpmn20.xml", "acme"); + + // Start and instance of the recent first version of the process for migration and one for reference + ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKeyAndTenantId("MP", "acme"); + ProcessInstance processInstance2 = runtimeService.startProcessInstanceByKeyAndTenantId("MP", "acme"); + + Task task = taskService.createTaskQuery().taskTenantId("acme").processInstanceId(processInstance1.getId()).singleResult(); + completeTask(task); + task = taskService.createTaskQuery().taskTenantId("acme").processInstanceId(processInstance2.getId()).singleResult(); + completeTask(task); + + task = taskService.createTaskQuery().taskTenantId("acme").processInstanceId(processInstance1.getId()).singleResult(); + assertThat(task.getTaskDefinitionKey()).isEqualTo("userTask2Id"); + assertThat(task.getProcessDefinitionId()).isEqualTo(version1ProcessDef.getId()); + task = taskService.createTaskQuery().taskTenantId("acme").processInstanceId(processInstance2.getId()).singleResult(); + assertThat(task.getTaskDefinitionKey()).isEqualTo("userTask2Id"); + assertThat(task.getProcessDefinitionId()).isEqualTo(version1ProcessDef.getId()); + + // Deploy second version of the process + ProcessDefinition version2ProcessDef = deployProcessDefinition("my deploy", + "org/flowable/engine/test/api/runtime/migration/one-task-simple-process.bpmn20.xml", "acme"); + + List processDefinitions = repositoryService.createProcessDefinitionQuery() + .processDefinitionTenantId("acme") + .processDefinitionKey("MP") + .list(); + + processDefinitions.sort(Comparator.comparingInt(ProcessDefinition::getVersion)); + assertThat(processDefinitions) + .extracting(ProcessDefinition::getId) + .containsExactly(version1ProcessDef.getId(), version2ProcessDef.getId()); + + // Prepare the process Instance migration builder as usual + ProcessInstanceMigrationBuilder processInstanceMigrationBuilder = processMigrationService.createProcessInstanceMigrationBuilder() + .migrateToProcessDefinition(version2ProcessDef.getId()); + + // Try batch migrate the process instances + Batch migrationBatch = processInstanceMigrationBuilder.batchMigrateProcessInstances(version1ProcessDef.getId()); + assertThat(JobTestHelper.areJobsAvailable(managementService)).isTrue(); + + // Confirm the batch is not finished + ProcessInstanceBatchMigrationResult migrationResult = processMigrationService.getResultsOfBatchProcessInstanceMigration(migrationBatch.getId()); + + // Partial Results + assertThat(migrationResult).isNotNull(); + assertThat(migrationResult.getBatchId()).isEqualTo(migrationBatch.getId()); + assertThat(migrationResult.getStatus()).isEqualTo(ProcessInstanceBatchMigrationResult.STATUS_IN_PROGRESS); + assertThat(migrationResult.getCompleteTime()).isNull(); + assertThat(migrationResult.getAllMigrationParts()).hasSize(2); + assertThat(migrationResult.getWaitingMigrationParts()).hasSize(2); + assertThat(migrationResult.getSuccessfulMigrationParts()).isEmpty(); + assertThat(migrationResult.getFailedMigrationParts()).isEmpty(); + + for (ProcessInstanceBatchMigrationPartResult part : migrationResult.getAllMigrationParts()) { + assertThat(part.getStatus()).isEqualTo(ProcessInstanceBatchMigrationResult.STATUS_WAITING); + assertThat(part.getResult()).isEqualTo(ProcessInstanceBatchMigrationResult.STATUS_WAITING); + } + + // Start async executor to process the batches + JobTestHelper.waitForJobExecutorToProcessAllJobs(processEngineConfiguration, managementService, 1000L, 500L, true); + assertThat(JobTestHelper.areJobsAvailable(managementService)).isFalse(); + + List timerJobs = managementService.createTimerJobQuery().jobTenantId("acme").handlerType(ProcessInstanceMigrationStatusJobHandler.TYPE).list(); + for (Job timerJob : timerJobs) { + Job executableJob = managementService.moveTimerToExecutableJob(timerJob.getId()); + managementService.executeJob(executableJob.getId()); + } + + // Confirm the batches have ended + migrationResult = processMigrationService.getResultsOfBatchProcessInstanceMigration(migrationBatch.getId()); + assertThat(migrationResult).isNotNull(); + + assertThat(migrationResult.getBatchId()).isEqualTo(migrationBatch.getId()); + assertThat(migrationResult.getStatus()).isEqualTo(ProcessInstanceBatchMigrationResult.STATUS_COMPLETED); + assertThat(migrationResult.getCompleteTime()).isNotNull(); + assertThat(migrationResult.getAllMigrationParts()).hasSize(2); + assertThat(migrationResult.getWaitingMigrationParts()).isEmpty(); + assertThat(migrationResult.getSuccessfulMigrationParts()).isEmpty(); + assertThat(migrationResult.getFailedMigrationParts()).hasSize(2); + + for (ProcessInstanceBatchMigrationPartResult part : migrationResult.getAllMigrationParts()) { + assertThat(part.getStatus()).isEqualTo(ProcessInstanceBatchMigrationResult.STATUS_COMPLETED); + assertThat(part.getResult()).isEqualTo(ProcessInstanceBatchMigrationResult.RESULT_FAIL); + assertThat(part.getMigrationMessage()).isEqualTo("Migration Activity mapping missing for activity definition Id:'userTask2Id' or its MI Parent"); + } + + // Confirm no migration happened + task = taskService.createTaskQuery().taskTenantId("acme").processInstanceId(processInstance1.getId()).singleResult(); + assertThat(task.getTaskDefinitionKey()).isEqualTo("userTask2Id"); + assertThat(task.getProcessDefinitionId()).isEqualTo(version1ProcessDef.getId()); + List childExecutions = runtimeService.createExecutionQuery().processInstanceId(processInstance1.getId()).list(); + assertThat(childExecutions).hasSize(2); + for (Execution childExecution : childExecutions) { + assertThat(((ExecutionEntity) childExecution).getProcessDefinitionId()).isEqualTo(version1ProcessDef.getId()); + } + + task = taskService.createTaskQuery().taskTenantId("acme").processInstanceId(processInstance2.getId()).singleResult(); + assertThat(task.getTaskDefinitionKey()).isEqualTo("userTask2Id"); + assertThat(task.getProcessDefinitionId()).isEqualTo(version1ProcessDef.getId()); + childExecutions = runtimeService.createExecutionQuery().executionTenantId("acme").processInstanceId(processInstance2.getId()).list(); + assertThat(childExecutions).hasSize(2); + for (Execution childExecution : childExecutions) { + assertThat(((ExecutionEntity) childExecution).getProcessDefinitionId()).isEqualTo(version1ProcessDef.getId()); + } + + assertThat(managementService.createJobQuery().jobTenantId("acme").processInstanceId(processInstance1.getId()).list()).hasSize(0); + assertThat(managementService.createTimerJobQuery().jobTenantId("acme").processInstanceId(processInstance1.getId()).list()).hasSize(0); + assertThat(managementService.createDeadLetterJobQuery().jobTenantId("acme").processInstanceId(processInstance1.getId()).list()).hasSize(0); + + assertThat(managementService.createJobQuery().jobTenantId("acme").processInstanceId(processInstance2.getId()).list()).hasSize(0); + assertThat(managementService.createTimerJobQuery().jobTenantId("acme").processInstanceId(processInstance2.getId()).list()).hasSize(0); + assertThat(managementService.createDeadLetterJobQuery().jobTenantId("acme").processInstanceId(processInstance2.getId()).list()).hasSize(0); + + completeProcessInstanceTasks(processInstance1.getId()); + completeProcessInstanceTasks(processInstance2.getId()); + assertProcessEnded(processInstance1.getId()); + assertProcessEnded(processInstance2.getId()); + + managementService.deleteBatch(migrationBatch.getId()); + } + @Test public void testProcessMigrationBatchMissingMapping() { // Deploy first version of the process