/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jbpm.kie.services.impl.admin; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.kie.scanner.MavenRepository.getMavenRepository; import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.drools.compiler.kie.builder.impl.InternalKieModule; import org.jbpm.kie.services.impl.KModuleDeploymentUnit; import org.jbpm.kie.services.test.KModuleDeploymentServiceTest; import org.jbpm.kie.test.util.AbstractKieServicesBaseTest; import org.jbpm.services.api.admin.MigrationReport; import org.jbpm.services.api.admin.ProcessInstanceMigrationService; import org.jbpm.services.api.model.DeploymentUnit; import org.jbpm.services.api.model.ProcessInstanceDesc; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.kie.api.KieServices; import org.kie.api.builder.ReleaseId; import org.kie.api.runtime.process.ProcessInstance; import org.kie.api.task.model.Status; import org.kie.api.task.model.TaskSummary; import org.kie.internal.query.QueryFilter; import org.kie.scanner.MavenRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ProcessInstanceMigrationServiceImplTest extends AbstractKieServicesBaseTest { private static final Logger logger = LoggerFactory.getLogger(KModuleDeploymentServiceTest.class); protected static final String MIGRATION_ARTIFACT_ID = "test-migration"; protected static final String MIGRATION_GROUP_ID = "org.jbpm.test"; protected static final String MIGRATION_VERSION_V1 = "1.0.0"; protected static final String MIGRATION_VERSION_V2 = "2.0.0"; private List<DeploymentUnit> units = new ArrayList<DeploymentUnit>(); private KModuleDeploymentUnit deploymentUnitV1; private KModuleDeploymentUnit deploymentUnitV2; protected ProcessInstanceMigrationService migrationService; @Before public void prepare() { configureServices(); logger.debug("Preparing kjar"); KieServices ks = KieServices.Factory.get(); // version 1 of kjar ReleaseId releaseId = ks.newReleaseId(MIGRATION_GROUP_ID, MIGRATION_ARTIFACT_ID, MIGRATION_VERSION_V1); List<String> processes = new ArrayList<String>(); processes.add("migration/v1/AddTaskAfterActive-v1.bpmn2"); processes.add("migration/v1/RemoveActiveTask-v1.bpmn2"); InternalKieModule kJar1 = createKieJar(ks, releaseId, processes); File pom = new File("target/migration-v1", "pom.xml"); pom.getParentFile().mkdir(); try { FileOutputStream fs = new FileOutputStream(pom); fs.write(getPom(releaseId).getBytes()); fs.close(); } catch (Exception e) { } MavenRepository repository = getMavenRepository(); repository.installArtifact(releaseId, kJar1, pom); // version 2 of kjar ReleaseId releaseId2 = ks.newReleaseId(MIGRATION_GROUP_ID, MIGRATION_ARTIFACT_ID, MIGRATION_VERSION_V2); processes = new ArrayList<String>(); processes.add("migration/v2/AddTaskAfterActive-v2.bpmn2"); processes.add("migration/v2/RemoveActiveTask-v2.bpmn2"); InternalKieModule kJar2 = createKieJar(ks, releaseId2, processes); File pom2 = new File("target/migration-v2", "pom.xml"); pom2.getParentFile().mkdirs(); try { FileOutputStream fs = new FileOutputStream(pom2); fs.write(getPom(releaseId2).getBytes()); fs.close(); } catch (Exception e) { } repository = getMavenRepository(); repository.installArtifact(releaseId2, kJar2, pom2); migrationService = new ProcessInstanceMigrationServiceImpl(); // now let's deploy to runtime both kjars deploymentUnitV1 = new KModuleDeploymentUnit(MIGRATION_GROUP_ID, MIGRATION_ARTIFACT_ID, MIGRATION_VERSION_V1); deploymentService.deploy(deploymentUnitV1); units.add(deploymentUnitV1); deploymentUnitV2 = new KModuleDeploymentUnit(MIGRATION_GROUP_ID, MIGRATION_ARTIFACT_ID, MIGRATION_VERSION_V2); deploymentService.deploy(deploymentUnitV2); units.add(deploymentUnitV2); } @After public void cleanup() { cleanupSingletonSessionId(); if (units != null && !units.isEmpty()) { for (DeploymentUnit unit : units) { try { deploymentService.undeploy(unit); } catch (Exception e) { // do nothing in case of some failed tests to avoid next test to fail as well } } units.clear(); } close(); } public void setMigrationService(ProcessInstanceMigrationService migrationService) { this.migrationService = migrationService; } private static final String ADDTASKAFTERACTIVE_ID_V1 = "process-migration-testv1.AddTaskAfterActive"; private static final String ADDTASKAFTERACTIVE_ID_V2 = "process-migration-testv2.AddTaskAfterActive"; @Test public void testMigrateSingleProcessInstance() { long processInstanceId = processService.startProcess(deploymentUnitV1.getIdentifier(), ADDTASKAFTERACTIVE_ID_V1); assertNotNull(processInstanceId); MigrationReport report = migrationService.migrate(deploymentUnitV1.getIdentifier(), processInstanceId, deploymentUnitV2.getIdentifier(), ADDTASKAFTERACTIVE_ID_V2); assertNotNull(report); assertTrue(report.isSuccessful()); assertMigratedProcessInstance(ADDTASKAFTERACTIVE_ID_V2, processInstanceId, ProcessInstance.STATE_ACTIVE); assertMigratedTaskAndComplete(ADDTASKAFTERACTIVE_ID_V2, processInstanceId, "Active Task"); assertMigratedTaskAndComplete(ADDTASKAFTERACTIVE_ID_V2, processInstanceId, "Added Task"); assertMigratedProcessInstance(ADDTASKAFTERACTIVE_ID_V2, processInstanceId, ProcessInstance.STATE_COMPLETED); } @Test public void testMigrateMultipleProcessInstances() { List<Long> ids = new ArrayList<Long>(); for (int i = 0; i < 5; i++) { long processInstanceId = processService.startProcess(deploymentUnitV1.getIdentifier(), ADDTASKAFTERACTIVE_ID_V1); assertNotNull(processInstanceId); ids.add(processInstanceId); } List<MigrationReport> reports = migrationService.migrate(deploymentUnitV1.getIdentifier(), ids, deploymentUnitV2.getIdentifier(), ADDTASKAFTERACTIVE_ID_V2); assertNotNull(reports); Iterator<MigrationReport> reportsIt = reports.iterator(); for (Long processInstanceId : ids) { MigrationReport report = reportsIt.next(); assertTrue(report.isSuccessful()); assertMigratedProcessInstance(ADDTASKAFTERACTIVE_ID_V2, processInstanceId, ProcessInstance.STATE_ACTIVE); assertMigratedTaskAndComplete(ADDTASKAFTERACTIVE_ID_V2, processInstanceId, "Active Task"); assertMigratedTaskAndComplete(ADDTASKAFTERACTIVE_ID_V2, processInstanceId, "Added Task"); assertMigratedProcessInstance(ADDTASKAFTERACTIVE_ID_V2, processInstanceId, ProcessInstance.STATE_COMPLETED); } } private static final String REMOVEACTIVETASK_ID_V1 = "process-migration-testv1.RemoveActiveTask"; private static final String REMOVEACTIVETASK_ID_V2 = "process-migration-testv2.RemoveActiveTask"; @Test public void testMigrateSingleProcessInstanceWithNodeMapping() { String activeNodeId = "_ECEDD1CE-7380-418C-B7A6-AF8ECB90B820"; String nextNodeId = "_9EF3CAE0-D978-4E96-9C00-8A80082EB68E"; Map<String, String> nodeMapping = new HashMap<String, String>(); nodeMapping.put(activeNodeId, nextNodeId); long processInstanceId = processService.startProcess(deploymentUnitV1.getIdentifier(), REMOVEACTIVETASK_ID_V1); assertNotNull(processInstanceId); MigrationReport report = migrationService.migrate(deploymentUnitV1.getIdentifier(), processInstanceId, deploymentUnitV2.getIdentifier(), REMOVEACTIVETASK_ID_V2, nodeMapping); assertNotNull(report); assertTrue(report.isSuccessful()); assertMigratedProcessInstance(REMOVEACTIVETASK_ID_V2, processInstanceId, ProcessInstance.STATE_ACTIVE); assertMigratedTaskAndComplete(REMOVEACTIVETASK_ID_V2, processInstanceId, "Mapped Task"); assertMigratedProcessInstance(REMOVEACTIVETASK_ID_V2, processInstanceId, ProcessInstance.STATE_COMPLETED); } @Test public void testMigrateMultipleProcessInstancesWithNodeMapping() { List<Long> ids = new ArrayList<Long>(); for (int i = 0; i < 5; i++) { long processInstanceId = processService.startProcess(deploymentUnitV1.getIdentifier(), REMOVEACTIVETASK_ID_V1); assertNotNull(processInstanceId); ids.add(processInstanceId); } String activeNodeId = "_ECEDD1CE-7380-418C-B7A6-AF8ECB90B820"; String nextNodeId = "_9EF3CAE0-D978-4E96-9C00-8A80082EB68E"; Map<String, String> nodeMapping = new HashMap<String, String>(); nodeMapping.put(activeNodeId, nextNodeId); List<MigrationReport> reports = migrationService.migrate(deploymentUnitV1.getIdentifier(), ids, deploymentUnitV2.getIdentifier(), REMOVEACTIVETASK_ID_V2, nodeMapping); assertNotNull(reports); Iterator<MigrationReport> reportsIt = reports.iterator(); for (Long processInstanceId : ids) { MigrationReport report = reportsIt.next(); assertTrue(report.isSuccessful()); assertMigratedProcessInstance(REMOVEACTIVETASK_ID_V2, processInstanceId, ProcessInstance.STATE_ACTIVE); assertMigratedTaskAndComplete(REMOVEACTIVETASK_ID_V2, processInstanceId, "Mapped Task"); assertMigratedProcessInstance(REMOVEACTIVETASK_ID_V2, processInstanceId, ProcessInstance.STATE_COMPLETED); } } /* * Helper methods */ protected void assertMigratedTaskAndComplete(String processId, Long processInstanceId, String taskName) { List<TaskSummary> tasks = runtimeDataService.getTasksByStatusByProcessInstanceId(processInstanceId, Arrays.asList(Status.Reserved), new QueryFilter()); assertNotNull(tasks); assertEquals(1, tasks.size()); TaskSummary task = tasks.get(0); assertNotNull(task); assertEquals(processId, task.getProcessId()); assertEquals(deploymentUnitV2.getIdentifier(), task.getDeploymentId()); assertEquals(taskName, task.getName()); userTaskService.completeAutoProgress(task.getId(), "john", null); } protected void assertMigratedProcessInstance(String processId, long processInstanceId, int status) { ProcessInstanceDesc instance = runtimeDataService.getProcessInstanceById(processInstanceId); assertNotNull(instance); assertEquals(processId, instance.getProcessId()); assertEquals(deploymentUnitV2.getIdentifier(), instance.getDeploymentId()); assertEquals(status, instance.getState().intValue()); } }