Fix use of Optional in TranslatorHeatToToscaParameterConverter
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / mapping / TranslatorHeatToToscaParameterConverter.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.openecomp.sdc.translator.services.heattotosca.mapping;
17
18 import static org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation.FunctionTranslator.getFunctionTranslateTo;
19
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Objects;
26 import java.util.Optional;
27 import org.apache.commons.collections4.MapUtils;
28 import org.apache.commons.lang3.StringUtils;
29 import org.onap.sdc.tosca.datatypes.model.Constraint;
30 import org.onap.sdc.tosca.datatypes.model.EntrySchema;
31 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
32 import org.onap.sdc.tosca.datatypes.model.ScalarUnitValidator;
33 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
34 import org.onap.sdc.tosca.datatypes.model.heatextend.AnnotationDefinition;
35 import org.onap.sdc.tosca.datatypes.model.heatextend.ParameterDefinitionExt;
36 import org.openecomp.core.utilities.file.FileUtils;
37 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
38 import org.openecomp.sdc.heat.datatypes.ToscaScalarUnitFrequency;
39 import org.openecomp.sdc.heat.datatypes.ToscaScalarUnitSize;
40 import org.openecomp.sdc.heat.datatypes.ToscaScalarUnitTime;
41 import org.openecomp.sdc.heat.datatypes.ToscaScalarUnitTypes;
42 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
43 import org.openecomp.sdc.heat.datatypes.model.Output;
44 import org.openecomp.sdc.heat.datatypes.model.Parameter;
45 import org.openecomp.sdc.tosca.datatypes.extend.ToscaAnnotationType;
46 import org.openecomp.sdc.tosca.services.ToscaConstants;
47 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
48 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslationFactory;
49 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
50 import org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation.FunctionTranslator;
51
52 public class TranslatorHeatToToscaParameterConverter {
53
54     private static final String RANGE = "range";
55     private static final String LENGTH = "length";
56     private static final String MIN = "min";
57     private static final String MAX = "max";
58     private static final String ALLOWED_VALUES = "allowed_values";
59     private static final String ALLOWED_PATTERN = "allowed_pattern";
60     private static Map<String, String> parameterTypeMapping;
61     private static Map<String, String> parameterEntrySchemaTypeMapping;
62
63     static {
64         parameterEntrySchemaTypeMapping = new HashMap<>();
65         parameterEntrySchemaTypeMapping.put("list", "string");
66     }
67
68     static {
69         parameterTypeMapping = new HashMap<>();
70         parameterTypeMapping.put("string", "string");
71         parameterTypeMapping.put("number", "float");
72         parameterTypeMapping.put("comma_delimited_list", "list");
73         parameterTypeMapping.put("json", "json");
74         parameterTypeMapping.put("boolean", "boolean");
75     }
76
77     /**
78      * Parameter converter map.
79      *
80      * @param parameters                the parameters
81      * @param heatOrchestrationTemplate the heat orchestration template
82      * @param heatFileName              the heat file name
83      * @param context                   the context
84      * @return the map
85      */
86     public static Map<String, ParameterDefinition> parameterConverter(ServiceTemplate serviceTemplate, Map<String, Parameter> parameters,
87                                                                       HeatOrchestrationTemplate heatOrchestrationTemplate, String heatFileName,
88                                                                       String parentHeatFileName, TranslationContext context,
89                                                                       Map<String, Object> heatEnvParameters) {
90         Map<String, ParameterDefinition> parameterDefinitionMap = new HashMap<>();
91         for (Map.Entry<String, Parameter> entry : parameters.entrySet()) {
92             String heatParamName = entry.getKey();
93             parameterDefinitionMap.put(heatParamName,
94                 getToscaParameter(serviceTemplate, heatParamName, entry.getValue(), heatOrchestrationTemplate, heatFileName, parentHeatFileName,
95                     context, heatEnvParameters));
96         }
97         return parameterDefinitionMap;
98     }
99
100     /**
101      * Parameter output converter map.
102      *
103      * @param parameters                the parameters
104      * @param heatOrchestrationTemplate the heat orchestration template
105      * @param heatFileName              the heat file name
106      * @param context                   the context
107      * @return the map
108      */
109     public static Map<String, ParameterDefinition> parameterOutputConverter(ServiceTemplate serviceTemplate, Map<String, Output> parameters,
110                                                                             HeatOrchestrationTemplate heatOrchestrationTemplate, String heatFileName,
111                                                                             TranslationContext context) {
112         Map<String, ParameterDefinition> parameterDefinitionMap = new HashMap<>();
113         for (Map.Entry<String, Output> entry : parameters.entrySet()) {
114             parameterDefinitionMap.put(entry.getKey(),
115                 getToscaOutputParameter(serviceTemplate, entry.getKey(), entry.getValue(), heatOrchestrationTemplate, heatFileName, context));
116         }
117         return parameterDefinitionMap;
118     }
119
120     /**
121      * Gets tosca parameter.
122      *
123      * @param heatParameter             the heat parameter
124      * @param heatOrchestrationTemplate the heat orchestration template
125      * @param heatFileName              the heat file name
126      * @param context                   the context
127      * @return the tosca parameter
128      */
129     private static ParameterDefinitionExt getToscaParameter(ServiceTemplate serviceTemplate, String heatParameterName, Parameter heatParameter,
130                                                             HeatOrchestrationTemplate heatOrchestrationTemplate, String heatFileName,
131                                                             String parentHeatFileName, TranslationContext context,
132                                                             Map<String, Object> heatEnvParameters) {
133         ParameterDefinitionExt toscaParameter = new ParameterDefinitionExt();
134         toscaParameter.setType(getToscaParameterType(heatParameter.getType(), heatEnvParameters));
135         toscaParameter.setEntry_schema(getToscaParameterEntrySchema(toscaParameter.getType()));
136         toscaParameter.setLabel(heatParameter.getLabel());
137         toscaParameter.setDescription(heatParameter.getDescription());
138         toscaParameter.set_default(
139             getToscaParameterDefaultValue(serviceTemplate, heatParameterName, heatParameter.get_default(), toscaParameter.getType(), heatFileName,
140                 heatOrchestrationTemplate, context));
141         toscaParameter.setHidden(heatParameter.isHidden());
142         toscaParameter.setImmutable(heatParameter.isImmutable());
143         toscaParameter.setConstraints(getToscaConstrains(heatParameter.getConstraints()));
144         Optional<Map<String, AnnotationDefinition>> annotations = getToscaAnnotations(context, heatFileName, parentHeatFileName, heatParameterName);
145         annotations.ifPresent(ant -> toscaParameter.setAnnotations(annotations.get()));
146         return toscaParameter;
147     }
148
149     private static Optional<Map<String, AnnotationDefinition>> getToscaAnnotations(TranslationContext context, String heatFileName,
150                                                                                    String parentHeatFileName, String heatParameterName) {
151         if (parentHeatFileName != null) {
152             heatFileName = parentHeatFileName;
153         }
154         if (!isAnnotationRequired(context, heatFileName)) {
155             return Optional.empty();
156         }
157         AnnotationDefinition annotationDefinition = new AnnotationDefinition();
158         annotationDefinition.setType(ToscaAnnotationType.SOURCE);
159         annotationDefinition.setProperties(new HashMap<>());
160         List<String> vfModuleList = new ArrayList<>();
161         vfModuleList.add(FileUtils.getFileWithoutExtention(heatFileName));
162         annotationDefinition.getProperties().put(ToscaConstants.VF_MODULE_LABEL_PROPERTY_NAME, vfModuleList);
163         annotationDefinition.getProperties().put(ToscaConstants.SOURCE_TYPE_PROPERTY_NAME, ToscaConstants.HEAT_SOURCE_TYPE);
164         annotationDefinition.getProperties().put(ToscaConstants.PARAM_NAME_PROPERTY_NAME, heatParameterName);
165         Map<String, AnnotationDefinition> annotationMap = new HashMap<>();
166         annotationMap.put(ToscaConstants.SOURCE_ANNOTATION_ID, annotationDefinition);
167         return Optional.of(annotationMap);
168     }
169
170     private static boolean isAnnotationRequired(TranslationContext context, String heatFileName) {
171         return !isNestedServiceTemplate(context, heatFileName);
172     }
173
174     private static boolean isNestedServiceTemplate(TranslationContext context, String heatFileName) {
175         return HeatToToscaUtil.isHeatFileNested(context, heatFileName);
176     }
177
178     /**
179      * Gets tosca output parameter.
180      *
181      * @param heatOutputParameter       the heat output parameter
182      * @param heatOrchestrationTemplate the heat orchestration template
183      * @param heatFileName              the heat file name
184      * @param context                   the context
185      * @return the tosca output parameter
186      */
187     private static ParameterDefinitionExt getToscaOutputParameter(ServiceTemplate serviceTemplate, String parameterName, Output heatOutputParameter,
188                                                                   HeatOrchestrationTemplate heatOrchestrationTemplate, String heatFileName,
189                                                                   TranslationContext context) {
190         ParameterDefinitionExt toscaParameter = new ParameterDefinitionExt();
191         toscaParameter.setDescription(heatOutputParameter.getDescription());
192         toscaParameter.setValue(
193             getToscaParameterDefaultValue(serviceTemplate, parameterName, heatOutputParameter.getValue(), toscaParameter.getType(), heatFileName,
194                 heatOrchestrationTemplate, context));
195         return toscaParameter;
196     }
197
198     /**
199      * Gets tosca parameter default value.
200      *
201      * @param obj                       the a default
202      * @param type                      the type
203      * @param heatFileName              the heat file name
204      * @param heatOrchestrationTemplate the heat orchestration template
205      * @param context                   the context
206      * @return the tosca parameter default value
207      */
208     public static Object getToscaParameterDefaultValue(ServiceTemplate serviceTemplate, String parameterName, Object obj, String type,
209                                                        String heatFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
210                                                        TranslationContext context) {
211         if (obj == null) {
212             return null;
213         }
214         Object toscaDefaultValue = obj;
215         if ("list".equals(type)) {
216             if (obj instanceof String) {
217                 return Arrays.asList(((String) obj).split(","));
218             } else {
219                 return toscaDefaultValue;
220             }
221         }
222         return getToscaParameterValue(serviceTemplate, parameterName, toscaDefaultValue, heatFileName, heatOrchestrationTemplate, context);
223     }
224
225     private static Object getToscaParameterValue(ServiceTemplate serviceTemplate, String parameterName, Object paramValue, String heatFileName,
226                                                  HeatOrchestrationTemplate heatOrchestrationTemplate, TranslationContext context) {
227         if (paramValue instanceof Map) {
228             if (MapUtils.isEmpty((Map) paramValue)) {
229                 return new HashMap<>();
230             }
231             Map.Entry<String, Object> functionMapEntry = (Map.Entry<String, Object>) ((Map) paramValue).entrySet().iterator().next();
232             if (FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).isPresent()) {
233                 FunctionTranslator functionTranslator = new FunctionTranslator(
234                     getFunctionTranslateTo(serviceTemplate, null, heatFileName, heatOrchestrationTemplate, context), parameterName,
235                     functionMapEntry.getValue(), null);
236                 return FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).isPresent() ? FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).get().translateFunction(functionTranslator) : paramValue;
237             }
238         }
239         return paramValue;
240     }
241
242     private static List<Constraint> getToscaConstrains(List<Map<String, Object>> constraints) {
243         if (constraints == null) {
244             return null;
245         }
246         List<Constraint> constraintList = new ArrayList<>();
247         for (Map<String, Object> constraint : constraints) {
248             constraintList.addAll(getToscaParameterConstraint(constraint));
249         }
250         return constraintList;
251     }
252
253     private static List<Constraint> getToscaParameterConstraint(Map<String, Object> constraint) {
254         List<Constraint> convertedConstraintList = new ArrayList<>();
255         Constraint convertedConstraint;
256         if (constraint.containsKey(RANGE)) {
257             convertedConstraint = new Constraint();
258             convertedConstraintList.add(convertedConstraint);
259             Integer min = (Integer) ((Map) constraint.get(RANGE)).get(MIN);
260             Integer max = (Integer) ((Map) constraint.get(RANGE)).get(MAX);
261             convertedConstraint.setIn_range(new Integer[]{min, max});
262         } else if (constraint.containsKey(LENGTH)) {
263             Integer min = (Integer) ((Map) constraint.get(LENGTH)).get(MIN);
264             Integer max = (Integer) ((Map) constraint.get(LENGTH)).get(MAX);
265             if (max != null) {
266                 convertedConstraint = new Constraint();
267                 convertedConstraintList.add(convertedConstraint);
268                 convertedConstraint.setMax_length(max);
269             }
270             if (min != null) {
271                 convertedConstraint = new Constraint();
272                 convertedConstraintList.add(convertedConstraint);
273                 convertedConstraint.setMin_length(min);
274             }
275         } else if (constraint.containsKey(ALLOWED_VALUES)) {
276             convertedConstraint = new Constraint();
277             convertedConstraintList.add(convertedConstraint);
278             convertedConstraint.setValid_values((List) constraint.get(ALLOWED_VALUES));
279         } else if (constraint.containsKey(ALLOWED_PATTERN)) {
280             convertedConstraint = new Constraint();
281             convertedConstraintList.add(convertedConstraint);
282             convertedConstraint.setPattern(constraint.get(ALLOWED_PATTERN));
283         }
284         return convertedConstraintList;
285     }
286
287     private static EntrySchema getToscaParameterEntrySchema(String type) {
288         if (!parameterEntrySchemaTypeMapping.containsKey(type)) {
289             return null;
290         }
291         EntrySchema entrySchema = new EntrySchema();
292         entrySchema.setType(parameterEntrySchemaTypeMapping.get(type));
293         return entrySchema;
294     }
295
296     protected static String getToscaParameterType(final String heatParameterType, final Map<String, Object> heatEnvParameters) {
297         if (heatEnvParameters != null && DefinedHeatParameterTypes.NUMBER.getType().equals(heatParameterType)) {
298             if (getScalarUnitType(heatEnvParameters, ToscaScalarUnitSize.class) != null) {
299                 return ToscaScalarUnitTypes.SCALAR_UNIT_SIZE.getType();
300             } else if (getScalarUnitType(heatEnvParameters, ToscaScalarUnitTime.class) != null) {
301                 return ToscaScalarUnitTypes.SCALAR_UNIT_TIME.getType();
302             } else if (getScalarUnitType(heatEnvParameters, ToscaScalarUnitFrequency.class) != null) {
303                 return ToscaScalarUnitTypes.SCALAR_UNIT_FREQUENCY.getType();
304             }
305         }
306         return parameterTypeMapping.get(heatParameterType);
307     }
308
309     private static <E extends Enum<E>> String getScalarUnitType(final Map<String, Object> heatEnvParameters, final Class<E> enumClass) {
310         final ScalarUnitValidator scalarUnitValidator = ScalarUnitValidator.getInstance();
311         if (Arrays.stream(enumClass.getEnumConstants()).anyMatch(unitType -> heatEnvParameters.values().stream().filter(Objects::nonNull).anyMatch(
312             parameterValue -> scalarUnitValidator.isScalarUnit(parameterValue.toString()) && Arrays
313                 .stream(StringUtils.split(parameterValue.toString())).anyMatch(strParamValue -> strParamValue.equalsIgnoreCase(unitType.name()))))) {
314             return enumClass.getTypeName();
315         }
316         return null;
317     }
318 }