6377152a13cae8ea68346fc09da5db62c963c950
[sdc.git] /
1 /*
2  * -
3  *  ============LICENSE_START=======================================================
4  *  Copyright (C) 2022 Nordix Foundation.
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *       http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.sdc.be.utils;
23
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Objects;
28 import java.util.Optional;
29 import java.util.Set;
30 import java.util.stream.Collectors;
31 import lombok.AccessLevel;
32 import lombok.NoArgsConstructor;
33 import org.apache.commons.lang3.StringUtils;
34 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction;
36 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
37 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionParameter;
38 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
39 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
40 import org.openecomp.sdc.be.datatypes.elements.ToscaStringParameter;
41 import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
42 import org.openecomp.sdc.be.datatypes.enums.FilterValueType;
43 import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType;
44 import org.openecomp.sdc.be.datatypes.enums.PropertySource;
45 import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
46 import org.yaml.snakeyaml.Yaml;
47
48 @NoArgsConstructor(access = AccessLevel.PRIVATE)
49 public class PropertyFilterConstraintDataDefinitionHelper {
50
51     public static PropertyFilterConstraintDataDefinition convertLegacyConstraint(final String constraint) {
52         final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition();
53         final Map<String, Object> constraintYaml = new Yaml().load(constraint);
54         final String propertyName = constraintYaml.keySet().iterator().next();
55         propertyFilterConstraint.setPropertyName(propertyName);
56         final Map<String, Object> operatorYaml = (Map<String, Object>) constraintYaml.get(propertyName);
57         final String operator = operatorYaml.keySet().iterator().next();
58         propertyFilterConstraint.setOperator(ConstraintType.findByType(operator).orElse(null));
59         final Object valueYaml = operatorYaml.get(operator);
60         final Optional<ToscaFunction> toscaFunction = createToscaFunctionFromLegacyConstraintValue(valueYaml);
61         if (toscaFunction.isPresent()) {
62             propertyFilterConstraint.setValue(toscaFunction.get());
63         } else {
64             propertyFilterConstraint.setValue(valueYaml);
65         }
66         propertyFilterConstraint.setValueType(detectValueType(valueYaml));
67         propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY);
68         return propertyFilterConstraint;
69     }
70
71     public static Optional<ToscaFunction> createToscaFunctionFromLegacyConstraintValue(final Object filterValue) {
72         if (!(filterValue instanceof Map)) {
73             return Optional.empty();
74         }
75         final Map<?, ?> filterValueAsMap = (Map<?, ?>) filterValue;
76         final Set<?> keys = filterValueAsMap.keySet();
77         if (keys.size() != 1) {
78             return Optional.empty();
79         }
80         final Object toscaFunctionTypeObject = keys.iterator().next();
81         if (!(toscaFunctionTypeObject instanceof String)) {
82             return Optional.empty();
83         }
84         final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType((String) toscaFunctionTypeObject).orElse(null);
85         if (toscaFunctionType == null) {
86             return Optional.empty();
87         }
88         switch (toscaFunctionType) {
89             case GET_INPUT:
90                 return readLegacyGetInputConstraintValue(filterValueAsMap, toscaFunctionTypeObject);
91             case GET_ATTRIBUTE:
92             case GET_PROPERTY:
93                 return readLegacyGetPropertyConstraintValue(filterValueAsMap, toscaFunctionTypeObject, toscaFunctionType);
94             case CONCAT:
95                 return readLegacyConcatConstraintValue(filterValueAsMap, toscaFunctionTypeObject);
96             default:
97                 return Optional.empty();
98         }
99     }
100
101     public static Optional<FilterValueType> convertFromToscaFunctionType(final ToscaFunctionType toscaFunctionType) {
102         return FilterValueType.findByName(toscaFunctionType.getName());
103     }
104
105     private static Optional<ToscaFunction> readLegacyConcatConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) {
106         final List<Object> concatValue;
107         try {
108             concatValue = (List<Object>) filterValueAsMap.get(toscaFunctionType);
109         } catch (final Exception ignored) {
110             return Optional.empty();
111         }
112         if (concatValue.isEmpty()) {
113             return Optional.empty();
114         }
115         final var toscaConcatFunction = new ToscaConcatFunction();
116         for (Object parameter : concatValue) {
117             if (parameter instanceof String) {
118                 final ToscaStringParameter toscaStringParameter = new ToscaStringParameter();
119                 toscaStringParameter.setValue((String) parameter);
120                 toscaConcatFunction.addParameter(toscaStringParameter);
121             } else {
122                 createToscaFunctionFromLegacyConstraintValue(parameter)
123                     .ifPresent(toscaFunction -> toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction));
124             }
125         }
126         return Optional.of(toscaConcatFunction);
127     }
128
129     private static Optional<ToscaFunction> readLegacyGetPropertyConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType,
130                                                                                 ToscaFunctionType toscaFunctionType1) {
131         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
132         toscaGetFunction.setFunctionType(
133             toscaFunctionType.toString().equalsIgnoreCase(ToscaFunctionType.GET_PROPERTY.getName()) ? ToscaGetFunctionType.GET_PROPERTY : ToscaGetFunctionType.GET_ATTRIBUTE
134         );
135         final Object functionValueObj = null != filterValueAsMap.get(toscaFunctionType1) ?
136             filterValueAsMap.get(toscaFunctionType1) : filterValueAsMap.get(toscaFunctionType);
137         if (!(functionValueObj instanceof List)) {
138             return Optional.empty();
139         }
140         final List<String> functionParameters;
141         try {
142             functionParameters = ((List<Object>) functionValueObj).stream()
143                 .map(object -> Objects.toString(object, null))
144                 .collect(Collectors.toList());
145         } catch (final ClassCastException ignored) {
146             return Optional.empty();
147         }
148         if (functionParameters.size() < 2) {
149             return Optional.empty();
150         }
151         final String propertySourceType = functionParameters.get(0);
152         final PropertySource propertySource = PropertySource.findType(propertySourceType).orElse(null);
153         if (propertySource == PropertySource.SELF) {
154             toscaGetFunction.setPropertySource(propertySource);
155         } else {
156             toscaGetFunction.setPropertySource(PropertySource.INSTANCE);
157             toscaGetFunction.setSourceName(propertySourceType);
158         }
159         List<String> propertySourceIndex = functionParameters.subList(1, functionParameters.size());
160         List<String> propertySourcePath = new ArrayList<>();
161         propertySourcePath.add((String)propertySourceIndex.get(0));
162         if (propertySourceIndex.size() > 1 ) {
163             List<Object> indexParsedList = new ArrayList<Object>();
164             List<String> indexObjectList = propertySourceIndex.subList(1,propertySourceIndex.size());
165             boolean loopFlag = true;
166             for (String indexValue : indexObjectList) {
167                 if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
168                     propertySourcePath.add(indexValue);
169                 } else {
170                     loopFlag = false;
171                     if (StringUtils.isNumeric(indexValue)) {
172                         indexParsedList.add(Integer.parseInt(indexValue));
173                     } else {
174                         indexParsedList.add(indexValue);
175                     }
176                 }
177             }
178             toscaGetFunction.setToscaIndexList(indexParsedList);
179         }
180         toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
181         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
182         toscaGetFunction.setPropertyName(propertyName);
183         return Optional.of(toscaGetFunction);
184     }
185
186     private static Optional<ToscaFunction> readLegacyGetInputConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) {
187         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
188         toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT);
189         toscaGetFunction.setPropertySource(PropertySource.SELF);
190         final Object functionValueObj = filterValueAsMap.get(toscaFunctionType);
191         if (!(functionValueObj instanceof List) && !(functionValueObj instanceof String)) {
192             return Optional.empty();
193         }
194         if (functionValueObj instanceof String) {
195             toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj));
196         } else {
197             final List<String> functionParameters;
198             try {
199                 functionParameters = ((List<Object>) functionValueObj).stream()
200                     .map(object -> Objects.toString(object, null))
201                     .collect(Collectors.toList());
202             } catch (final ClassCastException ignored) {
203                 return Optional.empty();
204             }
205             List<String> propertySourcePath = new ArrayList<>();
206             propertySourcePath.add((String)functionParameters.get(0));
207             if (functionParameters.size() > 1 ) {
208                 List<Object> indexParsedList = new ArrayList<Object>();
209                 List<String> indexObjectList = functionParameters.subList(1,functionParameters.size());
210                 boolean loopFlag = true;
211                 for (String indexValue : indexObjectList) {
212                     if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
213                         propertySourcePath.add(indexValue);
214                     } else {
215                         loopFlag = false;
216                         if (StringUtils.isNumeric(indexValue)) {
217                             indexParsedList.add(Integer.parseInt(indexValue));
218                         } else {
219                             indexParsedList.add(indexValue);
220                         }
221                     }
222                 }
223                 toscaGetFunction.setToscaIndexList(indexParsedList);
224             }
225             toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
226         }
227         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
228         toscaGetFunction.setPropertyName(propertyName);
229         return Optional.of(toscaGetFunction);
230     }
231
232     private static FilterValueType detectValueType(final Object value) {
233         if (value instanceof Map) {
234             final Map<?, ?> valueAsMap = (Map<?, ?>) value;
235             if (valueAsMap.containsKey(ToscaFunctionType.CONCAT.getName())) {
236                 return FilterValueType.CONCAT;
237             }
238             if (valueAsMap.containsKey(ToscaFunctionType.GET_ATTRIBUTE.getName())) {
239                 return FilterValueType.GET_ATTRIBUTE;
240             }
241             if (valueAsMap.containsKey(ToscaFunctionType.GET_PROPERTY.getName())) {
242                 return FilterValueType.GET_PROPERTY;
243             }
244             if (valueAsMap.containsKey(ToscaFunctionType.GET_INPUT.getName())) {
245                 return FilterValueType.GET_INPUT;
246             }
247         }
248
249         return FilterValueType.STATIC;
250     }
251
252 }