Skip to content

Commit

Permalink
AAE-27057 use VariableParsingService to parse variable with type defi…
Browse files Browse the repository at this point in the history
…ned in process extensions (#4601)
  • Loading branch information
tom-dal committed Mar 6, 2024
1 parent fa0b9e0 commit 911d9d7
Show file tree
Hide file tree
Showing 7 changed files with 314 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.activiti.runtime.api.impl.ExpressionResolver;
import org.activiti.runtime.api.impl.ExtensionsVariablesMappingProvider;
import org.activiti.spring.process.ProcessExtensionService;
import org.activiti.spring.process.variable.VariableParsingService;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
Expand Down Expand Up @@ -72,8 +73,9 @@ public DefaultServiceTaskBehavior defaultServiceTaskBehavior(
@Bean
@ConditionalOnMissingBean
public ExtensionsVariablesMappingProvider variablesMappingProvider(ProcessExtensionService processExtensionService,
ExpressionResolver expressionResolver) {
return new ExtensionsVariablesMappingProvider(processExtensionService, expressionResolver);
ExpressionResolver expressionResolver,
VariableParsingService variableParsingService) {
return new ExtensionsVariablesMappingProvider(processExtensionService, expressionResolver, variableParsingService);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
package org.activiti.runtime.api.impl;

import static java.util.Collections.emptyMap;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import org.activiti.api.runtime.model.impl.ProcessVariablesMapTypeRegistry;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.impl.bpmn.behavior.MappingExecutionContext;
Expand All @@ -30,17 +34,24 @@
import org.activiti.spring.process.model.Mapping;
import org.activiti.spring.process.model.ProcessConstantsMapping;
import org.activiti.spring.process.model.ProcessVariablesMapping;
import org.activiti.spring.process.model.VariableDefinition;
import org.activiti.spring.process.variable.VariableParsingService;
import org.springframework.core.convert.ConversionService;

public class ExtensionsVariablesMappingProvider implements VariablesCalculator {

private ProcessExtensionService processExtensionService;

private ExpressionResolver expressionResolver;

private VariableParsingService variableParsingService;

public ExtensionsVariablesMappingProvider(ProcessExtensionService processExtensionService,
ExpressionResolver expressionResolver) {
ExpressionResolver expressionResolver,
VariableParsingService variableParsingService) {
this.processExtensionService = processExtensionService;
this.expressionResolver = expressionResolver;
this.variableParsingService = variableParsingService;
}

protected Optional<Object> calculateMappedValue(Mapping inputMapping,
Expand Down Expand Up @@ -162,7 +173,14 @@ private Map<String, Object> calculateOutPutVariables(MappingExecutionContext map

if (isTargetProcessVariableDefined(extensions, mappingExecutionContext.getExecution(), name)) {
calculateOutPutMappedValue(mapping.getValue(), availableVariables).ifPresent(
value -> outboundVariables.put(mapping.getKey(), value));
value -> {
extensions.getProperties().values().stream().filter(v -> v.getName().equals(mapping.getKey())).findAny().ifPresentOrElse(
v -> outboundVariables.put(mapping.getKey(), variableParsingService.parse(new VariableDefinition(v.getType(), value))),
() -> outboundVariables.put(mapping.getKey(), value)
);


});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,26 @@
import org.activiti.engine.impl.variable.StringType;
import org.activiti.spring.process.ProcessExtensionService;
import org.activiti.spring.process.model.Extension;
import org.activiti.spring.process.model.Mapping;
import org.activiti.spring.process.model.ProcessExtensionModel;
import org.activiti.spring.process.model.ProcessVariablesMapping;
import org.activiti.spring.process.model.VariableDefinition;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.assertj.core.api.InstanceOfAssertFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.util.ReflectionTestUtils;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -53,9 +61,11 @@

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@SpringBootTest
public class ExtensionsVariablesMappingProviderTest {

@InjectMocks
@Autowired
private ExtensionsVariablesMappingProvider variablesMappingProvider;

@Mock
Expand Down Expand Up @@ -257,6 +267,123 @@ public void calculateOutputVariablesShouldNotPassAnyVariablesWhenTheMappingIsEmp
assertThat(outputVariables).isEmpty();
}

@Test
public void calculateOutputVariablesShouldConvertValueFromDoubleToBigDecimal() {

//given
String taskId = "task-id";
String processVariableId = "process-variable-id";
String processVariableName = "bigdecimal-process-variable";
String doubleOutputName = "double-output";

Extension extension = new Extension();
DelegateExecution execution = buildExecution(extension, taskId);

VariableDefinition bigdecimalProcessVariable = new VariableDefinition();
bigdecimalProcessVariable.setType("bigdecimal");
bigdecimalProcessVariable.setName(processVariableName);
bigdecimalProcessVariable.setId(processVariableId);
extension.setProperties(Map.of(processVariableId, bigdecimalProcessVariable));

ProcessVariablesMapping mappings = new ProcessVariablesMapping();
Mapping mapping = new Mapping();
mapping.setType(Mapping.SourceMappingType.VARIABLE);
mapping.setValue(doubleOutputName);
mappings.setOutputs(Map.of(processVariableName, mapping));
extension.setMappings(Map.of(taskId, mappings));

double doubleValue = 2.3;
BigDecimal bigDecimalValue = BigDecimal.valueOf(doubleValue);
Map<String, Object> availableVariables = singletonMap(doubleOutputName, doubleValue);

//when
Map<String, Object> outPutVariables = variablesMappingProvider.calculateOutPutVariables(buildMappingExecutionContext(execution),
availableVariables);

//then
assertThat(outPutVariables.get(processVariableName)).isEqualTo(bigDecimalValue);
}

@Test
public void calculateOutputVariablesShouldConvertValueFromIntegerToBigDecimal() {

//given
String taskId = "task-id";
String processVariableId = "process-variable-id";
String processVariableName = "bigdecimal-process-variable";
String integerOutputName = "integer-output";

Extension extension = new Extension();
DelegateExecution execution = buildExecution(extension, taskId);

VariableDefinition bigdecimalProcessVariable = new VariableDefinition();
bigdecimalProcessVariable.setType("bigdecimal");
bigdecimalProcessVariable.setName(processVariableName);
bigdecimalProcessVariable.setId(processVariableId);
extension.setProperties(Map.of(processVariableId, bigdecimalProcessVariable));

ProcessVariablesMapping mappings = new ProcessVariablesMapping();
Mapping mapping = new Mapping();
mapping.setType(Mapping.SourceMappingType.VARIABLE);
mapping.setValue(integerOutputName);
mappings.setOutputs(Map.of(processVariableName, mapping));
extension.setMappings(Map.of(taskId, mappings));

Integer intValue = 2;
BigDecimal bigDecimalValue = BigDecimal.valueOf(intValue);

Map<String, Object> availableVariables = singletonMap(integerOutputName, intValue);

//when
Map<String, Object> outPutVariables = variablesMappingProvider.calculateOutPutVariables(buildMappingExecutionContext(execution),
availableVariables);

//then
assertThat(outPutVariables.get(processVariableName)).asInstanceOf(InstanceOfAssertFactories.BIG_DECIMAL).isEqualByComparingTo(bigDecimalValue);
}

@Test
public void calculateOutputVariablesShouldConvertValueFromStringToBigDecimal() {

//given
String taskId = "task-id";
String processVariableId = "process-variable-id";
String processVariableName = "bigdecimal-process-variable";
String stringOutputName = "string-output";

Extension extension = new Extension();
DelegateExecution execution = buildExecution(extension, taskId);

VariableDefinition bigdecimalProcessVariable = new VariableDefinition();
bigdecimalProcessVariable.setType("bigdecimal");
bigdecimalProcessVariable.setName(processVariableName);
bigdecimalProcessVariable.setId(processVariableId);
extension.setProperties(Map.of(processVariableId, bigdecimalProcessVariable));

ProcessVariablesMapping mappings = new ProcessVariablesMapping();
Mapping mapping = new Mapping();
mapping.setType(Mapping.SourceMappingType.VARIABLE);
mapping.setValue(stringOutputName);
mappings.setOutputs(Map.of(processVariableName, mapping));
extension.setMappings(Map.of(taskId, mappings));

String stringValue = "4.1";
Map<String, Object> availableVariables = singletonMap(stringOutputName, stringValue);

ExpressionResolver expressionResolver = ExpressionResolverHelper.initContext(execution, extension);
ReflectionTestUtils.setField(variablesMappingProvider,
"expressionResolver",
expressionResolver);
ExpressionResolverHelper.setExecutionVariables(execution, availableVariables);

//when
Map<String, Object> outPutVariables = variablesMappingProvider.calculateOutPutVariables(buildMappingExecutionContext(execution),
availableVariables);

//then
assertThat(outPutVariables.get(processVariableName)).asInstanceOf(InstanceOfAssertFactories.BIG_DECIMAL).isEqualByComparingTo(stringValue);
}

private DelegateExecution initExpressionResolverTest(String fileName, String processDefinitionKey) throws IOException {
return initExpressionResolverTest(fileName, processDefinitionKey, new ArrayList<>());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ public class VariableDefinition extends org.activiti.core.common.model.connector

private Object value;

public VariableDefinition(){}
public VariableDefinition(String type, Object value) {
super();
this.setType(type);
this.value = value;
}

public Object getValue() {
return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public VariableParsingService(Map<String, VariableType> variableTypeMap) {

private Map<String, VariableType> variableTypeMap;

public Object parse(VariableDefinition variableDefinition) throws ActivitiException{
public Object parse(VariableDefinition variableDefinition) throws ActivitiException {


if(variableDefinition.getType()!=null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,18 @@ public class BigDecimalVariableType extends VariableType {

@Override
public Object parseFromValue(Object value) throws ActivitiException {
return BigDecimal.valueOf(((Number) value).doubleValue());

if(value instanceof BigDecimal) {
return value;
}
try {
if (value instanceof String) {
return new BigDecimal((String) value);
}
return BigDecimal.valueOf(((Number) value).doubleValue());
} catch (ClassCastException | NumberFormatException e) {
throw new ActivitiException("Error parsing bigdecimal value from " + value + ": " + e.getMessage(), e);
}
}

@Override
Expand Down

0 comments on commit 911d9d7

Please sign in to comment.