Support TOSCA functions in Node Filters
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / datamodel / utils / ConstraintConvertor.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.datamodel.utils;
21
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Optional;
27 import java.util.Set;
28 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
29 import org.openecomp.sdc.be.datatypes.enums.PropertySource;
30 import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
31 import org.openecomp.sdc.be.ui.model.UIConstraint;
32 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import org.yaml.snakeyaml.DumperOptions;
36 import org.yaml.snakeyaml.Yaml;
37
38 public class ConstraintConvertor {
39
40     public static final String STATIC_CONSTRAINT = "static";
41     public static final String PROPERTY_CONSTRAINT = "property";
42     public static final String SERVICE_INPUT_CONSTRAINT = "service_input";
43     public static final String SELF = "SELF";
44     private static final Logger logger = LoggerFactory.getLogger(ConstraintConvertor.class);
45     private static final Set<ConstraintType> SUPPORTED_CONSTRAINT_LIST =
46         Set.of(ConstraintType.EQUAL, ConstraintType.GREATER_THAN, ConstraintType.LESS_THAN,
47             ConstraintType.GREATER_OR_EQUAL, ConstraintType.LESS_OR_EQUAL);
48
49     public UIConstraint convert(final String constraintValue) {
50         return convert(constraintValue, null);
51     }
52
53     public UIConstraint convert(final String inConstraint, final String valueType) {
54         Yaml yamlSource = new Yaml();
55         UIConstraint uiConstraint = new UIConstraint();
56         Object content1 = yamlSource.load(inConstraint);
57         if (!(content1 instanceof Map)) {
58             return null;
59         }
60         Map propertyAndConstraintMap = (Map) content1;
61         Object propertyNameKey = propertyAndConstraintMap.keySet().iterator().next();
62         uiConstraint.setServicePropertyName(propertyNameKey.toString());
63         Object operatorMapObj = propertyAndConstraintMap.get(propertyNameKey);
64         if (!(operatorMapObj instanceof Map)) {
65             return null;
66         }
67         Map operatorMap = (Map) operatorMapObj;
68         Object operatorKey = operatorMap.keySet().iterator().next();
69         final String operator = (String) operatorKey;
70         final Optional<ConstraintType> constraintType = ConstraintType.findByType(operator);
71         if (constraintType.isPresent() && SUPPORTED_CONSTRAINT_LIST.contains(constraintType.get())) {
72             uiConstraint.setConstraintOperator(operator);
73         }
74         Object constraintValueObj = operatorMap.get(operatorKey);
75         if (constraintValueObj instanceof String || constraintValueObj instanceof Number || constraintValueObj instanceof Boolean) {
76             uiConstraint.setValue(constraintValueObj);
77             uiConstraint.setSourceType(STATIC_CONSTRAINT);
78             uiConstraint.setSourceName(STATIC_CONSTRAINT);
79             return uiConstraint;
80         } else if (constraintValueObj instanceof List) {
81             uiConstraint.setSourceType(STATIC_CONSTRAINT);
82             uiConstraint.setSourceName(STATIC_CONSTRAINT);
83             uiConstraint.setValue(constraintValueObj);
84             return uiConstraint;
85         } else if ("string".equals(valueType)) {
86             uiConstraint.setSourceType(STATIC_CONSTRAINT);
87             uiConstraint.setSourceName(STATIC_CONSTRAINT);
88             uiConstraint.setValue(dumpYamlString(constraintValueObj));
89             return uiConstraint;
90         } else if (constraintValueObj instanceof Map) {
91             return handleMap(uiConstraint, (Map<Object, Object>) constraintValueObj);
92         }
93         return null;
94     }
95
96     private String dumpYamlString(final Object constraintValueObj) {
97         final var dumperOptions = new DumperOptions();
98         dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
99         return new Yaml(dumperOptions).dump(constraintValueObj);
100     }
101
102     private UIConstraint handleMap(final UIConstraint uiConstraint, final Map<Object, Object> constraintValueAsMap) {
103         final Map.Entry<Object, Object> entry = constraintValueAsMap.entrySet().iterator().next();
104         final String firstKey = entry.getKey().toString().trim();
105         final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType(firstKey).orElse(null);
106         if (toscaFunctionType == null) {
107             uiConstraint.setValue(constraintValueAsMap);
108             return uiConstraint;
109         }
110         uiConstraint.setValue(constraintValueAsMap);
111         uiConstraint.setSourceType(toscaFunctionType.getName());
112         switch (toscaFunctionType) {
113             case GET_INPUT:
114                 uiConstraint.setSourceName(PropertySource.SELF.getName());
115                 break;
116             case GET_PROPERTY:
117             case GET_ATTRIBUTE:
118                 final List<String> value = (List<String>) entry.getValue();
119                 uiConstraint.setSourceName(value.get(0));
120                 break;
121             default:
122                 break;
123         }
124
125         return uiConstraint;
126     }
127
128     public List<String> convertToList(List<UIConstraint> uiConstraints) {
129         List<String> retVal = new ArrayList<>();
130         for (UIConstraint uiConstraint : uiConstraints) {
131             String constraint = convert(uiConstraint);
132             if (constraint != null) {
133                 retVal.add(constraint);
134             }
135         }
136         return retVal;
137     }
138
139     public String convert(final UIConstraint uiConstraint) {
140         try {
141             final Map<String, Object> constraintAsMap = new HashMap<>();
142             switch (uiConstraint.getSourceType()) {
143                 case STATIC_CONSTRAINT: {
144                     Object value = uiConstraint.getValue();
145                     if (value instanceof String) {
146                         value = new Yaml().load(value.toString());
147                     }
148                     constraintAsMap.put(uiConstraint.getConstraintOperator(), value);
149                     break;
150                 }
151                 case PROPERTY_CONSTRAINT:
152                     constraintAsMap.put(uiConstraint.getConstraintOperator(),
153                         Map.of(ToscaFunctions.GET_PROPERTY.getFunctionName(), List.of(uiConstraint.getSourceName(), uiConstraint.getValue()))
154                     );
155                     break;
156                 case SERVICE_INPUT_CONSTRAINT:
157                     constraintAsMap.put(uiConstraint.getConstraintOperator(), Map.of(ToscaFunctions.GET_INPUT.getFunctionName(), uiConstraint.getValue()));
158                     break;
159                 default: {
160                     if (ToscaFunctionType.findType(uiConstraint.getSourceType()).isPresent()) {
161                         Object value = uiConstraint.getValue();
162                         if (value instanceof String) {
163                             value = new Yaml().load((String) value);
164                         }
165                         constraintAsMap.put(uiConstraint.getConstraintOperator(), value);
166                     }
167                 }
168             }
169             return new Yaml().dump(Map.of(uiConstraint.getServicePropertyName(), constraintAsMap));
170         } catch (final Exception ex) {
171             logger.error("Could not convert constraint", ex);
172         }
173         return null;
174     }
175
176     public UIConstraint getUiConstraint(final String inConstraint, final UIConstraint uiConstraint) {
177         final Object constraintObject = new Yaml().load(inConstraint);
178         if (!(constraintObject instanceof Map)) {
179             return null;
180         }
181         final Map constraintMap = (Map) constraintObject;
182         final Object capabilityName = constraintMap.keySet().iterator().next();
183         uiConstraint.setServicePropertyName(capabilityName.toString());
184         Object capabilityProperties = constraintMap.get(capabilityName);
185         if (!(capabilityProperties instanceof Map)) {
186             return null;
187         }
188         final Map capabilityPropertiesMap = (Map) capabilityProperties;
189         final Object constraintOperator = capabilityPropertiesMap.keySet().iterator().next();
190         final String operator = constraintOperator.toString();
191         if (SUPPORTED_CONSTRAINT_LIST.contains(operator)) {
192             uiConstraint.setConstraintOperator(operator);
193         }
194         final Object constraintValue = capabilityPropertiesMap.get(constraintOperator);
195         if (constraintValue instanceof String || constraintValue instanceof Number || constraintValue instanceof Boolean) {
196             uiConstraint.setValue(constraintValue);
197             uiConstraint.setSourceType(STATIC_CONSTRAINT);
198             uiConstraint.setSourceName(STATIC_CONSTRAINT);
199             return uiConstraint;
200         } else if (constraintValue instanceof List) {
201             uiConstraint.setSourceType(STATIC_CONSTRAINT);
202             uiConstraint.setSourceName(STATIC_CONSTRAINT);
203             uiConstraint.setValue(constraintValue);
204             return uiConstraint;
205         } else if (constraintValue instanceof Map) {
206             return handleMap(uiConstraint, (Map<Object, Object>) constraintValue);
207         }
208         return null;
209     }
210 }