[sdc] update code of sdc
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ImportUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
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
21 package org.openecomp.sdc.be.components.impl;
22
23 import java.lang.reflect.Type;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.function.Consumer;
32 import java.util.function.Function;
33
34 import org.apache.commons.lang3.StringEscapeUtils;
35 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
36 import org.openecomp.sdc.be.model.HeatParameterDefinition;
37 import org.openecomp.sdc.be.model.InputDefinition;
38 import org.openecomp.sdc.be.model.LifecycleStateEnum;
39 import org.openecomp.sdc.be.model.PropertyConstraint;
40 import org.openecomp.sdc.be.model.PropertyDefinition;
41 import org.openecomp.sdc.be.model.heat.HeatParameterType;
42 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser;
43 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
44 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
45 import org.openecomp.sdc.common.util.GsonFactory;
46 import org.springframework.beans.factory.config.YamlProcessor;
47 import org.yaml.snakeyaml.DumperOptions;
48 import org.yaml.snakeyaml.Yaml;
49 import org.yaml.snakeyaml.constructor.Constructor;
50 import org.yaml.snakeyaml.nodes.Tag;
51 import org.yaml.snakeyaml.representer.Representer;
52 import org.yaml.snakeyaml.resolver.Resolver;
53
54 import com.google.gson.Gson;
55 import com.google.gson.GsonBuilder;
56 import com.google.gson.reflect.TypeToken;
57
58 import fj.data.Either;
59
60 public final class ImportUtils {
61         private ImportUtils() {
62
63         }
64         public static Yaml STRICT_MAPPING_YAML_LOADER = new YamlLoader().getStrictYamlLoader();
65         
66         private static CustomResolver customResolver = new CustomResolver();
67
68         private static class CustomResolver extends Resolver {
69              @Override
70                 protected void addImplicitResolvers() {
71                 // avoid implicit resolvers for strings that can be interpreted as boolean values
72                  addImplicitResolver(Tag.STR, EMPTY, "");
73                  addImplicitResolver(Tag.STR, NULL, null);
74                  addImplicitResolver(Tag.NULL, NULL, "~nN\0");
75                  addImplicitResolver(Tag.NULL, EMPTY, null);
76                  addImplicitResolver(Tag.YAML, YAML, "!&*");    
77                 }
78         }
79         
80         private static class YamlLoader extends YamlProcessor {
81                 public Yaml getStrictYamlLoader() {
82                         return createYaml();
83                 }
84         }
85
86         @SuppressWarnings("unchecked")
87         public static Either<List<HeatParameterDefinition>, ResultStatusEnum> getHeatParamsWithoutImplicitTypes(String heatDecodedPayload, String artifactType) {
88                 Map<String, Object> heatData = (Map<String, Object>) new Yaml(new Constructor(), new Representer(), new DumperOptions(), customResolver).load(heatDecodedPayload);      
89                 return getHeatParameters(heatData, artifactType);
90         }
91
92         public static class Constants {
93
94                 public static final String FIRST_CERTIFIED_VERSION_VERSION = "1.0";
95                 public static final String FIRST_NON_CERTIFIED_VERSION = "0.1";
96                 public static final String VENDOR_NAME = "ATT (Tosca)";
97                 public static final String VENDOR_RELEASE = "1.0.0.wd03";
98                 public static final LifecycleStateEnum NORMATIVE_TYPE_LIFE_CYCLE = LifecycleStateEnum.CERTIFIED;
99                 public static final LifecycleStateEnum NORMATIVE_TYPE_LIFE_CYCLE_NOT_CERTIFIED_CHECKOUT = LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT;
100                 public static final boolean NORMATIVE_TYPE_HIGHEST_VERSION = true;
101                 // public static final String ABSTRACT_CATEGORY = "Generic/Abstract";
102                 public static final String ABSTRACT_CATEGORY_NAME = "Generic";
103                 public static final String ABSTRACT_SUBCATEGORY = "Abstract";
104                 public static final String DEFAULT_ICON = "defaulticon";
105                 public static final String INNER_VFC_DESCRIPTION = "Not reusable inner VFC";
106                 public static final String USER_DEFINED_RESOURCE_NAMESPACE_PREFIX = "org.openecomp.resource.";
107                 public static final List<String> TOSCA_DEFINITION_VERSIONS = Arrays.asList(new String[] { "tosca_simple_yaml_1_0_0", "tosca_simple_profile_for_nfv_1_0_0", "tosca_simple_yaml_1_0" });
108                 public static final List<String> TOSCA_YML_CSAR_VALID_SUFFIX = Arrays.asList(new String[] { ".yml", ".yaml", ".csar" });
109                 public static final String UI_JSON_PAYLOAD_NAME = "payloadName";
110         }
111
112         public enum ResultStatusEnum {
113                 ELEMENT_NOT_FOUND, GENERAL_ERROR, OK, INVALID_PROPERTY_DEFAULT_VALUE, INVALID_PROPERTY_TYPE, INVALID_PROPERTY_VALUE, MISSING_ENTRY_SCHEMA_TYPE, INVALID_PROPERTY_NAME
114         }
115
116         public enum ToscaElementTypeEnum {
117                 BOOLEAN, STRING, MAP, LIST, ALL
118         }
119
120         public enum ToscaTagNamesEnum {
121                 DERIVED_FROM("derived_from"), IS_PASSWORD("is_password"),
122                 // Properties
123                 PROPERTIES("properties"), TYPE("type"), STATUS("status"), ENTRY_SCHEMA("entry_schema"), REQUIRED("required"), DESCRIPTION("description"), DEFAULT_VALUE("default"), VALUE("value"), CONSTRAINTS("constraints"),
124                 // Group Types
125                 MEMBERS("members"), METADATA("metadata"),
126                 // Policy Types
127                 TARGETS("targets"),
128                 // Capabilities
129                 CAPABILITIES("capabilities"), VALID_SOURCE_TYPES("valid_source_types"),
130                 // Requirements
131                 REQUIREMENTS("requirements"), NODE("node"), RELATIONSHIP("relationship"), CAPABILITY("capability"), INTERFACES("interfaces"),
132                 // Heat env Validation
133                 PARAMETERS("parameters"),
134                 // Import Validations
135                 TOSCA_VERSION("tosca_definitions_version"), TOPOLOGY_TEMPLATE("topology_template"), NODE_TYPES("node_types"), OCCURRENCES("occurrences"), NODE_TEMPLATES("node_templates"), GROUPS("groups"), INPUTS("inputs"),
136                 // Attributes
137                 ATTRIBUTES("attributes"), LABEL("label"), HIDDEN("hidden"), IMMUTABLE("immutable"), GET_INPUT("get_input");
138
139                 private String elementName;
140
141                 private ToscaTagNamesEnum(String elementName) {
142                         this.elementName = elementName;
143                 }
144
145                 public String getElementName() {
146                         return elementName;
147                 }
148         }
149
150         @SuppressWarnings("unchecked")
151         private static void handleElementNameNotFound(String elementName, Object elementValue, ToscaElementTypeEnum elementType, List<Object> returnedList) {
152                 if (elementValue instanceof Map) {
153                         ImportUtils.findToscaElements((Map<String, Object>) elementValue, elementName, elementType, returnedList);
154                 } else if (elementValue instanceof List) {
155                         ImportUtils.findAllToscaElementsInList((List<Object>) elementValue, elementName, elementType, returnedList);
156                 }
157         }
158
159         @SuppressWarnings("unchecked")
160         private static void handleElementNameFound(String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList, Object elementValue) {
161
162                 if (elementValue instanceof Boolean) {
163                         if (elementType == ToscaElementTypeEnum.BOOLEAN || elementType == ToscaElementTypeEnum.ALL) {
164                                 returnedList.add(elementValue);
165                         }
166                 }
167
168                 else if (elementValue instanceof String) {
169                         if (elementType == ToscaElementTypeEnum.STRING || elementType == ToscaElementTypeEnum.ALL) {
170                                 returnedList.add(elementValue);
171                         }
172                 } else if (elementValue instanceof Map) {
173                         if (elementType == ToscaElementTypeEnum.MAP || elementType == ToscaElementTypeEnum.ALL) {
174                                 returnedList.add(elementValue);
175                         }
176                         ImportUtils.findToscaElements((Map<String, Object>) elementValue, elementName, elementType, returnedList);
177
178                 } else if (elementValue instanceof List) {
179                         if (elementType == ToscaElementTypeEnum.LIST || elementType == ToscaElementTypeEnum.ALL) {
180                                 returnedList.add(elementValue);
181                         }
182                         ImportUtils.findAllToscaElementsInList((List<Object>) elementValue, elementName, elementType, returnedList);
183
184                 }
185                 // For Integer, Double etc...
186                 else if (elementType == ToscaElementTypeEnum.ALL) {
187                         if (elementValue != null) {
188                                 returnedList.add(String.valueOf(elementValue));
189                         } 
190                 }
191         }
192
193         private static void findAllToscaElementsInList(List<Object> list, String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList) {
194                 Iterator<Object> listItr = list.iterator();
195                 while (listItr.hasNext()) {
196                         Object elementValue = listItr.next();
197                         handleElementNameNotFound(elementName, elementValue, elementType, returnedList);
198                 }
199
200         }
201
202         public static Either<Object, ResultStatusEnum> findToscaElement(Map<String, Object> toscaJson, ToscaTagNamesEnum elementName, ToscaElementTypeEnum elementType) {
203                 List<Object> foundElements = new ArrayList<>();
204                 Either<Object, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
205                 ImportUtils.findToscaElements(toscaJson, elementName.getElementName(), elementType, foundElements);
206                 if (foundElements.size() > 0) {
207                         returnedElement = Either.left(foundElements.get(0));
208                 }
209                 return returnedElement;
210
211         }
212
213         /**
214          * Recursively searches for all tosca elements with key equals to elementName and value equals to elementType. <br>
215          * Returns Either element with:<br>
216          * List with all value if values found<br>
217          * Or ELEMENT_NOT_FOUND ActionStatus
218          * 
219          * @param toscaJson
220          * @param toscaTagName
221          * @return
222          */
223         public static Either<List<Object>, ResultStatusEnum> findToscaElements(Map<String, Object> toscaJson, String elementName, ToscaElementTypeEnum elementType, List<Object> returnedList) {
224                 Either<List<Object>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
225                 String skipKey = null;
226                 if (toscaJson.containsKey(elementName)) {
227                         Object elementValue = toscaJson.get(elementName);
228                         handleElementNameFound(elementName, elementType, returnedList, elementValue);
229                         skipKey = elementName;
230                 }
231
232                 Iterator<Entry<String, Object>> keyValItr = toscaJson.entrySet().iterator();
233                 while (keyValItr.hasNext()) {
234                         Entry<String, Object> keyValEntry = keyValItr.next();
235                         if (!String.valueOf(keyValEntry.getKey()).equals(skipKey)) {
236                                 handleElementNameNotFound(elementName, keyValEntry.getValue(), elementType, returnedList);
237                         }
238                 }
239
240                 if (returnedList.size() > 0) {
241                         returnedElement = Either.left(returnedList);
242                 }
243
244                 return returnedElement;
245         }
246
247         @SuppressWarnings("unchecked")
248         public static <T> Either<List<T>, ResultStatusEnum> findFirstToscaListElement(Map<String, Object> toscaJson, ToscaTagNamesEnum toscaTagName) {
249                 Either<List<T>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
250                 Either<Object, ResultStatusEnum> findFirstToscaElement = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.LIST);
251                 if (findFirstToscaElement.isLeft()) {
252                         returnedElement = Either.left((List<T>) findFirstToscaElement.left().value());
253                 }
254                 return returnedElement;
255
256         }
257
258         @SuppressWarnings("unchecked")
259         public static <T> Either<Map<String, T>, ResultStatusEnum> findFirstToscaMapElement(Map<String, Object> toscaJson, ToscaTagNamesEnum toscaTagName) {
260                 Either<Map<String, T>, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
261                 Either<Object, ResultStatusEnum> findFirstToscaElement = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.MAP);
262                 if (findFirstToscaElement.isLeft()) {
263                         returnedElement = Either.left((Map<String, T>) findFirstToscaElement.left().value());
264                 }
265                 return returnedElement;
266
267         }
268
269         public static Either<String, ResultStatusEnum> findFirstToscaStringElement(Map<String, Object> toscaJson, ToscaTagNamesEnum toscaTagName) {
270                 Either<String, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
271                 Either<Object, ResultStatusEnum> findFirstToscaElements = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.STRING);
272                 if (findFirstToscaElements.isLeft()) {
273                         returnedElement = Either.left((String) findFirstToscaElements.left().value());
274                 }
275                 return returnedElement;
276         }
277
278         /**
279          * searches for first Tosca in Json map (toscaJson) boolean element by name (toscaTagName) returns found element or ELEMENT_NOT_FOUND status
280          * 
281          * @param toscaJson
282          * @param toscaTagName
283          * @return
284          */
285         public static Either<String, ResultStatusEnum> findFirstToscaBooleanElement(Map<String, Object> toscaJson, ToscaTagNamesEnum toscaTagName) {
286                 Either<String, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
287                 Either<Object, ResultStatusEnum> findFirstToscaElements = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.BOOLEAN);
288                 if (findFirstToscaElements.isLeft()) {
289                         returnedElement = Either.left(String.valueOf(findFirstToscaElements.left().value()));
290                 }
291                 return returnedElement;
292         }
293
294         private static void setPropertyConstraints(Map<String, Object> propertyValue, PropertyDefinition property) {
295                 Either<List<Object>, ResultStatusEnum> propertyFieldconstraints = findFirstToscaListElement(propertyValue, ToscaTagNamesEnum.CONSTRAINTS);
296                 if (propertyFieldconstraints.isLeft()) {
297                         List<Object> jsonConstraintList = propertyFieldconstraints.left().value();
298
299                         List<PropertyConstraint> constraintList = new ArrayList<>();
300                         Type constraintType = new TypeToken<PropertyConstraint>() {
301                         }.getType();
302                         Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create();
303
304                         for (Object constraintJson : jsonConstraintList) {
305                                 PropertyConstraint propertyConstraint = gson.fromJson(gson.toJson(constraintJson), constraintType);
306                                 constraintList.add(propertyConstraint);
307                         }
308                         property.setConstraints(constraintList);
309                 }
310         }
311
312         public static PropertyDefinition createModuleProperty(Map<String, Object> propertyValue) {
313
314                 PropertyDefinition propertyDef = new PropertyDefinition();
315                 ImportUtils.setField(propertyValue, ToscaTagNamesEnum.TYPE, type -> propertyDef.setType(type));
316                 ImportUtils.setPropertyFieldRequired(propertyValue, propertyDef);
317                 ImportUtils.setField(propertyValue, ToscaTagNamesEnum.DESCRIPTION, desc -> propertyDef.setDescription(desc));
318
319                 Either<Object, ResultStatusEnum> findToscaElement = ImportUtils.findToscaElement(propertyValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL);
320                 if (findToscaElement.isLeft()) {
321                         String propertyJsonStringValue = getPropertyJsonStringValue(findToscaElement.left().value(), propertyDef.getType());
322                         propertyDef.setDefaultValue(propertyJsonStringValue);
323                 }
324                 ImportUtils.setField(propertyValue, ToscaTagNamesEnum.IS_PASSWORD, pass -> propertyDef.setPassword(Boolean.parseBoolean(pass)));
325                 ImportUtils.setField(propertyValue, ToscaTagNamesEnum.STATUS, status -> propertyDef.setStatus(status));
326                 ImportUtils.setPropertyScheme(propertyValue, propertyDef);
327                 ImportUtils.setPropertyConstraints(propertyValue, propertyDef);
328
329                 return propertyDef;
330         }
331
332         public static InputDefinition createModuleInput(Map<String, Object> inputValue) {
333
334                 InputDefinition inputDef = new InputDefinition();
335                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.TYPE, type -> inputDef.setType(type));
336                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.REQUIRED, req -> inputDef.setRequired(Boolean.parseBoolean(req)));
337                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.DESCRIPTION, desc -> inputDef.setDescription(desc));
338
339                 Either<Object, ResultStatusEnum> findToscaElement = ImportUtils.findToscaElement(inputValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL);
340                 if (findToscaElement.isLeft()) {
341                         String propertyJsonStringValue = getPropertyJsonStringValue(findToscaElement.left().value(), inputDef.getType());
342                         inputDef.setDefaultValue(propertyJsonStringValue);
343                 }
344                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.IS_PASSWORD, pass -> inputDef.setPassword(Boolean.parseBoolean(pass)));
345                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.STATUS, status -> inputDef.setStatus(status));
346                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.LABEL, label -> inputDef.setLabel(label));
347                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.HIDDEN, hidden -> inputDef.setHidden(Boolean.parseBoolean(hidden)));
348                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.HIDDEN, immutable -> inputDef.setImmutable(Boolean.parseBoolean(immutable)));
349                 ImportUtils.setField(inputValue, ToscaTagNamesEnum.LABEL, label -> inputDef.setLabel(label));
350                 ImportUtils.setPropertyScheme(inputValue, inputDef);
351                 ImportUtils.setPropertyConstraints(inputValue, inputDef);
352
353                 return inputDef;
354         }
355
356         public static PropertyDefinition createModuleAttribute(Map<String, Object> attributeMap) {
357
358                 PropertyDefinition attributeDef = new PropertyDefinition();
359                 ImportUtils.setField(attributeMap, ToscaTagNamesEnum.TYPE, type -> attributeDef.setType(type));
360                 ImportUtils.setField(attributeMap, ToscaTagNamesEnum.DESCRIPTION, desc -> attributeDef.setDescription(desc));
361                 ImportUtils.setField(attributeMap, ToscaTagNamesEnum.STATUS, status -> attributeDef.setStatus(status));
362                 Either<Object, ResultStatusEnum> eitherDefaultValue = ImportUtils.findToscaElement(attributeMap, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL);
363                 if (eitherDefaultValue.isLeft()) {
364                         String attributeDefaultValue = getPropertyJsonStringValue(eitherDefaultValue.left().value(), attributeDef.getType());
365                         attributeDef.setDefaultValue(attributeDefaultValue);
366                 }
367                 Either<Object, ResultStatusEnum> eitherValue = ImportUtils.findToscaElement(attributeMap, ToscaTagNamesEnum.VALUE, ToscaElementTypeEnum.ALL);
368                 if (eitherValue.isLeft()) {
369                         String attributeValue = getPropertyJsonStringValue(eitherValue.left().value(), attributeDef.getType());
370                         attributeDef.setValue(attributeValue);
371                 }
372                 ImportUtils.setAttributeScheme(attributeMap, attributeDef);
373                 return attributeDef;
374         }
375
376         private static void setPropertyFieldStatus(Map<String, Object> propertyValue, PropertyDefinition propertyDef) {
377                 Either<String, ResultStatusEnum> propertyFieldIsStatus = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.STATUS);
378                 if (propertyFieldIsStatus.isLeft()) {
379                         propertyDef.setStatus(propertyFieldIsStatus.left().value());
380                 }
381
382         }
383
384         private static void setAttributeFieldStatus(Map<String, Object> propertyValue, PropertyDefinition propertyDef) {
385                 Either<String, ResultStatusEnum> propertyFieldIsStatus = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.STATUS);
386                 if (propertyFieldIsStatus.isLeft()) {
387                         propertyDef.setStatus(propertyFieldIsStatus.left().value());
388                 }
389
390         }
391
392         private static void setPropertyScheme(Map<String, Object> propertyValue, PropertyDefinition propertyDefinition) {
393                 Either<SchemaDefinition, ResultStatusEnum> eitherSchema = getSchema(propertyValue);
394                 if (eitherSchema.isLeft()) {
395                         SchemaDefinition schemaDef = new SchemaDefinition();
396                         schemaDef.setProperty(eitherSchema.left().value().getProperty());
397                         propertyDefinition.setSchema(schemaDef);
398                 }
399
400         }
401
402         private static void setAttributeScheme(Map<String, Object> propertyValue, PropertyDefinition propertyDefinition) {
403                 Either<SchemaDefinition, ResultStatusEnum> eitherSchema = getSchema(propertyValue);
404                 if (eitherSchema.isLeft()) {
405                         SchemaDefinition schemaDef = new SchemaDefinition();
406                         schemaDef.setProperty(eitherSchema.left().value().getProperty());
407                         propertyDefinition.setSchema(schemaDef);
408                 }
409
410         }
411
412         private static Either<SchemaDefinition, ResultStatusEnum> getSchema(Map<String, Object> propertyValue) {
413                 Either<SchemaDefinition, ResultStatusEnum> result = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
414                 Either<Object, ResultStatusEnum> propertyFieldEntryScheme = findToscaElement(propertyValue, ToscaTagNamesEnum.ENTRY_SCHEMA, ToscaElementTypeEnum.ALL);
415                 if (propertyFieldEntryScheme.isLeft()) {
416                         if (propertyFieldEntryScheme.left().value() instanceof String) {
417                                 String schemaType = (String) propertyFieldEntryScheme.left().value();
418                                 SchemaDefinition schema = new SchemaDefinition();
419                                 PropertyDefinition schemeProperty = new PropertyDefinition();
420                                 schemeProperty.setType(schemaType);
421                                 schema.setProperty(schemeProperty);
422                                 result = Either.left(schema);
423
424                         } else if (propertyFieldEntryScheme.left().value() instanceof Map) {
425                                 PropertyDefinition schemeProperty = createModuleProperty((Map<String, Object>) propertyFieldEntryScheme.left().value());
426                                 SchemaDefinition schema = new SchemaDefinition();
427                                 schema.setProperty(schemeProperty);
428                                 result = Either.left(schema);
429
430                         }
431
432                 }
433                 return result;
434         }
435
436         private static void setPropertyFieldIsPassword(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
437                 Either<String, ResultStatusEnum> propertyFieldIsPassword = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.IS_PASSWORD);
438                 if (propertyFieldIsPassword.isLeft()) {
439                         dataDefinition.setPassword(Boolean.parseBoolean(propertyFieldIsPassword.left().value()));
440                 }
441         }
442
443         private static ResultStatusEnum setPropertyFieldDefaultValue(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
444                 Either<Object, ResultStatusEnum> propertyFieldDefaultValue = findToscaElement(propertyValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL);
445                 Gson gson = GsonFactory.getGson();
446                 if (propertyFieldDefaultValue.isLeft()) {
447                         Object defaultValue = propertyFieldDefaultValue.left().value();
448                         String type = dataDefinition.getType();
449                         ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(type);
450                         // esofer - supporting customized data types. The validation of the
451                         // type will be in the creation of the property.
452                         // if(innerToscaType == null){
453                         // return ResultStatusEnum.MISSING_ENTRY_SCHEMA_TYPE;
454                         // }
455                         // customized data types value is represented as json.
456                         // Also customized data types which are scalar ones, for example,
457                         // data type which derived from integer, their value will be
458                         // represented as json.
459                         if (innerToscaType == null || innerToscaType.equals(ToscaPropertyType.LIST) || innerToscaType.equals(ToscaPropertyType.MAP)) {
460                                 String jsonObj = null;
461                                 if (defaultValue != null) {
462                                         jsonObj = gson.toJson(defaultValue);
463                                 }
464
465                                 dataDefinition.setDefaultValue(jsonObj);
466                         } else {
467                                 dataDefinition.setDefaultValue(String.valueOf(defaultValue));
468                         }
469
470                 }
471
472                 return ResultStatusEnum.OK;
473         }
474
475         private static ResultStatusEnum setAttributeFieldDefaultValue(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
476                 Either<Object, ResultStatusEnum> propertyFieldDefaultValue = findToscaElement(propertyValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL);
477                 Gson gson = GsonFactory.getGson();
478                 if (propertyFieldDefaultValue.isLeft()) {
479                         Object defaultValue = propertyFieldDefaultValue.left().value();
480                         String type = dataDefinition.getType();
481                         ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(type);
482                         // esofer - supporting customized data types. The validation of the
483                         // type will be in the creation of the property.
484                         // if(innerToscaType == null){
485                         // return ResultStatusEnum.MISSING_ENTRY_SCHEMA_TYPE;
486                         // }
487                         // customized data types value is represented as json.
488                         // Also customized data types which are scalar ones, for example,
489                         // data type which derived from integer, their value will be
490                         // represented as json.
491                         if (innerToscaType == null || innerToscaType.equals(ToscaPropertyType.LIST) || innerToscaType.equals(ToscaPropertyType.MAP)) {
492                                 String jsonObj = null;
493                                 if (defaultValue != null) {
494                                         jsonObj = gson.toJson(defaultValue);
495                                 }
496
497                                 dataDefinition.setDefaultValue(jsonObj);
498                         } else {
499                                 dataDefinition.setDefaultValue(String.valueOf(defaultValue));
500                         }
501
502                 }
503
504                 return ResultStatusEnum.OK;
505         }
506
507         public static void setField(Map<String, Object> toscaJson, ToscaTagNamesEnum tagName, Consumer<String> setter) {
508                 Either<String, ResultStatusEnum> fieldStringValue = findFirstToscaStringElement(toscaJson, tagName);
509                 if (fieldStringValue.isLeft()) {
510                         setter.accept(fieldStringValue.left().value());
511                 }
512
513         }
514
515         private static void setPropertyFieldDescription(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
516                 Either<String, ResultStatusEnum> propertyFieldDescription = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.DESCRIPTION);
517                 if (propertyFieldDescription.isLeft()) {
518                         dataDefinition.setDescription(propertyFieldDescription.left().value());
519                 }
520         }
521
522         private static void setPropertyFieldRequired(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
523                 Either<String, ResultStatusEnum> propertyFieldRequired = findFirstToscaBooleanElement(propertyValue, ToscaTagNamesEnum.REQUIRED);
524                 if (propertyFieldRequired.isLeft()) {
525                         dataDefinition.setRequired(Boolean.parseBoolean(propertyFieldRequired.left().value()));
526                 }
527         }
528
529         private static void setAttributeFieldType(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
530                 Either<String, ResultStatusEnum> propertyFieldType = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.TYPE);
531                 if (propertyFieldType.isLeft()) {
532                         dataDefinition.setType(propertyFieldType.left().value());
533                 }
534         }
535
536         private static void setPropertyFieldType(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
537                 Either<String, ResultStatusEnum> propertyFieldType = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.TYPE);
538                 if (propertyFieldType.isLeft()) {
539                         dataDefinition.setType(propertyFieldType.left().value());
540                 }
541         }
542
543         private static void setAttributeFieldDescription(Map<String, Object> propertyValue, PropertyDefinition dataDefinition) {
544                 Either<String, ResultStatusEnum> propertyFieldDescription = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.DESCRIPTION);
545                 if (propertyFieldDescription.isLeft()) {
546                         dataDefinition.setDescription(propertyFieldDescription.left().value());
547                 }
548         }
549
550         public static Either<Map<String, PropertyDefinition>, ResultStatusEnum> getProperties(Map<String, Object> toscaJson) {
551                 Function<String, PropertyDefinition> elementGenByName = elementName -> createProperties(elementName);
552                 Function<Map<String, Object>, PropertyDefinition> func = map -> createModuleProperty(map);
553
554                 return getElements(toscaJson, ToscaTagNamesEnum.PROPERTIES, elementGenByName, func);
555
556         }
557
558         public static Either<Map<String, InputDefinition>, ResultStatusEnum> getInputs(Map<String, Object> toscaJson) {
559                 Function<String, InputDefinition> elementGenByName = elementName -> createInputs(elementName);
560                 Function<Map<String, Object>, InputDefinition> func = map -> createModuleInput(map);
561
562                 return getElements(toscaJson, ToscaTagNamesEnum.INPUTS, elementGenByName, func);
563
564         }
565
566         public static Either<Map<String, PropertyDefinition>, ResultStatusEnum> getAttributes(Map<String, Object> toscaJson) {
567                 Function<String, PropertyDefinition> elementGenByName = elementName -> createAttribute(elementName);
568                 Function<Map<String, Object>, PropertyDefinition> func = map -> createModuleAttribute(map);
569
570                 return getElements(toscaJson, ToscaTagNamesEnum.ATTRIBUTES, elementGenByName, func);
571         }
572
573         public static <ElementDefinition> Either<Map<String, ElementDefinition>, ResultStatusEnum> getElements(Map<String, Object> toscaJson, ToscaTagNamesEnum elementTagName, Function<String, ElementDefinition> elementGenByName,
574                         Function<Map<String, Object>, ElementDefinition> func) {
575                 Either<Map<String, ElementDefinition>, ResultStatusEnum> eitherResult = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
576                 Either<Map<String, Object>, ResultStatusEnum> toscaAttributes = findFirstToscaMapElement(toscaJson, elementTagName);
577                 if (toscaAttributes.isLeft()) {
578                         Map<String, Object> jsonAttributes = toscaAttributes.left().value();
579                         Map<String, ElementDefinition> moduleAttributes = new HashMap<>();
580                         Iterator<Entry<String, Object>> propertiesNameValue = jsonAttributes.entrySet().iterator();
581                         while (propertiesNameValue.hasNext()) {
582                                 Entry<String, Object> attributeNameValue = propertiesNameValue.next();
583                                 if (attributeNameValue.getValue() instanceof Map) {
584                                         @SuppressWarnings("unchecked")
585                                         ElementDefinition attribute = func.apply((Map<String, Object>) attributeNameValue.getValue());
586                                         moduleAttributes.put(String.valueOf(attributeNameValue.getKey()), attribute);
587                                 } else {
588
589                                         ElementDefinition element = elementGenByName.apply(String.valueOf(attributeNameValue.getValue()));
590
591                                         moduleAttributes.put(String.valueOf(attributeNameValue.getKey()), element);
592                                 }
593
594                         }
595
596                         if (moduleAttributes.size() > 0) {
597                                 eitherResult = Either.left(moduleAttributes);
598                         }
599
600                 }
601                 return eitherResult;
602
603         }
604
605         private static PropertyDefinition createAttribute(String name) {
606                 PropertyDefinition attribute = new PropertyDefinition();
607
608                 attribute.setName(name);
609                 return attribute;
610         }
611
612         private static PropertyDefinition createProperties(String name) {
613                 PropertyDefinition property = new PropertyDefinition();
614                 property.setDefaultValue(name);
615                 property.setName(name);
616                 return property;
617         }
618
619         private static InputDefinition createInputs(String name) {
620                 InputDefinition input = new InputDefinition();
621
622                 input.setName(name);
623                 return input;
624         }
625
626         public static Either<List<HeatParameterDefinition>, ResultStatusEnum> getHeatParameters(Map<String, Object> heatData, String artifactType) {
627
628                 Either<List<HeatParameterDefinition>, ResultStatusEnum> eitherResult = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND);
629                 Either<Map<String, Object>, ResultStatusEnum> toscaProperties = findFirstToscaMapElement(heatData, ToscaTagNamesEnum.PARAMETERS);
630                 if (toscaProperties.isLeft()) {
631                         Map<String, Object> jsonProperties = toscaProperties.left().value();
632                         List<HeatParameterDefinition> moduleProperties = new ArrayList<>();
633                         Iterator<Entry<String, Object>> propertiesNameValue = jsonProperties.entrySet().iterator();
634                         while (propertiesNameValue.hasNext()) {
635                                 Entry<String, Object> propertyNameValue = propertiesNameValue.next();
636                                 if (propertyNameValue.getValue() instanceof Map || propertyNameValue.getValue() instanceof List) {
637                                         if (!artifactType.equals(ArtifactTypeEnum.HEAT_ENV.getType())) {
638                                                 @SuppressWarnings("unchecked")
639                                                 Either<HeatParameterDefinition, ResultStatusEnum> propertyStatus = createModuleHeatParameter((Map<String, Object>) propertyNameValue.getValue());
640                                                 if (propertyStatus.isRight()) {
641                                                         return Either.right(propertyStatus.right().value());
642                                                 }
643                                                 HeatParameterDefinition property = propertyStatus.left().value();
644                                                 property.setName(String.valueOf(propertyNameValue.getKey()));
645                                                 moduleProperties.add(property);
646                                         } else {
647                                                 addHeatParamDefinition(moduleProperties, propertyNameValue, true);
648                                         }
649                                 } else {
650                                         addHeatParamDefinition(moduleProperties, propertyNameValue, false);
651                                 }
652
653                         }
654
655                         if (moduleProperties.size() > 0) {
656                                 eitherResult = Either.left(moduleProperties);
657                         }
658
659                 }
660                 return eitherResult;
661
662         }
663
664         private static void addHeatParamDefinition(List<HeatParameterDefinition> moduleProperties, Entry<String, Object> propertyNameValue, boolean isJson) {
665                 HeatParameterDefinition property = new HeatParameterDefinition();
666                 Object value = propertyNameValue.getValue();
667                 if (value != null) {
668                         property.setDefaultValue(isJson ? new Gson().toJson(value).toString() : StringEscapeUtils.escapeJava(String.valueOf(value)));
669                 }
670                 property.setName(String.valueOf(propertyNameValue.getKey()));
671                 moduleProperties.add(property);
672         }
673
674         private static Either<HeatParameterDefinition, ResultStatusEnum> createModuleHeatParameter(Map<String, Object> propertyValue) {
675                 HeatParameterDefinition propertyDef = new HeatParameterDefinition();
676                 String type;
677                 Either<String, ResultStatusEnum> propertyFieldType = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.TYPE);
678                 if (propertyFieldType.isLeft()) {
679                         type = propertyFieldType.left().value();
680                         propertyDef.setType(type);
681                 } else {
682                         return Either.right(ResultStatusEnum.INVALID_PROPERTY_TYPE);
683                 }
684                 Either<String, ResultStatusEnum> propertyFieldDescription = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.DESCRIPTION);
685                 if (propertyFieldDescription.isLeft()) {
686                         propertyDef.setDescription(propertyFieldDescription.left().value());
687                 }
688
689                 Either<Object, ResultStatusEnum> propertyFieldDefaultVal = findToscaElement(propertyValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL);
690                 if (propertyFieldDefaultVal.isLeft()) {
691                         if (propertyFieldDefaultVal.left().value() == null) {
692                                 return Either.right(ResultStatusEnum.INVALID_PROPERTY_VALUE);
693                         }
694                         Object value = propertyFieldDefaultVal.left().value();
695                         String defaultValue = type.equals(HeatParameterType.JSON.getType()) ? new Gson().toJson(value).toString() : StringEscapeUtils.escapeJava(String.valueOf(value));
696                         propertyDef.setDefaultValue(defaultValue);
697                         propertyDef.setCurrentValue(defaultValue);
698                 }
699
700                 return Either.left(propertyDef);
701         }
702
703         public static String getPropertyJsonStringValue(Object value, String type) {
704                 Gson gson = new Gson();
705                 if (type == null) {
706                         return null;
707                 }
708                 ToscaPropertyType validType = ToscaPropertyType.isValidType(type);
709                 if (validType == null ||  validType.equals(ToscaPropertyType.JSON) ||validType.equals(ToscaPropertyType.MAP) || validType.equals(ToscaPropertyType.LIST)) {
710                         return gson.toJson(value);
711                 }
712                 return value.toString();
713         }
714
715         /**
716          * removes from Json map (toscaJson) first element found by name (elementName) note that this method could update the received argument toscaJson
717          * 
718          * @param toscaJson
719          * @param elementName
720          */
721         public static void removeElementFromJsonMap(Map<String, Object> toscaJson, String elementName) {
722                 for (Entry<String, Object> entry : toscaJson.entrySet()) {
723                         String key = entry.getKey();
724                         Object value = entry.getValue();
725                         if (key.equals(elementName)) {
726                                 toscaJson.remove(elementName);
727                                 return;
728                         } else if (value instanceof Map) {
729                                 removeElementFromJsonMap((Map<String, Object>) value, elementName);
730                         }
731                 }
732         }
733 }