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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.openecomp.sdc.be.utils;
24 import java.util.ArrayList;
25 import java.util.List;
27 import java.util.Objects;
28 import java.util.Optional;
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;
48 @NoArgsConstructor(access = AccessLevel.PRIVATE)
49 public class PropertyFilterConstraintDataDefinitionHelper {
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());
64 propertyFilterConstraint.setValue(valueYaml);
66 propertyFilterConstraint.setValueType(detectValueType(valueYaml));
67 propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY);
68 return propertyFilterConstraint;
71 public static Optional<ToscaFunction> createToscaFunctionFromLegacyConstraintValue(final Object filterValue) {
72 if (!(filterValue instanceof Map)) {
73 return Optional.empty();
75 final Map<?, ?> filterValueAsMap = (Map<?, ?>) filterValue;
76 final Set<?> keys = filterValueAsMap.keySet();
77 if (keys.size() != 1) {
78 return Optional.empty();
80 final Object toscaFunctionTypeObject = keys.iterator().next();
81 if (!(toscaFunctionTypeObject instanceof String)) {
82 return Optional.empty();
84 final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType((String) toscaFunctionTypeObject).orElse(null);
85 if (toscaFunctionType == null) {
86 return Optional.empty();
88 switch (toscaFunctionType) {
90 return readLegacyGetInputConstraintValue(filterValueAsMap, toscaFunctionTypeObject);
93 return readLegacyGetPropertyConstraintValue(filterValueAsMap, toscaFunctionTypeObject, toscaFunctionType);
95 return readLegacyConcatConstraintValue(filterValueAsMap, toscaFunctionTypeObject);
97 return Optional.empty();
101 public static Optional<FilterValueType> convertFromToscaFunctionType(final ToscaFunctionType toscaFunctionType) {
102 return FilterValueType.findByName(toscaFunctionType.getName());
105 private static Optional<ToscaFunction> readLegacyConcatConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) {
106 final List<Object> concatValue;
108 concatValue = (List<Object>) filterValueAsMap.get(toscaFunctionType);
109 } catch (final Exception ignored) {
110 return Optional.empty();
112 if (concatValue.isEmpty()) {
113 return Optional.empty();
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);
122 createToscaFunctionFromLegacyConstraintValue(parameter)
123 .ifPresent(toscaFunction -> toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction));
126 return Optional.of(toscaConcatFunction);
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
135 final Object functionValueObj = null != filterValueAsMap.get(toscaFunctionType1) ?
136 filterValueAsMap.get(toscaFunctionType1) : filterValueAsMap.get(toscaFunctionType);
137 if (!(functionValueObj instanceof List)) {
138 return Optional.empty();
140 final List<String> functionParameters;
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();
148 if (functionParameters.size() < 2) {
149 return Optional.empty();
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);
156 toscaGetFunction.setPropertySource(PropertySource.INSTANCE);
157 toscaGetFunction.setSourceName(propertySourceType);
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);
171 if (StringUtils.isNumeric(indexValue)) {
172 indexParsedList.add(Integer.parseInt(indexValue));
174 indexParsedList.add(indexValue);
178 toscaGetFunction.setToscaIndexList(indexParsedList);
180 toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
181 final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
182 toscaGetFunction.setPropertyName(propertyName);
183 return Optional.of(toscaGetFunction);
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();
194 if (functionValueObj instanceof String) {
195 toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj));
197 final List<String> functionParameters;
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();
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);
216 if (StringUtils.isNumeric(indexValue)) {
217 indexParsedList.add(Integer.parseInt(indexValue));
219 indexParsedList.add(indexValue);
223 toscaGetFunction.setToscaIndexList(indexParsedList);
225 toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
227 final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
228 toscaGetFunction.setPropertyName(propertyName);
229 return Optional.of(toscaGetFunction);
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;
238 if (valueAsMap.containsKey(ToscaFunctionType.GET_ATTRIBUTE.getName())) {
239 return FilterValueType.GET_ATTRIBUTE;
241 if (valueAsMap.containsKey(ToscaFunctionType.GET_PROPERTY.getName())) {
242 return FilterValueType.GET_PROPERTY;
244 if (valueAsMap.containsKey(ToscaFunctionType.GET_INPUT.getName())) {
245 return FilterValueType.GET_INPUT;
249 return FilterValueType.STATIC;