re base code
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / merge / property / PropertyDataValueMergeBusinessLogic.java
1 package org.openecomp.sdc.be.components.merge.property;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Optional;
8 import java.util.stream.Collectors;
9
10 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
11 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
12 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
13 import org.openecomp.sdc.be.model.DataTypeDefinition;
14 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
15 import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
16 import org.openecomp.sdc.be.tosca.PropertyConvertor;
17 import org.openecomp.sdc.common.log.wrappers.Logger;
18 import org.springframework.stereotype.Component;
19
20 import com.google.gson.Gson;
21
22 import fj.data.Either;
23
24 @Component
25 public class PropertyDataValueMergeBusinessLogic {
26
27     private static final Logger LOGGER = Logger.getLogger(PropertyDataValueMergeBusinessLogic.class);
28
29     private final PropertyValueMerger propertyValueMerger;
30     private final ApplicationDataTypeCache dataTypeCache;
31     
32     private final PropertyConvertor propertyConvertor = PropertyConvertor.getInstance();
33     private final Gson gson = new Gson();
34
35     
36     public PropertyDataValueMergeBusinessLogic(PropertyValueMerger propertyValueMerger, ApplicationDataTypeCache dataTypeCache) {
37         this.propertyValueMerger = propertyValueMerger;
38         this.dataTypeCache = dataTypeCache;
39     }
40
41     /**
42      *
43      * @param oldProp the old property to merge value from
44      * @param newProp the new property to merge value into
45      */
46     public void mergePropertyValue(PropertyDataDefinition oldProp, PropertyDataDefinition newProp, List<String> getInputNamesToMerge) {
47         Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
48         if (dataTypesEither.isRight()) {
49             LOGGER.debug("failed to fetch data types, skip merging of previous property values. status: {}", dataTypesEither.right().value());
50         }
51         else {
52             mergePropertyValue(oldProp, newProp, dataTypesEither.left().value(), getInputNamesToMerge);
53         }
54     }
55     
56     private void mergePropertyValue(PropertyDataDefinition oldProp, PropertyDataDefinition newProp, Map<String, DataTypeDefinition> dataTypes, List<String> getInputNamesToMerge) {
57         Object oldValAsObject = convertPropertyStrValueToObject(oldProp, dataTypes);
58         Object newValAsObject = convertPropertyStrValueToObject(newProp, dataTypes);
59         if(oldValAsObject != null){
60             Object mergedValue =  propertyValueMerger.merge(oldValAsObject, newValAsObject, getInputNamesToMerge, newProp.getType(), newProp.getSchemaType(), dataTypes);
61             newProp.setValue(convertPropertyValueObjectToString(mergedValue));
62             
63             mergePropertyGetInputsValues(oldProp, newProp);
64         }
65         
66     }
67     
68     private String convertPropertyValueObjectToString(Object mergedValue) {
69         if (PropertyValueMerger.isEmptyValue(mergedValue)) {
70             return null;
71         }
72         return mergedValue instanceof String? mergedValue.toString() : gson.toJson(mergedValue);
73     }
74
75     private Object convertPropertyStrValueToObject(PropertyDataDefinition propertyDataDefinition, Map<String, DataTypeDefinition> dataTypes) {
76         String propValue = propertyDataDefinition.getValue() == null ? "": propertyDataDefinition.getValue();
77         String propertyType = propertyDataDefinition.getType();
78         String innerType = propertyDataDefinition.getSchemaType();
79         return propertyConvertor.convertToToscaObject(propertyType, propValue, innerType, dataTypes, true);
80     }
81
82     protected void mergePropertyGetInputsValues(PropertyDataDefinition oldProp, PropertyDataDefinition newProp) {
83         if (!oldProp.isGetInputProperty()) {
84             return;
85         }
86         List<GetInputValueDataDefinition> getInputsToMerge = findOldGetInputValuesToMerge(oldProp, newProp);
87         List<GetInputValueDataDefinition> newPropGetInputValues = Optional.ofNullable(newProp.getGetInputValues()).orElse(new ArrayList<>());
88         newPropGetInputValues.addAll(getInputsToMerge);
89         newProp.setGetInputValues(newPropGetInputValues);
90     }
91
92     private List<GetInputValueDataDefinition> findOldGetInputValuesToMerge(PropertyDataDefinition oldProp, PropertyDataDefinition newProp) {
93         List<GetInputValueDataDefinition> oldGetInputValues = oldProp.getGetInputValues();
94         List<GetInputValueDataDefinition> newGetInputValues = Optional.ofNullable(newProp.getGetInputValues()).orElse(Collections.emptyList());
95         List<String> newGetInputNames = newGetInputValues.stream().map(GetInputValueDataDefinition::getInputName).collect(Collectors.toList());
96         return oldGetInputValues.stream()
97                 .filter(getInput -> !newGetInputNames.contains(getInput.getInputName()))
98                 .filter(getInput -> isValueContainsGetInput(getInput.getInputName(), newProp.getValue()))
99                 .collect(Collectors.toList());
100     }
101
102     private boolean isValueContainsGetInput(String inputName, String value) {
103         String getInputEntry = "\"%s\":\"%s\"";
104         return value != null && value.contains(String.format(getInputEntry, ToscaFunctions.GET_INPUT.getFunctionName(), inputName));
105     }
106 }