|
| 1 | +package org.cloudfoundry.multiapps.controller.process.flowable; |
| 2 | + |
| 3 | +import java.util.HashMap; |
| 4 | +import java.util.List; |
| 5 | +import java.util.Map; |
| 6 | +import javax.sql.DataSource; |
| 7 | + |
| 8 | +import org.cloudfoundry.multiapps.common.util.JsonSerializationStrategy; |
| 9 | +import org.cloudfoundry.multiapps.common.util.JsonUtil; |
| 10 | +import org.cloudfoundry.multiapps.controller.persistence.test.TestDataSourceProvider; |
| 11 | +import org.cloudfoundry.multiapps.controller.process.variables.Serializer; |
| 12 | +import org.cloudfoundry.multiapps.controller.process.variables.Variable; |
| 13 | +import org.cloudfoundry.multiapps.controller.process.variables.Variables; |
| 14 | +import org.flowable.engine.ProcessEngine; |
| 15 | +import org.flowable.engine.ProcessEngineConfiguration; |
| 16 | +import org.flowable.engine.RepositoryService; |
| 17 | +import org.flowable.engine.RuntimeService; |
| 18 | +import org.flowable.engine.delegate.DelegateExecution; |
| 19 | +import org.flowable.engine.delegate.JavaDelegate; |
| 20 | +import org.flowable.engine.repository.ProcessDefinition; |
| 21 | +import org.flowable.mail.common.api.client.FlowableMailClient; |
| 22 | +import org.junit.jupiter.api.AfterEach; |
| 23 | +import org.junit.jupiter.api.BeforeEach; |
| 24 | +import org.junit.jupiter.api.Test; |
| 25 | +import org.mockito.Mock; |
| 26 | +import org.mockito.MockitoAnnotations; |
| 27 | + |
| 28 | +import static org.junit.jupiter.api.Assertions.assertEquals; |
| 29 | +import static org.junit.jupiter.api.Assertions.assertNotEquals; |
| 30 | + |
| 31 | +/** |
| 32 | + * Integration test for Flowable engine with in-memory H2 database. Tests real BPMN process creation, variable setting and retrieval using |
| 33 | + * the multiapps-controller variable handling system. |
| 34 | + */ |
| 35 | +class FlowableEngineTest { |
| 36 | + |
| 37 | + private static final String TEST_PROCESS_KEY = "mtaDeploymentTest"; |
| 38 | + private static final String MTA_DEPLOYMENT_TEST_PROCESS = "MTA Deployment Test Process"; |
| 39 | + private static final String FLOWABLE_DB_SCHEMA_STRATEGY_CREATE_DROP = "create-drop"; |
| 40 | + private static final String TEST_VARIABLE_TASK_BEAN_NAME = "testVariableTask"; |
| 41 | + private static final String DEPLOYMENT_NAME_OF_DIAGRAM = "MTA Deployment Test"; |
| 42 | + private static final String TEST_BPMN_DIAGRAM_RESOURCE = |
| 43 | + "org/cloudfoundry/multiapps/controller/process/flowable/test-bpmn-diagram.bpmn"; |
| 44 | + |
| 45 | + @Mock |
| 46 | + private FlowableMailClient flowableMailClient; |
| 47 | + |
| 48 | + private ProcessEngine processEngine; |
| 49 | + private RepositoryService repositoryService; |
| 50 | + private RuntimeService runtimeService; |
| 51 | + private String deploymentId; |
| 52 | + private TestVariableTask testVariableTask; |
| 53 | + |
| 54 | + @BeforeEach |
| 55 | + void setUp() throws Exception { |
| 56 | + MockitoAnnotations.openMocks(this); |
| 57 | + testVariableTask = new TestVariableTask(); |
| 58 | + DataSource dataSource = TestDataSourceProvider.getDataSource(); |
| 59 | + ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration(); |
| 60 | + configuration.setDataSource(dataSource); |
| 61 | + configuration.setDefaultMailClient(flowableMailClient); |
| 62 | + configuration.setDatabaseSchemaUpdate(FLOWABLE_DB_SCHEMA_STRATEGY_CREATE_DROP); |
| 63 | + configuration.setBeans(Map.of(TEST_VARIABLE_TASK_BEAN_NAME, testVariableTask)); |
| 64 | + processEngine = configuration.buildProcessEngine(); |
| 65 | + repositoryService = processEngine.getRepositoryService(); |
| 66 | + runtimeService = processEngine.getRuntimeService(); |
| 67 | + deploymentId = repositoryService.createDeployment() |
| 68 | + .name(DEPLOYMENT_NAME_OF_DIAGRAM) |
| 69 | + .addClasspathResource( |
| 70 | + TEST_BPMN_DIAGRAM_RESOURCE) |
| 71 | + .deploy() |
| 72 | + .getId(); |
| 73 | + } |
| 74 | + |
| 75 | + @AfterEach |
| 76 | + void tearDown() { |
| 77 | + if (deploymentId != null) { |
| 78 | + repositoryService.deleteDeployment(deploymentId, true); |
| 79 | + } |
| 80 | + if (processEngine != null) { |
| 81 | + processEngine.close(); |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + @Test |
| 86 | + void testProcessDeployment() { |
| 87 | + List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery() |
| 88 | + .processDefinitionKey(TEST_PROCESS_KEY) |
| 89 | + .list(); |
| 90 | + |
| 91 | + assertEquals(1, processDefinitions.size()); |
| 92 | + assertEquals(TEST_PROCESS_KEY, processDefinitions.get(0) |
| 93 | + .getKey()); |
| 94 | + assertEquals(MTA_DEPLOYMENT_TEST_PROCESS, processDefinitions.get(0) |
| 95 | + .getName()); |
| 96 | + } |
| 97 | + |
| 98 | + @Test |
| 99 | + void testProcessWithPredefinedVariables() { |
| 100 | + FlowableProcessTestData data = FlowableProcessTestDataUtils.predefinedScenario(); |
| 101 | + runtimeService.startProcessInstanceByKey(TEST_PROCESS_KEY, buildVariablesMap(data)); |
| 102 | + assertCapturedVariables(data, true); |
| 103 | + } |
| 104 | + |
| 105 | + @Test |
| 106 | + void testVariableUpdateAndRetrieval() { |
| 107 | + FlowableProcessTestDataUtils.UpdateScenario updateScenario = FlowableProcessTestDataUtils.updateScenario(); |
| 108 | + testVariableTask.variablesToSetInContext = buildVariablesMap(updateScenario.updated()); |
| 109 | + runtimeService.startProcessInstanceByKey(TEST_PROCESS_KEY, buildVariablesMap(updateScenario.initial())); |
| 110 | + // This assertion intentionally checks that the modified deployment descriptor is different from the initially set one because of flowable caching regression |
| 111 | + // https://github.com/flowable/flowable-engine/issues/4130 |
| 112 | + // The original behaviour must be to have same deployment descriptor as it was set in the task. Modify the test to assert for matching values when the issue is fixed. |
| 113 | + assertCapturedVariables(updateScenario.updated(), false); |
| 114 | + } |
| 115 | + |
| 116 | + @Test |
| 117 | + void testSetVariablesInsideStep() { |
| 118 | + FlowableProcessTestData data = FlowableProcessTestDataUtils.insideStepScenario(); |
| 119 | + testVariableTask.variablesToSetInContext = buildVariablesMap(data); |
| 120 | + runtimeService.startProcessInstanceByKey(TEST_PROCESS_KEY); |
| 121 | + assertCapturedVariables(data, true); |
| 122 | + } |
| 123 | + |
| 124 | + private Map<String, Object> buildVariablesMap(FlowableProcessTestData flowableProcessTestData) { |
| 125 | + Map<String, Object> vars = new HashMap<>(); |
| 126 | + setSerializedValueInMap(vars, Variables.CORRELATION_ID, flowableProcessTestData.getCorrelationId()); |
| 127 | + setSerializedValueInMap(vars, Variables.SPACE_GUID, flowableProcessTestData.getSpaceGuid()); |
| 128 | + setSerializedValueInMap(vars, Variables.ORGANIZATION_GUID, flowableProcessTestData.getOrgGuid()); |
| 129 | + setSerializedValueInMap(vars, Variables.USER, flowableProcessTestData.getUsername()); |
| 130 | + setSerializedValueInMap(vars, Variables.USER_GUID, flowableProcessTestData.getUserGuid()); |
| 131 | + setSerializedValueInMap(vars, Variables.MTA_ID, flowableProcessTestData.getMtaId()); |
| 132 | + setSerializedValueInMap(vars, Variables.KEEP_FILES, flowableProcessTestData.keepFiles()); |
| 133 | + setSerializedValueInMap(vars, Variables.DELETE_SERVICES, flowableProcessTestData.deleteServices()); |
| 134 | + setSerializedValueInMap(vars, Variables.APPS_STAGE_TIMEOUT_PROCESS_VARIABLE, flowableProcessTestData.getAppsStageTimeout()); |
| 135 | + setSerializedValueInMap(vars, Variables.MODULES_COUNT, flowableProcessTestData.getModulesCount()); |
| 136 | + setSerializedValueInMap(vars, Variables.DEPLOYMENT_DESCRIPTOR_WITH_SYSTEM_PARAMETERS, flowableProcessTestData.getSmallDescriptor()); |
| 137 | + setSerializedValueInMap(vars, Variables.DEPLOYMENT_DESCRIPTOR, flowableProcessTestData.getBigDescriptor()); |
| 138 | + setSerializedValueInMap(vars, Variables.DEPLOYED_MTA, flowableProcessTestData.getDeployedMta()); |
| 139 | + setSerializedValueInMap(vars, Variables.CURRENT_ROUTES, flowableProcessTestData.getRoutes()); |
| 140 | + setSerializedValueInMap(vars, Variables.STEP_PHASE, flowableProcessTestData.getStepPhase()); |
| 141 | + setSerializedValueInMap(vars, Variables.APP_STATE_ACTIONS_TO_EXECUTE, flowableProcessTestData.getAppActions()); |
| 142 | + setSerializedValueInMap(vars, Variables.CLOUD_SERVICE_KEYS_TO_CREATE, flowableProcessTestData.getServiceKeys()); |
| 143 | + setSerializedValueInMap(vars, Variables.MODULES_FOR_DEPLOYMENT, flowableProcessTestData.getModulesForDeployment()); |
| 144 | + setSerializedValueInMap(vars, Variables.MTA_EXTENSION_DESCRIPTOR_CHAIN, flowableProcessTestData.getExtensionDescriptors()); |
| 145 | + return vars; |
| 146 | + } |
| 147 | + |
| 148 | + private <T> void setSerializedValueInMap(Map<String, Object> variables, Variable<T> variable, T value) { |
| 149 | + if (value == null) { |
| 150 | + variables.put(variable.getName(), null); |
| 151 | + return; |
| 152 | + } |
| 153 | + Serializer<T> serializer = variable.getSerializer(); |
| 154 | + variables.put(variable.getName(), serializer.serialize(value)); |
| 155 | + } |
| 156 | + |
| 157 | + private <T> T getDeserializedValue(Map<String, Object> variables, Variable<T> variable) { |
| 158 | + Object serializedValue = variables.get(variable.getName()); |
| 159 | + if (serializedValue == null) { |
| 160 | + return variable.getDefaultValue(); |
| 161 | + } |
| 162 | + Serializer<T> serializer = variable.getSerializer(); |
| 163 | + return serializer.deserialize(serializedValue); |
| 164 | + } |
| 165 | + |
| 166 | + private void assertCapturedVariables(FlowableProcessTestData expected, boolean expectBigDescriptorMatch) { |
| 167 | + Map<String, Object> actual = testVariableTask.capturedVariables; |
| 168 | + assertEquals(expected.getCorrelationId(), getDeserializedValue(actual, Variables.CORRELATION_ID)); |
| 169 | + assertEquals(expected.getSpaceGuid(), getDeserializedValue(actual, Variables.SPACE_GUID)); |
| 170 | + assertEquals(expected.getOrgGuid(), getDeserializedValue(actual, Variables.ORGANIZATION_GUID)); |
| 171 | + assertEquals(expected.getUsername(), getDeserializedValue(actual, Variables.USER)); |
| 172 | + assertEquals(expected.getUserGuid(), getDeserializedValue(actual, Variables.USER_GUID)); |
| 173 | + assertEquals(expected.getMtaId(), getDeserializedValue(actual, Variables.MTA_ID)); |
| 174 | + assertEquals(expected.keepFiles(), getDeserializedValue(actual, Variables.KEEP_FILES)); |
| 175 | + assertEquals(expected.deleteServices(), getDeserializedValue(actual, Variables.DELETE_SERVICES)); |
| 176 | + assertEquals(expected.getAppsStageTimeout(), getDeserializedValue(actual, Variables.APPS_STAGE_TIMEOUT_PROCESS_VARIABLE)); |
| 177 | + assertEquals(expected.getModulesCount(), getDeserializedValue(actual, Variables.MODULES_COUNT)); |
| 178 | + assertEquals(JsonUtil.toJson(expected.getSmallDescriptor()), |
| 179 | + JsonUtil.toJson(getDeserializedValue(actual, Variables.DEPLOYMENT_DESCRIPTOR_WITH_SYSTEM_PARAMETERS))); |
| 180 | + |
| 181 | + String expectedBigDescriptor = JsonUtil.toJson(expected.getBigDescriptor()); |
| 182 | + String actualBigDescriptor = JsonUtil.toJson(getDeserializedValue(actual, Variables.DEPLOYMENT_DESCRIPTOR)); |
| 183 | + assertBigDescriptor(expectBigDescriptorMatch, expectedBigDescriptor, actualBigDescriptor); |
| 184 | + |
| 185 | + assertEquals(expected.getDeployedMta(), getDeserializedValue(actual, Variables.DEPLOYED_MTA)); |
| 186 | + assertEquals(expected.getRoutes(), getDeserializedValue(actual, Variables.CURRENT_ROUTES)); |
| 187 | + assertEquals(expected.getStepPhase(), getDeserializedValue(actual, Variables.STEP_PHASE)); |
| 188 | + assertEquals(expected.getAppActions(), getDeserializedValue(actual, Variables.APP_STATE_ACTIONS_TO_EXECUTE)); |
| 189 | + assertEquals(expected.getServiceKeys(), getDeserializedValue(actual, Variables.CLOUD_SERVICE_KEYS_TO_CREATE)); |
| 190 | + assertEquals(expected.getModulesForDeployment(), getDeserializedValue(actual, Variables.MODULES_FOR_DEPLOYMENT)); |
| 191 | + assertEquals(JsonUtil.toJson(expected.getExtensionDescriptors(), JsonSerializationStrategy.ALLOW_NULLS), |
| 192 | + JsonUtil.toJson(getDeserializedValue(actual, Variables.MTA_EXTENSION_DESCRIPTOR_CHAIN), |
| 193 | + JsonSerializationStrategy.ALLOW_NULLS)); |
| 194 | + } |
| 195 | + |
| 196 | + private static void assertBigDescriptor(boolean expectBigDescriptorMatch, String expectedBigDescriptor, String actualBigDescriptor) { |
| 197 | + if (expectBigDescriptorMatch) { |
| 198 | + assertEquals(expectedBigDescriptor, actualBigDescriptor); |
| 199 | + return; |
| 200 | + } |
| 201 | + assertNotEquals(expectedBigDescriptor, actualBigDescriptor); |
| 202 | + |
| 203 | + } |
| 204 | + |
| 205 | + private class TestVariableTask implements JavaDelegate { |
| 206 | + |
| 207 | + Map<String, Object> variablesToSetInContext = new HashMap<>(); |
| 208 | + Map<String, Object> capturedVariables = new HashMap<>(); |
| 209 | + |
| 210 | + @Override |
| 211 | + public void execute(DelegateExecution execution) { |
| 212 | + execution.setVariables(variablesToSetInContext); |
| 213 | + capturedVariables = execution.getVariables(); |
| 214 | + } |
| 215 | + } |
| 216 | + |
| 217 | +} |
0 commit comments