2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.components.impl;
23 import com.google.gson.Gson;
24 import com.google.gson.GsonBuilder;
25 import com.google.gson.reflect.TypeToken;
26 import fj.data.Either;
27 import org.apache.commons.lang3.StringEscapeUtils;
28 import org.openecomp.sdc.be.components.impl.utils.ExceptionUtils;
29 import org.openecomp.sdc.be.datatypes.elements.Annotation;
30 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
31 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
32 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
33 import org.openecomp.sdc.be.impl.ComponentsUtils;
34 import org.openecomp.sdc.be.model.*;
35 import org.openecomp.sdc.be.model.heat.HeatParameterType;
36 import org.openecomp.sdc.be.model.operations.impl.AnnotationTypeOperations;
37 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser;
38 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
39 import org.openecomp.sdc.be.utils.TypeUtils;
40 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
41 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
42 import org.openecomp.sdc.common.log.wrappers.Logger;
43 import org.openecomp.sdc.exception.ResponseFormat;
44 import org.springframework.beans.factory.annotation.Autowired;
45 import org.springframework.beans.factory.config.YamlProcessor;
46 import org.yaml.snakeyaml.DumperOptions;
47 import org.yaml.snakeyaml.Yaml;
48 import org.yaml.snakeyaml.constructor.Constructor;
49 import org.yaml.snakeyaml.nodes.Tag;
50 import org.yaml.snakeyaml.representer.Representer;
51 import org.yaml.snakeyaml.resolver.Resolver;
53 import java.lang.reflect.Type;
55 import java.util.Map.Entry;
56 import java.util.function.Consumer;
57 import java.util.function.Function;
59 import static org.apache.commons.collections.CollectionUtils.isEmpty;
60 import static org.openecomp.sdc.be.components.impl.ResourceImportManager.PROPERTY_NAME_PATTERN_IGNORE_LENGTH;
61 import static org.openecomp.sdc.be.datatypes.elements.Annotation.setAnnotationsName;
64 public final class ImportUtils {
67 private static final CustomResolver customResolver = new CustomResolver();
68 private static final Yaml strictYamlLoader = new YamlLoader().getStrictYamlLoader();
71 protected static ComponentsUtils componentsUtils;
74 private ExceptionUtils exceptionUtils;
76 private static final Logger log = Logger.getLogger(ImportUtils.class);
78 private ImportUtils() {
82 private static class CustomResolver extends Resolver {
84 protected void addImplicitResolvers() {
85 // avoid implicit resolvers for strings that can be interpreted as boolean values
86 addImplicitResolver(Tag.STR, EMPTY, "");
87 addImplicitResolver(Tag.STR, NULL, null);
88 addImplicitResolver(Tag.NULL, NULL, "~nN\0");
89 addImplicitResolver(Tag.NULL, EMPTY, null);
90 addImplicitResolver(Tag.INT, INT, "-+0123456789");
91 addImplicitResolver(Tag.FLOAT, FLOAT, "-+0123456789.");
92 addImplicitResolver(Tag.YAML, YAML, "!&*");
97 private static void buildMap(Map<String, Object> output, Map<String, Object> map) {
98 for (Entry<String, Object> entry : map.entrySet()) {
99 String key = entry.getKey();
100 Object value = entry.getValue();
101 if (value instanceof Map) {
102 Map<String, Object> result = new LinkedHashMap<>();
103 buildMap(result, (Map) value);
104 output.put(key, result);
106 else if (value instanceof Collection) {
107 Map<String, Object> result = new LinkedHashMap<>();
109 for(Object item : (Collection<Object>) value) {
110 buildMap(result, Collections.singletonMap("[" + (i++) + "]", item));
112 output.put(key, new ArrayList<>(result.values()));
115 output.put(key, value);
120 public static Map<String, Object> loadYamlAsStrictMap(String content){
121 Map<String, Object> result = new LinkedHashMap<>();
122 Object map = strictYamlLoader.load(content);
123 buildMap(result, (Map<String, Object>)map);
127 private static class YamlLoader extends YamlProcessor {
128 public Yaml getStrictYamlLoader() {
133 @SuppressWarnings("unchecked")
134 public static Either<List<HeatParameterDefinition>, ResultStatusEnum> getHeatParamsWithoutImplicitTypes(String heatDecodedPayload, String artifactType) {
135 Map<String, Object> heatData = (Map<String, Object>) new Yaml(new Constructor(), new Representer(), new DumperOptions(), customResolver).load(heatDecodedPayload);
136 return getHeatParameters(heatData, artifactType);
139 public static class Constants {
140 public static final String FIRST_NON_CERTIFIED_VERSION = "0.1";
141 public static final String VENDOR_NAME = "ONAP (Tosca)";
142 public static final String VENDOR_RELEASE = "1.0.0.wd03";
143 public static final LifecycleStateEnum NORMATIVE_TYPE_LIFE_CYCLE = LifecycleStateEnum.CERTIFIED;
144 public static final LifecycleStateEnum NORMATIVE_TYPE_LIFE_CYCLE_NOT_CERTIFIED_CHECKOUT = LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT;
145 public static final boolean NORMATIVE_TYPE_HIGHEST_VERSION = true;
146 public static final String ABSTRACT_CATEGORY_NAME = "Generic";
147 public static final String ABSTRACT_SUBCATEGORY = "Abstract";
148 public static final String DEFAULT_ICON = "defaulticon";
149 public static final String INNER_VFC_DESCRIPTION = "Not reusable inner VFC";
150 public static final String USER_DEFINED_RESOURCE_NAMESPACE_PREFIX = "org.openecomp.resource.";
151 public static final String UI_JSON_PAYLOAD_NAME = "payloadName";
152 public static final String CVFC_DESCRIPTION = "Complex node type that is used as nested type in VF";
154 private Constants() {}
157 public enum ResultStatusEnum {
158 ELEMENT_NOT_FOUND, GENERAL_ERROR, OK, INVALID_PROPERTY_DEFAULT_VALUE, INVALID_PROPERTY_TYPE, INVALID_PROPERTY_VALUE, MISSING_ENTRY_SCHEMA_TYPE, INVALID_PROPERTY_NAME
161 public enum ToscaElementTypeEnum {
162 BOOLEAN, STRING, MAP, LIST, ALL
165 @SuppressWarnings("unchecked")
166 private static void handleElementNameNotFound(String elementName, Object elementValue, ToscaElementTypeEnum elementType, List<Object> returnedList) {
167 if (elementValue instanceof Map) {
168 ImportUtils.findToscaElements((Map<String, Object>) elementValue, elementName, elementType, returnedList);
169 } else if (elementValue instanceof List) {
170 ImportUtils.findAllToscaElementsInList((List<Object>) elementValue, elementName, elementType, returnedList);
174 @SuppressWarnings("unchecked")
175 private static void addFoundElementAccordingToItsType(String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList, Object elementValue) {
177 if (elementValue instanceof Boolean) {
178 if (elementType == ToscaElementTypeEnum.BOOLEAN || elementType == ToscaElementTypeEnum.ALL) {
179 returnedList.add(elementValue);
183 else if (elementValue instanceof String) {
184 if (elementType == ToscaElementTypeEnum.STRING || elementType == ToscaElementTypeEnum.ALL) {
185 returnedList.add(elementValue);
187 } else if (elementValue instanceof Map) {
188 if (elementType == ToscaElementTypeEnum.MAP || elementType == ToscaElementTypeEnum.ALL) {
189 returnedList.add(elementValue);
191 ImportUtils.findToscaElements((Map<String, Object>) elementValue, elementName, elementType, returnedList);
193 } else if (elementValue instanceof List) {
194 if (elementType == ToscaElementTypeEnum.LIST || elementType == ToscaElementTypeEnum.ALL) {
195 returnedList.add(elementValue);
197 ImportUtils.findAllToscaElementsInList((List<Object>) elementValue, elementName, elementType, returnedList);
200 // For Integer, Double etc...
201 else if (elementType == ToscaElementTypeEnum.ALL && elementValue != null) {
202 returnedList.add(String.valueOf(elementValue));
206 private static void findAllToscaElementsInList(List<Object> list, String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList) {
207 list.forEach(elementValue -> handleElementNameNotFound(elementName, elementValue, elementType, returnedList));
210 public static Either<Object, ResultStatusEnum> findToscaElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum elementName, ToscaElementTypeEnum elementType) {
211 List<Object> foundElements = new ArrayList<>();
212 ImportUtils.findToscaElements(toscaJson, elementName.getElementName(), elementType, foundElements);
213 if (!isEmpty(foundElements)) {
214 return Either.left(foundElements.get(0));
216 return Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
220 * Recursively searches for all tosca elements with key equals to elementName and value equals to elementType. <br>
221 * Returns Either element with:<br>
222 * List with all value if values found<br>
223 * Or ELEMENT_NOT_FOUND ActionStatus
228 public static Either<List<Object>, ResultStatusEnum> findToscaElements(Map<String, Object> toscaJson, String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList) {
229 Either<List<Object>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
230 String skipKey = null;
231 if (toscaJson.containsKey(elementName)) {
232 skipKey = handleFoundElement(toscaJson, elementName, elementType, returnedList);
236 Iterator<Entry<String, Object>> keyValItr = toscaJson.entrySet().iterator();
237 while (keyValItr.hasNext()) {
238 Entry<String, Object> keyValEntry = keyValItr.next();
239 if (!String.valueOf(keyValEntry.getKey()).equals(skipKey)) {
240 handleElementNameNotFound(elementName, keyValEntry.getValue(), elementType, returnedList);
244 if (!isEmpty(returnedList)) {
245 returnedElement = Either.left(returnedList);
248 return returnedElement;
251 private static String handleFoundElement(Map<String, Object> toscaJson, String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList) {
252 Object elementValue = toscaJson.get(elementName);
253 addFoundElementAccordingToItsType(elementName, elementType, returnedList, elementValue);
258 @SuppressWarnings("unchecked")
259 public static <T> Either<List<T>, ResultStatusEnum> findFirstToscaListElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum toscaTagName) {
260 Either<List<T>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
261 Either<Object, ResultStatusEnum> findFirstToscaElement = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.LIST);
262 if (findFirstToscaElement.isLeft()) {
263 returnedElement = Either.left((List<T>) findFirstToscaElement.left().value());
265 return returnedElement;
269 @SuppressWarnings("unchecked")
270 public static <T> Either<Map<String, T>, ResultStatusEnum> findFirstToscaMapElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum toscaTagName) {
271 Either<Map<String, T>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
272 Either<Object, ResultStatusEnum> findFirstToscaElement = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.MAP);
273 if (findFirstToscaElement.isLeft()) {
274 returnedElement = Either.left((Map<String, T>) findFirstToscaElement.left().value());
276 return returnedElement;
280 public static Either<String, ResultStatusEnum> findFirstToscaStringElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum toscaTagName) {
281 Either<String, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
282 Either<Object, ResultStatusEnum> findFirstToscaElements = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.STRING);
283 if (findFirstToscaElements.isLeft()) {
284 returnedElement = Either.left((String) findFirstToscaElements.left().value());
286 return returnedElement;
290 * searches for first Tosca in Json map (toscaJson) boolean element by name (toscaTagName) returns found element or ELEMENT_NOT_FOUND status
293 * @param toscaTagName
296 public static Either<String, ResultStatusEnum> findFirstToscaBooleanElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum toscaTagName) {
297 Either<String, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
298 Either<Object, ResultStatusEnum> findFirstToscaElements = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.BOOLEAN);
299 if (findFirstToscaElements.isLeft()) {
300 returnedElement = Either.left(String.valueOf(findFirstToscaElements.left().value()));
302 return returnedElement;
305 private static void setPropertyConstraints(Map<String, Object> propertyValue, PropertyDefinition property) {
306 Either<List<Object>, ResultStatusEnum> propertyFieldconstraints = findFirstToscaListElement(propertyValue, TypeUtils.ToscaTagNamesEnum.CONSTRAINTS);
307 if (propertyFieldconstraints.isLeft()) {
308 List<Object> jsonConstraintList = propertyFieldconstraints.left().value();
310 List<PropertyConstraint> constraintList = new ArrayList<>();
311 Type constraintType = new TypeToken<PropertyConstraint>() {
313 Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create();
315 for (Object constraintJson : jsonConstraintList) {
316 PropertyConstraint propertyConstraint = gson.fromJson(gson.toJson(constraintJson), constraintType);
317 constraintList.add(propertyConstraint);
319 property.setConstraints(constraintList);
323 public static PropertyDefinition createModuleProperty(Map<String, Object> propertyValue) {
325 PropertyDefinition propertyDef = new PropertyDefinition();
326 setField(propertyValue, TypeUtils.ToscaTagNamesEnum.TYPE, propertyDef::setType);
327 setFieldBoolean(propertyValue, ToscaTagNamesEnum.REQUIRED, req -> propertyDef.setRequired(Boolean.parseBoolean(req)));
328 setField(propertyValue, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, propertyDef::setDescription);
330 setJsonStringField(propertyValue, TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE, propertyDef.getType(), propertyDef::setDefaultValue);
331 setJsonStringField(propertyValue, TypeUtils.ToscaTagNamesEnum.VALUE, propertyDef.getType(), propertyDef::setValue);
333 setFieldBoolean(propertyValue, TypeUtils.ToscaTagNamesEnum.IS_PASSWORD, pass -> propertyDef.setPassword(Boolean.parseBoolean(pass)));
334 setField(propertyValue, TypeUtils.ToscaTagNamesEnum.STATUS, propertyDef::setStatus);
335 setScheme(propertyValue, propertyDef);
336 setPropertyConstraints(propertyValue, propertyDef);
342 private static void setJsonStringField(Map<String, Object> propertyValue, ToscaTagNamesEnum elementName, String type, Consumer<String> setter) {
343 Either<Object, ResultStatusEnum> eitherValue = ImportUtils.findToscaElement(propertyValue, elementName, ToscaElementTypeEnum.ALL);
344 if (eitherValue.isLeft()) {
345 String propertyJsonStringValue = getPropertyJsonStringValue(eitherValue.left().value(), type);
346 setter.accept(propertyJsonStringValue);
352 public static Annotation createModuleAnnotation(Map<String, Object> annotationMap, AnnotationTypeOperations annotationTypeOperations) {
353 String parsedAnnotationType = findFirstToscaStringElement(annotationMap, TypeUtils.ToscaTagNamesEnum.TYPE).left().value();
354 AnnotationTypeDefinition annotationTypeObject = annotationTypeOperations.getLatestType(parsedAnnotationType);
355 if (annotationTypeObject != null) {
356 Annotation annotation = new Annotation();
357 ImportUtils.setField(annotationMap, TypeUtils.ToscaTagNamesEnum.TYPE, annotation::setType);
358 ImportUtils.setField(annotationMap, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, annotation::setDescription);
359 Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = getProperties(annotationMap);
360 modifyPropertiesKeysToProperForm(properties, annotation);
366 private static Either<Boolean, ResponseFormat> modifyPropertiesKeysToProperForm(Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties, Annotation annotation) {
367 Either<Boolean, ResponseFormat> result = Either.left(true);
368 if (properties.isLeft()) {
369 List<PropertyDataDefinition> propertiesList = new ArrayList<>();
370 Map<String, PropertyDefinition> value = properties.left().value();
372 for (Entry<String, PropertyDefinition> entry : value.entrySet()) {
373 String name = entry.getKey();
374 if (!PROPERTY_NAME_PATTERN_IGNORE_LENGTH.matcher(name).matches()) {
375 log.debug("The property with invalid name {} occurred upon import resource {}. ", name, annotation.getName());
376 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromResultStatusEnum(ResultStatusEnum.INVALID_PROPERTY_NAME, JsonPresentationFields.PROPERTY)));
378 PropertyDefinition propertyDefinition = entry.getValue();
379 propertyDefinition.setValue(propertyDefinition.getName());
380 propertyDefinition.setName(name);
381 propertiesList.add(propertyDefinition);
384 annotation.setProperties(propertiesList);
386 else if (properties.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND) {
387 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromResultStatusEnum(properties
389 .value(), JsonPresentationFields.PROPERTY)));
394 public static InputDefinition createModuleInput(Map<String, Object> inputValue, AnnotationTypeOperations annotationTypeOperations) {
396 InputDefinition inputDef = new InputDefinition();
397 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.TYPE, inputDef::setType);
398 ImportUtils.setFieldBoolean(inputValue, ToscaTagNamesEnum.REQUIRED, req -> inputDef.setRequired(Boolean.parseBoolean(req)));
399 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, inputDef::setDescription);
401 setJsonStringField(inputValue, TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE, inputDef.getType(), inputDef::setDefaultValue);
403 ImportUtils.setFieldBoolean(inputValue, TypeUtils.ToscaTagNamesEnum.IS_PASSWORD, pass -> inputDef.setPassword(Boolean.parseBoolean(pass)));
404 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.STATUS, inputDef::setStatus);
405 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.LABEL, inputDef::setLabel);
406 ImportUtils.setFieldBoolean(inputValue, TypeUtils.ToscaTagNamesEnum.HIDDEN, hidden -> inputDef.setHidden(Boolean.parseBoolean(hidden)));
407 ImportUtils.setFieldBoolean(inputValue, TypeUtils.ToscaTagNamesEnum.IMMUTABLE, immutable -> inputDef.setImmutable(Boolean.parseBoolean(immutable)));
409 ImportUtils.setScheme(inputValue, inputDef);
410 ImportUtils.setPropertyConstraints(inputValue, inputDef);
412 return parseAnnotationsAndAddItToInput(inputDef, inputValue, annotationTypeOperations);
417 public static InputDefinition parseAnnotationsAndAddItToInput(InputDefinition inputDef, Map<String, Object> inputValue, AnnotationTypeOperations annotationTypeOperations){
418 Function<String, Annotation> elementGenByName = ImportUtils::createAnnotation;
419 Function<Map<String, Object>, Annotation> func = annotation -> createModuleAnnotation(annotation, annotationTypeOperations);
420 return getElements(inputValue, TypeUtils.ToscaTagNamesEnum.ANNOTATIONS, elementGenByName, func).
421 left().map( annotations -> modifyInputWithAnnotations(inputDef, annotations)).
422 left().on(err -> { log.error("Parsing annotations or adding them to the PropertyDataDefinition object failed");
426 private static InputDefinition modifyInputWithAnnotations(InputDefinition inputDef, Map<String, Annotation> annotationsMap) {
427 setAnnotationsName(annotationsMap);
428 inputDef.setAnnotationsToInput(annotationsMap.values());
433 public static PropertyDefinition createModuleAttribute(Map<String, Object> attributeMap) {
435 PropertyDefinition attributeDef = new PropertyDefinition();
436 setField(attributeMap, TypeUtils.ToscaTagNamesEnum.TYPE, attributeDef::setType);
437 setField(attributeMap, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, attributeDef::setDescription);
438 setField(attributeMap, TypeUtils.ToscaTagNamesEnum.STATUS, attributeDef::setStatus);
440 setJsonStringField(attributeMap, TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE, attributeDef.getType(), attributeDef::setDefaultValue);
441 setJsonStringField(attributeMap, TypeUtils.ToscaTagNamesEnum.VALUE, attributeDef.getType(), attributeDef::setValue);
443 setScheme(attributeMap, attributeDef);
447 private static void setScheme(Map<String, Object> propertyValue, PropertyDefinition propertyDefinition) {
448 Either<SchemaDefinition, ResultStatusEnum> eitherSchema = getSchema(propertyValue);
449 if (eitherSchema.isLeft()) {
450 SchemaDefinition schemaDef = new SchemaDefinition();
451 schemaDef.setProperty(eitherSchema.left().value().getProperty());
452 propertyDefinition.setSchema(schemaDef);
457 private static Either<SchemaDefinition, ResultStatusEnum> getSchema(Map<String, Object> propertyValue) {
458 Either<SchemaDefinition, ResultStatusEnum> result = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
459 Either<Object, ResultStatusEnum> propertyFieldEntryScheme = findToscaElement(propertyValue, TypeUtils.ToscaTagNamesEnum.ENTRY_SCHEMA, ToscaElementTypeEnum.ALL);
460 if (propertyFieldEntryScheme.isLeft()) {
461 if (propertyFieldEntryScheme.left().value() instanceof String) {
462 String schemaType = (String) propertyFieldEntryScheme.left().value();
463 SchemaDefinition schema = new SchemaDefinition();
464 PropertyDefinition schemeProperty = new PropertyDefinition();
465 schemeProperty.setType(schemaType);
466 schema.setProperty(schemeProperty);
467 result = Either.left(schema);
469 } else if (propertyFieldEntryScheme.left().value() instanceof Map) {
470 PropertyDefinition schemeProperty = createModuleProperty((Map<String, Object>) propertyFieldEntryScheme.left().value());
471 SchemaDefinition schema = new SchemaDefinition();
472 schema.setProperty(schemeProperty);
473 result = Either.left(schema);
479 public static void setField(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum tagName, Consumer<String> setter) {
480 Either<String, ResultStatusEnum> fieldStringValue = findFirstToscaStringElement(toscaJson, tagName);
481 if (fieldStringValue.isLeft()) {
482 setter.accept(fieldStringValue.left().value());
487 public static void setFieldBoolean(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum tagName, Consumer<String> setter) {
488 Either<String, ResultStatusEnum> fieldStringValue = findFirstToscaBooleanElement(toscaJson, tagName);
489 if (fieldStringValue.isLeft()) {
490 setter.accept(fieldStringValue.left().value());
496 public static Either<Map<String, PropertyDefinition>, ResultStatusEnum> getProperties(Map<String, Object> toscaJson) {
497 Function<String, PropertyDefinition> elementGenByName = ImportUtils::createProperties;
498 Function<Map<String, Object>, PropertyDefinition> func = ImportUtils::createModuleProperty;
500 return getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.PROPERTIES, elementGenByName, func);
504 public static Either<Map<String, InputDefinition>, ResultStatusEnum> getInputs(Map<String, Object> toscaJson, AnnotationTypeOperations annotationTypeOperations) {
505 Function<String, InputDefinition> elementGenByName = ImportUtils::createInputs;
506 Function<Map<String, Object>, InputDefinition> func = object -> createModuleInput(object, annotationTypeOperations);
508 return getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.INPUTS, elementGenByName, func);
512 public static Either<Map<String, PropertyDefinition>, ResultStatusEnum> getAttributes(Map<String, Object> toscaJson) {
513 Function<String, PropertyDefinition> elementGenByName = ImportUtils::createAttribute;
514 Function<Map<String, Object>, PropertyDefinition> func = ImportUtils::createModuleAttribute;
516 return getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.ATTRIBUTES, elementGenByName, func);
519 public static <T> Either<Map<String, T>, ResultStatusEnum> getElements(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum elementTagName, Function<String, T> elementGenByName,
520 Function<Map<String, Object>, T> func) {
521 Either<Map<String, T>, ResultStatusEnum> eitherResult = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
522 Either<Map<String, Object>, ResultStatusEnum> toscaAttributes = findFirstToscaMapElement(toscaJson, elementTagName);
523 if (toscaAttributes.isLeft()) {
524 Map<String, Object> jsonAttributes = toscaAttributes.left().value();
525 Map<String, T> moduleAttributes = new HashMap<>();
526 Iterator<Entry<String, Object>> propertiesNameValue = jsonAttributes.entrySet().iterator();
527 while (propertiesNameValue.hasNext()) {
528 Entry<String, Object> attributeNameValue = propertiesNameValue.next();
529 if (attributeNameValue.getValue() instanceof Map) {
530 @SuppressWarnings("unchecked")
531 T attribute = func.apply((Map<String, Object>) attributeNameValue.getValue());
532 if (attribute != null){
533 moduleAttributes.put(String.valueOf(attributeNameValue.getKey()), attribute);
537 T element = elementGenByName.apply(String.valueOf(attributeNameValue.getValue()));
538 moduleAttributes.put(String.valueOf(attributeNameValue.getKey()), element);
541 if (moduleAttributes.size() > 0) {
542 eitherResult = Either.left(moduleAttributes);
550 private static PropertyDefinition createAttribute(String name) {
551 PropertyDefinition attribute = new PropertyDefinition();
553 attribute.setName(name);
557 private static PropertyDefinition createProperties(String name) {
558 PropertyDefinition property = new PropertyDefinition();
559 property.setDefaultValue(name);
560 property.setName(name);
566 private static InputDefinition createInputs(String name) {
567 InputDefinition input = new InputDefinition();
573 private static Annotation createAnnotation(String name) {
574 Annotation annotation = new Annotation();
575 annotation.setName(name);
581 public static Either<List<HeatParameterDefinition>, ResultStatusEnum> getHeatParameters(Map<String, Object> heatData, String artifactType) {
583 Either<List<HeatParameterDefinition>, ResultStatusEnum> eitherResult = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
584 Either<Map<String, Object>, ResultStatusEnum> toscaProperties = findFirstToscaMapElement(heatData, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
585 if (toscaProperties.isLeft()) {
586 Map<String, Object> jsonProperties = toscaProperties.left().value();
587 List<HeatParameterDefinition> moduleProperties = new ArrayList<>();
588 Iterator<Entry<String, Object>> propertiesNameValue = jsonProperties.entrySet().iterator();
589 while (propertiesNameValue.hasNext()) {
590 Entry<String, Object> propertyNameValue = propertiesNameValue.next();
591 if (propertyNameValue.getValue() instanceof Map || propertyNameValue.getValue() instanceof List) {
592 if (!artifactType.equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
593 @SuppressWarnings("unchecked")
594 Either<HeatParameterDefinition, ResultStatusEnum> propertyStatus = createModuleHeatParameter((Map<String, Object>) propertyNameValue.getValue());
595 if (propertyStatus.isRight()) {
596 return Either.right(propertyStatus.right().value());
598 HeatParameterDefinition property = propertyStatus.left().value();
599 property.setName(String.valueOf(propertyNameValue.getKey()));
600 moduleProperties.add(property);
602 addHeatParamDefinition(moduleProperties, propertyNameValue, true);
605 addHeatParamDefinition(moduleProperties, propertyNameValue, false);
610 if (!isEmpty(moduleProperties)) {
611 eitherResult = Either.left(moduleProperties);
619 private static void addHeatParamDefinition(List<HeatParameterDefinition> moduleProperties, Entry<String, Object> propertyNameValue, boolean isJson) {
620 HeatParameterDefinition property = new HeatParameterDefinition();
621 Object value = propertyNameValue.getValue();
623 property.setDefaultValue(isJson ? new Gson().toJson(value) : StringEscapeUtils.escapeJava(String.valueOf(value)));
625 property.setName(String.valueOf(propertyNameValue.getKey()));
626 moduleProperties.add(property);
629 private static Either<HeatParameterDefinition, ResultStatusEnum> createModuleHeatParameter(Map<String, Object> propertyValue) {
630 HeatParameterDefinition propertyDef = new HeatParameterDefinition();
632 Either<String, ResultStatusEnum> propertyFieldType = findFirstToscaStringElement(propertyValue, TypeUtils.ToscaTagNamesEnum.TYPE);
633 if (propertyFieldType.isLeft()) {
634 type = propertyFieldType.left().value();
635 propertyDef.setType(type);
637 return Either.right(ResultStatusEnum.INVALID_PROPERTY_TYPE);
639 Either<String, ResultStatusEnum> propertyFieldDescription = findFirstToscaStringElement(propertyValue, TypeUtils.ToscaTagNamesEnum.DESCRIPTION);
640 if (propertyFieldDescription.isLeft()) {
641 propertyDef.setDescription(propertyFieldDescription.left().value());
644 Either<Object, ResultStatusEnum> propertyFieldDefaultVal = findToscaElement(propertyValue, TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL);
645 if (propertyFieldDefaultVal.isLeft()) {
646 if (propertyFieldDefaultVal.left().value() == null) {
647 return Either.right(ResultStatusEnum.INVALID_PROPERTY_VALUE);
649 Object value = propertyFieldDefaultVal.left().value();
650 String defaultValue = type.equals(HeatParameterType.JSON.getType()) ? new Gson().toJson(value) : StringEscapeUtils.escapeJava(String.valueOf(value));
651 propertyDef.setDefaultValue(defaultValue);
652 propertyDef.setCurrentValue(defaultValue);
655 return Either.left(propertyDef);
657 public static boolean containsGetInput(Object propValue) {
658 String value = getPropertyJsonStringValue(propValue, ToscaPropertyType.MAP.getType());
659 return value != null && value.contains(TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
662 public static String getPropertyJsonStringValue(Object value, String type) {
663 Gson gson = new Gson();
667 ToscaPropertyType validType = ToscaPropertyType.isValidType(type);
668 if (validType == null || validType.equals(ToscaPropertyType.JSON) ||validType.equals(ToscaPropertyType.MAP) || validType.equals(ToscaPropertyType.LIST)) {
669 return gson.toJson(value);
671 return value.toString();
675 * removes from Json map (toscaJson) first element found by name (elementName) note that this method could update the received argument toscaJson
680 public static void removeElementFromJsonMap(Map<String, Object> toscaJson, String elementName) {
681 for (Entry<String, Object> entry : toscaJson.entrySet()) {
682 String key = entry.getKey();
683 Object value = entry.getValue();
684 if (key.equals(elementName)) {
685 toscaJson.remove(elementName);
687 } else if (value instanceof Map) {
688 removeElementFromJsonMap((Map<String, Object>) value, elementName);