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 {
65 private ImportUtils() {
69 private static CustomResolver customResolver = new CustomResolver();
70 private static Yaml strictYamlLoader = new YamlLoader().getStrictYamlLoader();
73 protected static ComponentsUtils componentsUtils;
76 private ExceptionUtils exceptionUtils;
78 private static final Logger log = Logger.getLogger(ImportUtils.class);
80 private static class CustomResolver extends Resolver {
82 protected void addImplicitResolvers() {
83 // avoid implicit resolvers for strings that can be interpreted as boolean values
84 addImplicitResolver(Tag.STR, EMPTY, "");
85 addImplicitResolver(Tag.STR, NULL, null);
86 addImplicitResolver(Tag.NULL, NULL, "~nN\0");
87 addImplicitResolver(Tag.NULL, EMPTY, null);
88 addImplicitResolver(Tag.INT, INT, "-+0123456789");
89 addImplicitResolver(Tag.FLOAT, FLOAT, "-+0123456789.");
90 addImplicitResolver(Tag.YAML, YAML, "!&*");
95 private static void buildMap(Map<String, Object> output, Map<String, Object> map) {
96 for (Entry<String, Object> entry : map.entrySet()) {
97 String key = entry.getKey();
98 Object value = entry.getValue();
99 if (value instanceof Map) {
100 Map<String, Object> result = new LinkedHashMap<>();
101 buildMap(result, (Map) value);
102 output.put(key, result);
104 else if (value instanceof Collection) {
105 Map<String, Object> result = new LinkedHashMap<>();
107 for(Object item : (Collection<Object>) value) {
108 buildMap(result, Collections.singletonMap("[" + (i++) + "]", item));
110 output.put(key, new ArrayList<>(result.values()));
113 output.put(key, value);
118 public static Map<String, Object> loadYamlAsStrictMap(String content){
119 Map<String, Object> result = new LinkedHashMap<>();
120 Object map = strictYamlLoader.load(content);
121 buildMap(result, (Map<String, Object>)map);
125 private static class YamlLoader extends YamlProcessor {
126 public Yaml getStrictYamlLoader() {
131 @SuppressWarnings("unchecked")
132 public static Either<List<HeatParameterDefinition>, ResultStatusEnum> getHeatParamsWithoutImplicitTypes(String heatDecodedPayload, String artifactType) {
133 Map<String, Object> heatData = (Map<String, Object>) new Yaml(new Constructor(), new Representer(), new DumperOptions(), customResolver).load(heatDecodedPayload);
134 return getHeatParameters(heatData, artifactType);
137 public static class Constants {
138 public static final String FIRST_NON_CERTIFIED_VERSION = "0.1";
139 public static final String VENDOR_NAME = "ATT (Tosca)";
140 public static final String VENDOR_RELEASE = "1.0.0.wd03";
141 public static final LifecycleStateEnum NORMATIVE_TYPE_LIFE_CYCLE = LifecycleStateEnum.CERTIFIED;
142 public static final LifecycleStateEnum NORMATIVE_TYPE_LIFE_CYCLE_NOT_CERTIFIED_CHECKOUT = LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT;
143 public static final boolean NORMATIVE_TYPE_HIGHEST_VERSION = true;
144 public static final String ABSTRACT_CATEGORY_NAME = "Generic";
145 public static final String ABSTRACT_SUBCATEGORY = "Abstract";
146 public static final String DEFAULT_ICON = "defaulticon";
147 public static final String INNER_VFC_DESCRIPTION = "Not reusable inner VFC";
148 public static final String USER_DEFINED_RESOURCE_NAMESPACE_PREFIX = "org.openecomp.resource.";
149 public static final String UI_JSON_PAYLOAD_NAME = "payloadName";
150 public static final String CVFC_DESCRIPTION = "Complex node type that is used as nested type in VF";
152 private Constants() {}
155 public enum ResultStatusEnum {
156 ELEMENT_NOT_FOUND, GENERAL_ERROR, OK, INVALID_PROPERTY_DEFAULT_VALUE, INVALID_PROPERTY_TYPE, INVALID_PROPERTY_VALUE, MISSING_ENTRY_SCHEMA_TYPE, INVALID_PROPERTY_NAME
159 public enum ToscaElementTypeEnum {
160 BOOLEAN, STRING, MAP, LIST, ALL
163 @SuppressWarnings("unchecked")
164 private static void handleElementNameNotFound(String elementName, Object elementValue, ToscaElementTypeEnum elementType, List<Object> returnedList) {
165 if (elementValue instanceof Map) {
166 ImportUtils.findToscaElements((Map<String, Object>) elementValue, elementName, elementType, returnedList);
167 } else if (elementValue instanceof List) {
168 ImportUtils.findAllToscaElementsInList((List<Object>) elementValue, elementName, elementType, returnedList);
172 @SuppressWarnings("unchecked")
173 private static void addFoundElementAccordingToItsType(String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList, Object elementValue) {
175 if (elementValue instanceof Boolean) {
176 if (elementType == ToscaElementTypeEnum.BOOLEAN || elementType == ToscaElementTypeEnum.ALL) {
177 returnedList.add(elementValue);
181 else if (elementValue instanceof String) {
182 if (elementType == ToscaElementTypeEnum.STRING || elementType == ToscaElementTypeEnum.ALL) {
183 returnedList.add(elementValue);
185 } else if (elementValue instanceof Map) {
186 if (elementType == ToscaElementTypeEnum.MAP || elementType == ToscaElementTypeEnum.ALL) {
187 returnedList.add(elementValue);
189 ImportUtils.findToscaElements((Map<String, Object>) elementValue, elementName, elementType, returnedList);
191 } else if (elementValue instanceof List) {
192 if (elementType == ToscaElementTypeEnum.LIST || elementType == ToscaElementTypeEnum.ALL) {
193 returnedList.add(elementValue);
195 ImportUtils.findAllToscaElementsInList((List<Object>) elementValue, elementName, elementType, returnedList);
198 // For Integer, Double etc...
199 else if (elementType == ToscaElementTypeEnum.ALL && elementValue != null) {
200 returnedList.add(String.valueOf(elementValue));
204 private static void findAllToscaElementsInList(List<Object> list, String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList) {
205 Iterator<Object> listItr = list.iterator();
206 while (listItr.hasNext()) {
207 Object elementValue = listItr.next();
208 handleElementNameNotFound(elementName, elementValue, elementType, returnedList);
213 public static Either<Object, ResultStatusEnum> findToscaElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum elementName, ToscaElementTypeEnum elementType) {
214 List<Object> foundElements = new ArrayList<>();
215 ImportUtils.findToscaElements(toscaJson, elementName.getElementName(), elementType, foundElements);
216 if (!isEmpty(foundElements)) {
217 return Either.left(foundElements.get(0));
219 return Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
223 * Recursively searches for all tosca elements with key equals to elementName and value equals to elementType. <br>
224 * Returns Either element with:<br>
225 * List with all value if values found<br>
226 * Or ELEMENT_NOT_FOUND ActionStatus
231 public static Either<List<Object>, ResultStatusEnum> findToscaElements(Map<String, Object> toscaJson, String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList) {
232 Either<List<Object>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
233 String skipKey = null;
234 if (toscaJson.containsKey(elementName)) {
235 skipKey = handleFoundElement(toscaJson, elementName, elementType, returnedList);
238 Iterator<Entry<String, Object>> keyValItr = toscaJson.entrySet().iterator();
239 while (keyValItr.hasNext()) {
240 Entry<String, Object> keyValEntry = keyValItr.next();
241 if (!String.valueOf(keyValEntry.getKey()).equals(skipKey)) {
242 handleElementNameNotFound(elementName, keyValEntry.getValue(), elementType, returnedList);
246 if (!isEmpty(returnedList)) {
247 returnedElement = Either.left(returnedList);
250 return returnedElement;
253 private static String handleFoundElement(Map<String, Object> toscaJson, String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList) {
254 Object elementValue = toscaJson.get(elementName);
255 addFoundElementAccordingToItsType(elementName, elementType, returnedList, elementValue);
260 @SuppressWarnings("unchecked")
261 public static <T> Either<List<T>, ResultStatusEnum> findFirstToscaListElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum toscaTagName) {
262 Either<List<T>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
263 Either<Object, ResultStatusEnum> findFirstToscaElement = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.LIST);
264 if (findFirstToscaElement.isLeft()) {
265 returnedElement = Either.left((List<T>) findFirstToscaElement.left().value());
267 return returnedElement;
271 @SuppressWarnings("unchecked")
272 public static <T> Either<Map<String, T>, ResultStatusEnum> findFirstToscaMapElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum toscaTagName) {
273 Either<Map<String, T>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
274 Either<Object, ResultStatusEnum> findFirstToscaElement = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.MAP);
275 if (findFirstToscaElement.isLeft()) {
276 returnedElement = Either.left((Map<String, T>) findFirstToscaElement.left().value());
278 return returnedElement;
282 public static Either<String, ResultStatusEnum> findFirstToscaStringElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum toscaTagName) {
283 Either<String, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
284 Either<Object, ResultStatusEnum> findFirstToscaElements = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.STRING);
285 if (findFirstToscaElements.isLeft()) {
286 returnedElement = Either.left((String) findFirstToscaElements.left().value());
288 return returnedElement;
292 * searches for first Tosca in Json map (toscaJson) boolean element by name (toscaTagName) returns found element or ELEMENT_NOT_FOUND status
295 * @param toscaTagName
298 public static Either<String, ResultStatusEnum> findFirstToscaBooleanElement(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum toscaTagName) {
299 Either<String, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
300 Either<Object, ResultStatusEnum> findFirstToscaElements = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.BOOLEAN);
301 if (findFirstToscaElements.isLeft()) {
302 returnedElement = Either.left(String.valueOf(findFirstToscaElements.left().value()));
304 return returnedElement;
307 private static void setPropertyConstraints(Map<String, Object> propertyValue, PropertyDefinition property) {
308 Either<List<Object>, ResultStatusEnum> propertyFieldconstraints = findFirstToscaListElement(propertyValue, TypeUtils.ToscaTagNamesEnum.CONSTRAINTS);
309 if (propertyFieldconstraints.isLeft()) {
310 List<Object> jsonConstraintList = propertyFieldconstraints.left().value();
312 List<PropertyConstraint> constraintList = new ArrayList<>();
313 Type constraintType = new TypeToken<PropertyConstraint>() {
315 Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create();
317 for (Object constraintJson : jsonConstraintList) {
318 PropertyConstraint propertyConstraint = gson.fromJson(gson.toJson(constraintJson), constraintType);
319 constraintList.add(propertyConstraint);
321 property.setConstraints(constraintList);
325 public static PropertyDefinition createModuleProperty(Map<String, Object> propertyValue) {
327 PropertyDefinition propertyDef = new PropertyDefinition();
328 setField(propertyValue, TypeUtils.ToscaTagNamesEnum.TYPE, propertyDef::setType);
329 setPropertyFieldRequired(propertyValue, propertyDef);
330 setField(propertyValue, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, propertyDef::setDescription);
332 setJsonStringField(propertyValue, TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE, propertyDef.getType(), propertyDef::setDefaultValue);
333 setJsonStringField(propertyValue, TypeUtils.ToscaTagNamesEnum.VALUE, propertyDef.getType(), propertyDef::setValue);
335 setField(propertyValue, TypeUtils.ToscaTagNamesEnum.IS_PASSWORD, pass -> propertyDef.setPassword(Boolean.parseBoolean(pass)));
336 setField(propertyValue, TypeUtils.ToscaTagNamesEnum.STATUS, propertyDef::setStatus);
337 setScheme(propertyValue, propertyDef);
338 setPropertyConstraints(propertyValue, propertyDef);
344 private static void setJsonStringField(Map<String, Object> propertyValue, ToscaTagNamesEnum elementName, String type, Consumer<String> setter) {
345 Either<Object, ResultStatusEnum> eitherValue = ImportUtils.findToscaElement(propertyValue, elementName, ToscaElementTypeEnum.ALL);
346 if (eitherValue.isLeft()) {
347 String propertyJsonStringValue = getPropertyJsonStringValue(eitherValue.left().value(), type);
348 setter.accept(propertyJsonStringValue);
354 public static Annotation createModuleAnnotation(Map<String, Object> annotationMap, AnnotationTypeOperations annotationTypeOperations) {
355 String parsedAnnotationType = findFirstToscaStringElement(annotationMap, TypeUtils.ToscaTagNamesEnum.TYPE).left().value();
356 AnnotationTypeDefinition annotationTypeObject = annotationTypeOperations.getLatestType(parsedAnnotationType);
357 if (annotationTypeObject != null) {
358 Annotation annotation = new Annotation();
359 ImportUtils.setField(annotationMap, TypeUtils.ToscaTagNamesEnum.TYPE, annotation::setType);
360 ImportUtils.setField(annotationMap, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, annotation::setDescription);
361 Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = getProperties(annotationMap);
362 modifyPropertiesKeysToProperForm(properties, annotation);
368 private static Either<Boolean, ResponseFormat> modifyPropertiesKeysToProperForm(Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties, Annotation annotation) {
369 Either<Boolean, ResponseFormat> result = Either.left(true);
370 if (properties.isLeft()) {
371 List<PropertyDataDefinition> propertiesList = new ArrayList<>();
372 Map<String, PropertyDefinition> value = properties.left().value();
374 for (Entry<String, PropertyDefinition> entry : value.entrySet()) {
375 String name = entry.getKey();
376 if (!PROPERTY_NAME_PATTERN_IGNORE_LENGTH.matcher(name).matches()) {
377 log.debug("The property with invalid name {} occured upon import resource {}. ", name, annotation.getName());
378 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromResultStatusEnum(ResultStatusEnum.INVALID_PROPERTY_NAME, JsonPresentationFields.PROPERTY)));
380 PropertyDefinition propertyDefinition = entry.getValue();
381 propertyDefinition.setValue(propertyDefinition.getName());
382 propertyDefinition.setName(name);
383 propertiesList.add(propertyDefinition);
386 annotation.setProperties(propertiesList);
388 else if (properties.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND) {
389 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromResultStatusEnum(properties
391 .value(), JsonPresentationFields.PROPERTY)));
396 public static InputDefinition createModuleInput(Map<String, Object> inputValue, AnnotationTypeOperations annotationTypeOperations) {
398 InputDefinition inputDef = new InputDefinition();
399 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.TYPE, inputDef::setType);
400 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.REQUIRED, req -> inputDef.setRequired(Boolean.parseBoolean(req)));
401 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, inputDef::setDescription);
403 setJsonStringField(inputValue, TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE, inputDef.getType(), inputDef::setDefaultValue);
405 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.IS_PASSWORD, pass -> inputDef.setPassword(Boolean.parseBoolean(pass)));
406 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.STATUS, inputDef::setStatus);
407 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.LABEL, inputDef::setLabel);
408 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.HIDDEN, hidden -> inputDef.setHidden(Boolean.parseBoolean(hidden)));
409 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.HIDDEN, immutable -> inputDef.setImmutable(Boolean.parseBoolean(immutable)));
410 ImportUtils.setField(inputValue, TypeUtils.ToscaTagNamesEnum.LABEL, inputDef::setLabel);
412 ImportUtils.setScheme(inputValue, inputDef);
413 ImportUtils.setPropertyConstraints(inputValue, inputDef);
415 return parseAnnotationsAndAddItToInput(inputDef, inputValue, annotationTypeOperations);
420 public static InputDefinition parseAnnotationsAndAddItToInput(InputDefinition inputDef, Map<String, Object> inputValue, AnnotationTypeOperations annotationTypeOperations){
421 Function<String, Annotation> elementGenByName = ImportUtils::createAnnotation;
422 Function<Map<String, Object>, Annotation> func = annotation -> createModuleAnnotation(annotation, annotationTypeOperations);
423 return getElements(inputValue, TypeUtils.ToscaTagNamesEnum.ANNOTATIONS, elementGenByName, func).
424 left().map( annotations -> modifyInputWithAnnotations(inputDef, annotations)).
425 left().on(err -> { log.error("Parsing annotations or adding them to the PropertyDataDefinition object failed");
429 private static InputDefinition modifyInputWithAnnotations(InputDefinition inputDef, Map<String, Annotation> annotationsMap) {
430 setAnnotationsName(annotationsMap);
431 inputDef.setAnnotationsToInput(annotationsMap.values());
436 public static PropertyDefinition createModuleAttribute(Map<String, Object> attributeMap) {
438 PropertyDefinition attributeDef = new PropertyDefinition();
439 setField(attributeMap, TypeUtils.ToscaTagNamesEnum.TYPE, attributeDef::setType);
440 setField(attributeMap, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, attributeDef::setDescription);
441 setField(attributeMap, TypeUtils.ToscaTagNamesEnum.STATUS, attributeDef::setStatus);
443 setJsonStringField(attributeMap, TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE, attributeDef.getType(), attributeDef::setDefaultValue);
444 setJsonStringField(attributeMap, TypeUtils.ToscaTagNamesEnum.VALUE, attributeDef.getType(), attributeDef::setValue);
446 setScheme(attributeMap, attributeDef);
450 private static void setScheme(Map<String, Object> propertyValue, PropertyDefinition propertyDefinition) {
451 Either<SchemaDefinition, ResultStatusEnum> eitherSchema = getSchema(propertyValue);
452 if (eitherSchema.isLeft()) {
453 SchemaDefinition schemaDef = new SchemaDefinition();
454 schemaDef.setProperty(eitherSchema.left().value().getProperty());
455 propertyDefinition.setSchema(schemaDef);
460 private static Either<SchemaDefinition, ResultStatusEnum> getSchema(Map<String, Object> propertyValue) {
461 Either<SchemaDefinition, ResultStatusEnum> result = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
462 Either<Object, ResultStatusEnum> propertyFieldEntryScheme = findToscaElement(propertyValue, TypeUtils.ToscaTagNamesEnum.ENTRY_SCHEMA, ToscaElementTypeEnum.ALL);
463 if (propertyFieldEntryScheme.isLeft()) {
464 if (propertyFieldEntryScheme.left().value() instanceof String) {
465 String schemaType = (String) propertyFieldEntryScheme.left().value();
466 SchemaDefinition schema = new SchemaDefinition();
467 PropertyDefinition schemeProperty = new PropertyDefinition();
468 schemeProperty.setType(schemaType);
469 schema.setProperty(schemeProperty);
470 result = Either.left(schema);
472 } else if (propertyFieldEntryScheme.left().value() instanceof Map) {
473 PropertyDefinition schemeProperty = createModuleProperty((Map<String, Object>) propertyFieldEntryScheme.left().value());
474 SchemaDefinition schema = new SchemaDefinition();
475 schema.setProperty(schemeProperty);
476 result = Either.left(schema);
482 public static void setField(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum tagName, Consumer<String> setter) {
483 Either<String, ResultStatusEnum> fieldStringValue = findFirstToscaStringElement(toscaJson, tagName);
484 if (fieldStringValue.isLeft()) {
485 setter.accept(fieldStringValue.left().value());
490 private static void setPropertyFieldRequired(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
491 Either<String, ResultStatusEnum> propertyFieldRequired = findFirstToscaBooleanElement(propertyValue, TypeUtils.ToscaTagNamesEnum.REQUIRED);
492 if (propertyFieldRequired.isLeft()) {
493 dataDefinition.setRequired(Boolean.parseBoolean(propertyFieldRequired.left().value()));
497 public static Either<Map<String, PropertyDefinition>, ResultStatusEnum> getProperties(Map<String, Object> toscaJson) {
498 Function<String, PropertyDefinition> elementGenByName = ImportUtils::createProperties;
499 Function<Map<String, Object>, PropertyDefinition> func = ImportUtils::createModuleProperty;
501 return getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.PROPERTIES, elementGenByName, func);
505 public static Either<Map<String, InputDefinition>, ResultStatusEnum> getInputs(Map<String, Object> toscaJson, AnnotationTypeOperations annotationTypeOperations) {
506 Function<String, InputDefinition> elementGenByName = ImportUtils::createInputs;
507 Function<Map<String, Object>, InputDefinition> func = object -> createModuleInput(object, annotationTypeOperations);
509 return getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.INPUTS, elementGenByName, func);
513 public static Either<Map<String, PropertyDefinition>, ResultStatusEnum> getAttributes(Map<String, Object> toscaJson) {
514 Function<String, PropertyDefinition> elementGenByName = ImportUtils::createAttribute;
515 Function<Map<String, Object>, PropertyDefinition> func = ImportUtils::createModuleAttribute;
517 return getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.ATTRIBUTES, elementGenByName, func);
520 public static <T> Either<Map<String, T>, ResultStatusEnum> getElements(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum elementTagName, Function<String, T> elementGenByName,
521 Function<Map<String, Object>, T> func) {
522 Either<Map<String, T>, ResultStatusEnum> eitherResult = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
523 Either<Map<String, Object>, ResultStatusEnum> toscaAttributes = findFirstToscaMapElement(toscaJson, elementTagName);
524 if (toscaAttributes.isLeft()) {
525 Map<String, Object> jsonAttributes = toscaAttributes.left().value();
526 Map<String, T> moduleAttributes = new HashMap<>();
527 Iterator<Entry<String, Object>> propertiesNameValue = jsonAttributes.entrySet().iterator();
528 while (propertiesNameValue.hasNext()) {
529 Entry<String, Object> attributeNameValue = propertiesNameValue.next();
530 if (attributeNameValue.getValue() instanceof Map) {
531 @SuppressWarnings("unchecked")
532 T attribute = func.apply((Map<String, Object>) attributeNameValue.getValue());
533 if (attribute != null){
534 moduleAttributes.put(String.valueOf(attributeNameValue.getKey()), attribute);
538 T element = elementGenByName.apply(String.valueOf(attributeNameValue.getValue()));
539 moduleAttributes.put(String.valueOf(attributeNameValue.getKey()), element);
542 if (moduleAttributes.size() > 0) {
543 eitherResult = Either.left(moduleAttributes);
551 private static PropertyDefinition createAttribute(String name) {
552 PropertyDefinition attribute = new PropertyDefinition();
554 attribute.setName(name);
558 private static PropertyDefinition createProperties(String name) {
559 PropertyDefinition property = new PropertyDefinition();
560 property.setDefaultValue(name);
561 property.setName(name);
567 private static InputDefinition createInputs(String name) {
568 InputDefinition input = new InputDefinition();
574 private static Annotation createAnnotation(String name) {
575 Annotation annotation = new Annotation();
576 annotation.setName(name);
582 public static Either<List<HeatParameterDefinition>, ResultStatusEnum> getHeatParameters(Map<String, Object> heatData, String artifactType) {
584 Either<List<HeatParameterDefinition>, ResultStatusEnum> eitherResult = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
585 Either<Map<String, Object>, ResultStatusEnum> toscaProperties = findFirstToscaMapElement(heatData, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
586 if (toscaProperties.isLeft()) {
587 Map<String, Object> jsonProperties = toscaProperties.left().value();
588 List<HeatParameterDefinition> moduleProperties = new ArrayList<>();
589 Iterator<Entry<String, Object>> propertiesNameValue = jsonProperties.entrySet().iterator();
590 while (propertiesNameValue.hasNext()) {
591 Entry<String, Object> propertyNameValue = propertiesNameValue.next();
592 if (propertyNameValue.getValue() instanceof Map || propertyNameValue.getValue() instanceof List) {
593 if (!artifactType.equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
594 @SuppressWarnings("unchecked")
595 Either<HeatParameterDefinition, ResultStatusEnum> propertyStatus = createModuleHeatParameter((Map<String, Object>) propertyNameValue.getValue());
596 if (propertyStatus.isRight()) {
597 return Either.right(propertyStatus.right().value());
599 HeatParameterDefinition property = propertyStatus.left().value();
600 property.setName(String.valueOf(propertyNameValue.getKey()));
601 moduleProperties.add(property);
603 addHeatParamDefinition(moduleProperties, propertyNameValue, true);
606 addHeatParamDefinition(moduleProperties, propertyNameValue, false);
611 if (!isEmpty(moduleProperties)) {
612 eitherResult = Either.left(moduleProperties);
620 private static void addHeatParamDefinition(List<HeatParameterDefinition> moduleProperties, Entry<String, Object> propertyNameValue, boolean isJson) {
621 HeatParameterDefinition property = new HeatParameterDefinition();
622 Object value = propertyNameValue.getValue();
624 property.setDefaultValue(isJson ? new Gson().toJson(value) : StringEscapeUtils.escapeJava(String.valueOf(value)));
626 property.setName(String.valueOf(propertyNameValue.getKey()));
627 moduleProperties.add(property);
630 private static Either<HeatParameterDefinition, ResultStatusEnum> createModuleHeatParameter(Map<String, Object> propertyValue) {
631 HeatParameterDefinition propertyDef = new HeatParameterDefinition();
633 Either<String, ResultStatusEnum> propertyFieldType = findFirstToscaStringElement(propertyValue, TypeUtils.ToscaTagNamesEnum.TYPE);
634 if (propertyFieldType.isLeft()) {
635 type = propertyFieldType.left().value();
636 propertyDef.setType(type);
638 return Either.right(ResultStatusEnum.INVALID_PROPERTY_TYPE);
640 Either<String, ResultStatusEnum> propertyFieldDescription = findFirstToscaStringElement(propertyValue, TypeUtils.ToscaTagNamesEnum.DESCRIPTION);
641 if (propertyFieldDescription.isLeft()) {
642 propertyDef.setDescription(propertyFieldDescription.left().value());
645 Either<Object, ResultStatusEnum> propertyFieldDefaultVal = findToscaElement(propertyValue, TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL);
646 if (propertyFieldDefaultVal.isLeft()) {
647 if (propertyFieldDefaultVal.left().value() == null) {
648 return Either.right(ResultStatusEnum.INVALID_PROPERTY_VALUE);
650 Object value = propertyFieldDefaultVal.left().value();
651 String defaultValue = type.equals(HeatParameterType.JSON.getType()) ? new Gson().toJson(value) : StringEscapeUtils.escapeJava(String.valueOf(value));
652 propertyDef.setDefaultValue(defaultValue);
653 propertyDef.setCurrentValue(defaultValue);
656 return Either.left(propertyDef);
658 public static boolean containsGetInput(Object propValue) {
659 String value = getPropertyJsonStringValue(propValue, ToscaPropertyType.MAP.getType());
660 return value != null && value.contains(TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName());
663 public static String getPropertyJsonStringValue(Object value, String type) {
664 Gson gson = new Gson();
668 ToscaPropertyType validType = ToscaPropertyType.isValidType(type);
669 if (validType == null || validType.equals(ToscaPropertyType.JSON) ||validType.equals(ToscaPropertyType.MAP) || validType.equals(ToscaPropertyType.LIST)) {
670 return gson.toJson(value);
672 return value.toString();
676 * removes from Json map (toscaJson) first element found by name (elementName) note that this method could update the received argument toscaJson
681 public static void removeElementFromJsonMap(Map<String, Object> toscaJson, String elementName) {
682 for (Entry<String, Object> entry : toscaJson.entrySet()) {
683 String key = entry.getKey();
684 Object value = entry.getValue();
685 if (key.equals(elementName)) {
686 toscaJson.remove(elementName);
688 } else if (value instanceof Map) {
689 removeElementFromJsonMap((Map<String, Object>) value, elementName);