summaryrefslogtreecommitdiffstats
path: root/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/input/InputsValuesMergingBusinessLogic.java
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/input/InputsValuesMergingBusinessLogic.java')
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/input/InputsValuesMergingBusinessLogic.java180
1 files changed, 180 insertions, 0 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/input/InputsValuesMergingBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/input/InputsValuesMergingBusinessLogic.java
new file mode 100644
index 0000000000..e49d2b2c87
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/input/InputsValuesMergingBusinessLogic.java
@@ -0,0 +1,180 @@
+package org.openecomp.sdc.be.components.merge.input;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang.StringUtils;
+import org.openecomp.sdc.be.dao.utils.MapUtil;
+import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.InputDefinition;
+
+@org.springframework.stereotype.Component
+public class InputsValuesMergingBusinessLogic {
+
+ /**
+ * Merge old inputs values into the updated inputs
+ * An input value is merged if the input previous version had a user defined value and its value is empty in current version
+ * @param oldInputs the currently persisted inputs mapped by their names
+ * @param updatedInputs the currently being update inputs mapped by their names
+ */
+ public void mergeComponentInputs(Map<String, InputDefinition> oldInputs, Map<String, InputDefinition> updatedInputs) {
+ updatedInputs.forEach((inputName, input) -> mergeInputsValues(oldInputs.get(inputName), input));
+ }
+
+ /**
+ * @param oldComponent the old state of {@link Component} that is being updated
+ * @param newComponent the new state of {@link Component} that is being updated
+ * @return a list of all inputs that were previously declared and need to be merged to the updating component
+ * An input needs to merged if a property was declared as an input (by the user) in previous component version and the declared input not exist in new version
+ */
+ public List<InputDefinition> getPreviouslyDeclaredInputsToMerge(Component oldComponent, Component newComponent) {
+ if (oldComponent == null || oldComponent.getInputs() == null || newComponent == null ) {
+ return Collections.emptyList();
+ }
+ Map<String, List<PropertyDataDefinition>> getInputProperties = getAllGetInputPropertyData(newComponent);
+ List<RedeclareInputData> inputsToRedeclareData = buildRedeclareInputData(newComponent, getInputProperties);
+ return findPrevDeclaredInputs(oldComponent.getInputs(), inputsToRedeclareData);
+ }
+
+ /**
+ * @param oldInputs list of previous inputs to find inputs to redeclare from
+ * @param newComponent the new state of {@link Component} that is being updated
+ * @param instanceId instance id
+ * @return a list of all inputs that were previously declared and need to be merged to the updating component
+ * An input needs to merged if an instance property was declared as an input (by the user) in previous component version and the declared input not exist in new version
+ */
+ public List<InputDefinition> getPreviouslyDeclaredInputsToMerge(List<InputDefinition> oldInputs, Component newComponent, String instanceId) {
+ if (oldInputs == null || newComponent == null ) {
+ return Collections.emptyList();
+ }
+ Map<String, List<PropertyDataDefinition>> getInputProperties = getAllGetInputPropertyData(newComponent, instanceId);
+ List<RedeclareInputData> inputsToRedeclareData = buildRedeclareInputData(newComponent, getInputProperties);
+ return findPrevDeclaredInputs(oldInputs, inputsToRedeclareData);
+ }
+
+ private List<InputDefinition> findPrevDeclaredInputs(List<InputDefinition> oldInputs, List<RedeclareInputData> inputsToRedeclareData) {
+ Map<String, InputDefinition> oldInputsById = MapUtil.toMap(oldInputs, InputDefinition::getUniqueId);
+ List<InputDefinition> inputsToRedeclare = new ArrayList<>();
+ inputsToRedeclareData.forEach(redeclareInputData -> {
+ List<InputDefinition> inputDefinitions = prepareInputsForRedeclaration(oldInputsById, redeclareInputData);
+ inputsToRedeclare.addAll(inputDefinitions);
+ });
+ return inputsToRedeclare;
+ }
+
+ private List<InputDefinition> prepareInputsForRedeclaration(Map<String, InputDefinition> oldInputsById, RedeclareInputData redeclareInputData) {
+ List<InputDefinition> inputsForRedeclaration = redeclareInputData.declaredInputIds.stream().map(oldInputsById::get).collect(Collectors.toList());
+ inputsForRedeclaration.forEach(input -> {
+ input.setPropertyId(redeclareInputData.propertyId);
+ input.setInstanceUniqueId(redeclareInputData.instanceId);
+ });
+ return inputsForRedeclaration;
+ }
+
+ private <T extends PropertyDataDefinition> Map<String, List<PropertyDataDefinition>> findGetInputPropsDefinitions(Map<String, List<T>> instancesPropDefinitions) {
+ Map<String, List<PropertyDataDefinition>> getInputProps = new HashMap<>();
+ if (instancesPropDefinitions == null) {
+ return getInputProps;
+ }
+ return instancesPropDefinitions.entrySet()
+ .stream()
+ .collect(Collectors.toMap(Map.Entry::getKey,
+ entry -> this.filterGetInputProps(entry.getValue())));
+ }
+
+ private <T extends PropertyDataDefinition> List<PropertyDataDefinition> filterGetInputProps(List<T> propDefinitions) {
+ return propDefinitions
+ .stream()
+ .filter(PropertyDataDefinition::isGetInputProperty)
+ .collect(Collectors.toList());
+ }
+
+ private void mergeInputsValues(InputDefinition oldInput, InputDefinition updatedInput) {
+ if (shouldMergeOldValue(oldInput, updatedInput)) {
+ updatedInput.setDefaultValue(oldInput.getDefaultValue());
+ }
+ }
+
+ private boolean shouldMergeOldValue(InputDefinition oldInput, InputDefinition newInput) {
+ return isNonEmptyDefaultValue(oldInput) && isEmptyDefaultValue(newInput) && isSameType(oldInput, newInput);
+ }
+
+ private boolean isSameType(InputDefinition oldInput, InputDefinition updatedInput) {
+ return oldInput.typeEquals(updatedInput);
+ }
+
+ private boolean isEmptyDefaultValue(InputDefinition input) {
+ return input != null && StringUtils.isEmpty(input.getDefaultValue());
+ }
+
+ private boolean isNonEmptyDefaultValue(InputDefinition input) {
+ return input != null && !isEmptyDefaultValue(input);
+ }
+
+ private List<RedeclareInputData> buildRedeclareInputData(Component newComponent, Map<String, List<PropertyDataDefinition>> getInputProperties) {
+ Map<String, InputDefinition> inputsById = MapUtil.toMap(newComponent.getInputs(), InputDefinition::getUniqueId);
+ List<RedeclareInputData> redeclareInputData = new ArrayList<>();
+ getInputProperties.forEach((instanceId, getInputProps) -> {
+ redeclareInputData.addAll(findInputsToRedeclare(inputsById, instanceId, getInputProps));
+ });
+ return redeclareInputData;
+
+ }
+
+ private Map<String, List<PropertyDataDefinition>> getAllGetInputPropertyData(Component newComponent) {
+ Map<String, List<PropertyDataDefinition>> getInputInstanceProps = findGetInputPropsDefinitions(newComponent.getComponentInstancesProperties());
+ Map<String, List<PropertyDataDefinition>> getInputInstanceInputs = findGetInputPropsDefinitions(newComponent.getComponentInstancesInputs());
+ getInputInstanceInputs.putAll(getInputInstanceProps);
+ return getInputInstanceInputs;
+ }
+
+ private Map<String, List<PropertyDataDefinition>> getAllGetInputPropertyData(Component newComponent, String instanceId) {
+ List<PropertyDataDefinition> getInputInstanceProps = this.filterGetInputProps(newComponent.safeGetComponentInstanceProperties(instanceId));
+ List<PropertyDataDefinition> getInputInstanceInputs = this.filterGetInputProps(newComponent.safeGetComponentInstanceInput(instanceId));
+ getInputInstanceInputs.addAll(getInputInstanceProps);
+ return Collections.singletonMap(instanceId, getInputInstanceInputs);
+ }
+
+ private List<RedeclareInputData> findInputsToRedeclare(Map<String, InputDefinition> inputsById, String instanceId, List<PropertyDataDefinition> getInputProps) {
+ List<RedeclareInputData> redeclareInputDataList = new ArrayList<>();
+ getInputProps.forEach(property -> {
+ List<String> inputsToRedeclareIds = findInputsToRedeclareIds(inputsById, property);
+ RedeclareInputData redeclareInputData = new RedeclareInputData(property.getUniqueId(), inputsToRedeclareIds, instanceId);
+ redeclareInputDataList.add(redeclareInputData);
+ });
+ return redeclareInputDataList;
+ }
+
+ private List<String> findInputsToRedeclareIds(Map<String, InputDefinition> inputsById, PropertyDataDefinition property) {
+ List<GetInputValueDataDefinition> getInputValues = property.getGetInputValues();
+ return getInputValues.stream()
+ .filter(getInputVal -> getInputValueWithNoCorrespondingInput(getInputVal, inputsById))
+ .map(GetInputValueDataDefinition::getInputId)
+ .collect(Collectors.toList());
+ }
+
+ private boolean getInputValueWithNoCorrespondingInput(GetInputValueDataDefinition getInputVal, Map<String, InputDefinition> inputsById) {
+ return !inputsById.containsKey(getInputVal.getInputId());
+ }
+
+ private class RedeclareInputData {
+ private String propertyId;
+ private List<String> declaredInputIds;
+ private String instanceId;
+
+ public RedeclareInputData(String propertyId, List<String> declaredInputIds, String instanceId) {
+ this.propertyId = propertyId;
+ this.declaredInputIds = declaredInputIds;
+ this.instanceId = instanceId;
+ }
+
+ }
+
+
+} \ No newline at end of file