public static MigratingProcessInstanceValidationExceptionDto from(MigratingProcessInstanceValidationException exception) { MigratingProcessInstanceValidationExceptionDto dto = new MigratingProcessInstanceValidationExceptionDto(); dto.message = exception.getMessage(); dto.type = exception.getClass().getSimpleName(); dto.setValidationReport(MigratingProcessInstanceValidationReportDto.from(exception.getValidationReport())); return dto; }
public static MigratingProcessInstanceValidationExceptionDto from(MigratingProcessInstanceValidationException exception) { MigratingProcessInstanceValidationExceptionDto dto = new MigratingProcessInstanceValidationExceptionDto(); dto.message = exception.getMessage(); dto.type = exception.getClass().getSimpleName(); dto.setValidationReport(MigratingProcessInstanceValidationReportDto.from(exception.getValidationReport())); return dto; }
@Test public void testCannotMigrateWhenNotAllActivityInstancesAreMapped() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(ProcessModels.PARALLEL_GATEWAY_PROCESS); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(ProcessModels.PARALLEL_GATEWAY_PROCESS); MigrationPlan migrationPlan = rule.getRuntimeService().createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("userTask1", "userTask1") .build(); // when try { testHelper.createProcessInstanceAndMigrate(migrationPlan); Assert.fail("should not succeed because the userTask2 instance is not mapped"); } catch (MigratingProcessInstanceValidationException e) { assertThat(e.getValidationReport()) .hasActivityInstanceFailures("userTask2", "There is no migration instruction for this instance's activity"); } }
@Test public void testCannotMigrateUnmappedTransitionInstance() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_BEFORE_USER_TASK_PROCESS); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_BEFORE_USER_TASK_PROCESS); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .build(); // when try { testHelper.createProcessInstanceAndMigrate(migrationPlan); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasTransitionInstanceFailures("userTask", "There is no migration instruction for this instance's activity" ); } }
@Test public void testCannotMigrateAsyncBeforeTransitionInstanceToNonAsyncActivity() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_BEFORE_USER_TASK_PROCESS); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(ProcessModels.ONE_TASK_PROCESS); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapEqualActivities() .build(); // when try { testHelper.createProcessInstanceAndMigrate(migrationPlan); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasTransitionInstanceFailures("userTask", "Target activity is not asyncBefore" ); } }
@Test public void testMigrateAsyncBeforeStartEventTransitionInstanceCase2() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_BEFORE_START_EVENT_PROCESS); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_BEFORE_SUBPROCESS_START_EVENT_PROCESS); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("startEvent", "subProcessStart") .build(); // when try { testHelper.createProcessInstanceAndMigrate(migrationPlan); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { assertThat(e.getValidationReport()) .hasTransitionInstanceFailures("startEvent", "A transition instance that instantiates the process can only be migrated to a process-level flow node" ); } }
@Test public void testCannotMigrateActivityInstance() { // given BpmnModelInstance model = ProcessModels.newModel() .startEvent() .serviceTask("serviceTask") .camundaClass(SignallableServiceTaskDelegate.class.getName()) .endEvent() .done(); ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(model); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(model); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("serviceTask", "serviceTask") .build(); // when try { testHelper.createProcessInstanceAndMigrate(migrationPlan); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasActivityInstanceFailures("serviceTask", "The type of the source activity is not supported for activity instance migration" ); } }
@Test public void testCannotMigrateUnmappedTransitionInstanceAtNonLeafActivity() { // given BpmnModelInstance model = modify(ProcessModels.SUBPROCESS_PROCESS) .activityBuilder("subProcess") .camundaAsyncBefore(true) .done(); ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(model); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(model); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .build(); // when try { testHelper.createProcessInstanceAndMigrate(migrationPlan); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasTransitionInstanceFailures("subProcess", "There is no migration instruction for this instance's activity" ); } }
@Test public void testCannotMigrateAsyncAfterTransitionInstanceToNonAsyncActivity() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_AFTER_USER_TASK_PROCESS); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(ProcessModels.ONE_TASK_PROCESS); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("userTask1", "userTask") .build(); ProcessInstance processInstance = rule.getRuntimeService() .startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasTransitionInstanceFailures("userTask1", "Target activity is not asyncAfter" ); } }
@Test public void testCannotMigrateWhenNotAllTransitionInstancesAreMapped() { // given BpmnModelInstance model = ModifiableBpmnModelInstance.modify(ProcessModels.PARALLEL_GATEWAY_PROCESS) .activityBuilder("userTask1") .camundaAsyncBefore() .moveToActivity("userTask2") .camundaAsyncBefore() .done(); ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(model); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(model); MigrationPlan migrationPlan = rule.getRuntimeService().createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("userTask1", "userTask1") .build(); // when try { testHelper.createProcessInstanceAndMigrate(migrationPlan); Assert.fail("should not succeed because the userTask2 instance is not mapped"); } catch (MigratingProcessInstanceValidationException e) { assertThat(e.getValidationReport()) .hasTransitionInstanceFailures("userTask2", "There is no migration instruction for this instance's activity"); } }
@Test public void testCannotRemoveCompensationEventSubscriptions() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.ONE_COMPENSATION_TASK_MODEL); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(ProcessModels.TWO_TASKS_PROCESS); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("userTask2", "userTask2") .build(); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasProcessInstanceId(testHelper.snapshotBeforeMigration.getProcessInstanceId()) .hasActivityInstanceFailures( sourceProcessDefinition.getId(), "Cannot migrate subscription for compensation handler 'compensationHandler'. " + "There is no migration instruction for the compensation boundary event"); } }
@Test public void testCannotMigrateWithoutMappingCompensationBoundaryEvents() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.ONE_COMPENSATION_TASK_MODEL); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.ONE_COMPENSATION_TASK_MODEL); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("userTask2", "userTask2") .build(); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasProcessInstanceId(testHelper.snapshotBeforeMigration.getProcessInstanceId()) .hasActivityInstanceFailures( sourceProcessDefinition.getId(), "Cannot migrate subscription for compensation handler 'compensationHandler'. " + "There is no migration instruction for the compensation boundary event"); } }
@Test public void testCannotMigrateActiveCompensationWithoutInstructionForThrowingEventCase1() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.ONE_COMPENSATION_TASK_MODEL); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.ONE_COMPENSATION_TASK_MODEL); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); testHelper.completeTask("userTask2"); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("compensationHandler", "compensationHandler") .build(); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasProcessInstanceId(testHelper.snapshotBeforeMigration.getProcessInstanceId()) .hasActivityInstanceFailures("compensationEvent", "There is no migration instruction for this instance's activity", "The type of the source activity is not supported for activity instance migration" ); } }
@Test public void testCannotMigrateActiveCompensationWithoutInstructionForThrowingEventCase2() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.COMPENSATION_END_EVENT_MODEL); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.COMPENSATION_END_EVENT_MODEL); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); testHelper.completeTask("userTask2"); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("compensationHandler", "compensationHandler") .build(); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasProcessInstanceId(testHelper.snapshotBeforeMigration.getProcessInstanceId()) .hasActivityInstanceFailures("compensationEvent", "There is no migration instruction for this instance's activity", "The type of the source activity is not supported for activity instance migration" ); } }
@Test public void testCannotMigrateActivityInstanceForCancelEndEvent() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.TRANSACTION_COMPENSATION_MODEL); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.TRANSACTION_COMPENSATION_MODEL); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask"); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("transactionEndEvent", "transactionEndEvent") .mapActivities("compensationHandler", "compensationHandler") .build(); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasProcessInstanceId(testHelper.snapshotBeforeMigration.getProcessInstanceId()) .hasActivityInstanceFailures("transactionEndEvent", "The type of the source activity is not supported for activity instance migration" ); } }
@Test public void testCannotMigrateUnmappedTransitionInstanceWithIncident() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_BEFORE_USER_TASK_PROCESS); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_BEFORE_USER_TASK_PROCESS); // the user task is not mapped in the migration plan, i.e. there is no instruction to migrate the job // and the incident MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .build(); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(migrationPlan.getSourceProcessDefinitionId()); Job job = rule.getManagementService().createJobQuery().singleResult(); rule.getManagementService().setJobRetries(job.getId(), 0); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasTransitionInstanceFailures("userTask", "There is no migration instruction for this instance's activity" ); } }
@Test public void testCannotMigrateActivityInstanceForCompensationThrowingEvent() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.ONE_COMPENSATION_TASK_MODEL); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.ONE_COMPENSATION_TASK_MODEL); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); testHelper.completeTask("userTask2"); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("compensationEvent", "compensationEvent") .mapActivities("compensationHandler", "compensationHandler") .build(); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasProcessInstanceId(testHelper.snapshotBeforeMigration.getProcessInstanceId()) .hasActivityInstanceFailures("compensationEvent", "The type of the source activity is not supported for activity instance migration" ); } }
@Test public void testCannotMigrateWithoutCompensationStartEventCase1() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.COMPENSATION_EVENT_SUBPROCESS_MODEL); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(CompensationModels.COMPENSATION_EVENT_SUBPROCESS_MODEL); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("subProcess", "subProcess") .mapActivities("userTask2", "userTask2") .mapActivities("compensationBoundary", "compensationBoundary") .build(); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasProcessInstanceId(testHelper.snapshotBeforeMigration.getProcessInstanceId()) .hasActivityInstanceFailures(sourceProcessDefinition.getId(), "Cannot migrate subscription for compensation handler 'eventSubProcess'. " + "There is no migration instruction for the compensation start event"); } }
@Test public void testCannotMigrateWithoutCompensationStartEventCase2() { // given BpmnModelInstance model = modify(CompensationModels.COMPENSATION_EVENT_SUBPROCESS_MODEL) .removeFlowNode("compensationBoundary"); ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(model); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(model); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("subProcess", "subProcess") .mapActivities("userTask2", "userTask2") .build(); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { // then assertThat(e.getValidationReport()) .hasProcessInstanceId(testHelper.snapshotBeforeMigration.getProcessInstanceId()) .hasActivityInstanceFailures(sourceProcessDefinition.getId(), "Cannot migrate subscription for compensation handler 'eventSubProcess'. " + "There is no migration instruction for the compensation start event"); } }
@Test public void testMigrateAsyncAfterTransitionInstanceAddOutgoingFlowCase3() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(AsyncProcessModels.ASYNC_AFTER_USER_TASK_PROCESS); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(modify(AsyncProcessModels.ASYNC_AFTER_USER_TASK_PROCESS) .changeElementId("flow1", "flow2") .activityBuilder("userTask1") .sequenceFlowId("flow3") .userTask("userTask3") .endEvent() .done()); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapEqualActivities() .build(); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); testHelper.completeTask("userTask1"); // when try { testHelper.migrateProcessInstance(migrationPlan, processInstance); Assert.fail("should fail"); } catch (MigratingProcessInstanceValidationException e) { assertThat(e.getValidationReport()) .hasTransitionInstanceFailures("userTask1", "Transition instance is assigned to a sequence flow that cannot be matched in the target activity" ); } }