9bc2d01c6d777a1125d409114c55f45a59767ce5
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / csar / YamlTemplateParsingHandler.java
1 package org.openecomp.sdc.be.components.csar;
2
3 import com.google.common.collect.Lists;
4 import com.google.common.collect.Maps;
5 import com.google.gson.Gson;
6 import fj.data.Either;
7 import org.apache.commons.collections.CollectionUtils;
8 import org.apache.commons.collections.MapUtils;
9 import org.apache.commons.lang.StringUtils;
10 import org.openecomp.sdc.be.components.impl.AnnotationBusinessLogic;
11 import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic;
12 import org.openecomp.sdc.be.components.impl.ImportUtils;
13 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
14 import org.openecomp.sdc.be.config.BeEcompErrorManager;
15 import org.openecomp.sdc.be.dao.api.ActionStatus;
16 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
17 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
18 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
19 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
20 import org.openecomp.sdc.be.model.*;
21 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
22 import org.openecomp.sdc.common.log.wrappers.Logger;
23 import org.springframework.stereotype.Component;
24 import org.yaml.snakeyaml.parser.ParserException;
25
26 import java.util.*;
27 import java.util.regex.Pattern;
28 import java.util.stream.Collectors;
29
30 import static java.util.stream.Collectors.toList;
31 import static org.openecomp.sdc.be.components.impl.ImportUtils.*;
32 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.*;
33
34 /**
35  * A handler class designed to parse the YAML file of the service template for a JAVA object
36  */
37 @Component
38 public class YamlTemplateParsingHandler {
39
40     private static final Pattern propertyValuePattern = Pattern.compile("[ ]*\\{[ ]*(str_replace=|token=|get_property=|concat=|get_attribute=)+");
41     private static final int SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX = 0;
42     private static final int SUB_MAPPING_CAPABILITY_NAME_IDX = 1;
43     private static final Logger log = Logger.getLogger(YamlTemplateParsingHandler.class);
44
45
46     private Gson gson = new Gson();
47     private TitanDao titanDao;
48     private GroupTypeBusinessLogic groupTypeBusinessLogic;
49     private AnnotationBusinessLogic annotationBusinessLogic;
50
51     public YamlTemplateParsingHandler(TitanDao titanDao,
52                                       GroupTypeBusinessLogic groupTypeBusinessLogic, AnnotationBusinessLogic annotationBusinessLogic) {
53         this.titanDao = titanDao;
54         this.groupTypeBusinessLogic = groupTypeBusinessLogic;
55         this.annotationBusinessLogic = annotationBusinessLogic;
56     }
57
58     public ParsedToscaYamlInfo parseResourceInfoFromYAML(String fileName, String resourceYml, Map<String, String> createdNodesToscaResourceNames,
59                                                          Map<String, NodeTypeInfo> nodeTypesInfo, String nodeName) {
60         log.debug("#parseResourceInfoFromYAML - Going to parse yaml {} ", fileName);
61         Map<String, Object> mappedToscaTemplate = getMappedToscaTemplate(fileName, resourceYml, nodeTypesInfo, nodeName);
62         ParsedToscaYamlInfo parsedToscaYamlInfo = new ParsedToscaYamlInfo();
63         findToscaElement(mappedToscaTemplate, TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL)
64                 .left()
65                 .on(err -> failIfNotTopologyTemplate(fileName));
66
67         parsedToscaYamlInfo.setInputs(getInputs(mappedToscaTemplate));
68         parsedToscaYamlInfo.setInstances(getInstances(fileName, mappedToscaTemplate, createdNodesToscaResourceNames));
69         parsedToscaYamlInfo.setGroups(getGroups(fileName, mappedToscaTemplate));
70         log.debug("#parseResourceInfoFromYAML - The yaml {} has been parsed ", fileName);
71         return parsedToscaYamlInfo;
72     }
73
74     private Map<String, Object> getMappedToscaTemplate(String fileName, String resourceYml, Map<String, NodeTypeInfo> nodeTypesInfo, String nodeName) {
75         Map<String, Object> mappedToscaTemplate;
76         if (isNodeExist(nodeTypesInfo, nodeName)) {
77             mappedToscaTemplate = nodeTypesInfo.get(nodeName).getMappedToscaTemplate();
78         } else {
79             mappedToscaTemplate = loadYaml(fileName, resourceYml);
80         }
81         return mappedToscaTemplate;
82     }
83
84     private Map<String, Object> loadYaml(String fileName, String resourceYml) {
85         Map<String, Object> mappedToscaTemplate = null;
86         try {
87             mappedToscaTemplate = loadYamlAsStrictMap(resourceYml);
88         } catch (ParserException e) {
89             log.debug("#getMappedToscaTemplate - Failed to load YAML file {}", fileName, e);
90             rollbackWithException(ActionStatus.TOSCA_PARSE_ERROR, fileName, e.getMessage());
91         }
92         return mappedToscaTemplate;
93     }
94
95     private boolean isNodeExist(Map<String, NodeTypeInfo> nodeTypesInfo, String nodeName) {
96         return nodeTypesInfo != null && nodeName != null && nodeTypesInfo.containsKey(nodeName);
97     }
98
99     private Map<String, InputDefinition> getInputs(Map<String, Object> toscaJson) {
100         Map<String, InputDefinition> inputs = ImportUtils.getInputs(toscaJson, annotationBusinessLogic.getAnnotationTypeOperations())
101                 .left()
102                 .on(err -> new HashMap<>());
103         annotationBusinessLogic.validateAndMergeAnnotationsAndAssignToInput(inputs);
104         return inputs;
105     }
106
107     private Map<String, UploadComponentInstanceInfo> getInstances(String yamlName, Map<String, Object> toscaJson, Map<String, String> createdNodesToscaResourceNames) {
108
109         Map<String, Object> nodeTemlates = findFirstToscaMapElement(toscaJson, NODE_TEMPLATES)
110                 .left()
111                 .on(err -> failIfNoNodeTemplates(yamlName));
112
113         Map<String, UploadComponentInstanceInfo> componentInstances = getInstances(toscaJson, createdNodesToscaResourceNames, nodeTemlates);
114         if (MapUtils.isEmpty(componentInstances)) {
115             failIfNotTopologyTemplate(yamlName);
116         }
117         return componentInstances;
118     }
119
120     private Map<String, UploadComponentInstanceInfo> getInstances(Map<String, Object> toscaJson, Map<String, String> createdNodesToscaResourceNames, Map<String, Object> nodeTemlates) {
121         Map<String, UploadComponentInstanceInfo> moduleComponentInstances;
122         Map<String, Object> substitutionMappings = getSubstitutionMappings(toscaJson);
123         moduleComponentInstances = nodeTemlates.entrySet()
124                 .stream()
125                 .map(node -> buildModuleComponentInstanceInfo(node, substitutionMappings, createdNodesToscaResourceNames))
126                 .collect(Collectors.toMap(UploadComponentInstanceInfo::getName, i -> i));
127         return moduleComponentInstances;
128     }
129
130     private Map<String, Object> getSubstitutionMappings(Map<String, Object> toscaJson) {
131         Map<String, Object> substitutionMappings = null;
132         Either<Map<String, Object>, ResultStatusEnum> eitherSubstitutionMappings = findFirstToscaMapElement(toscaJson, SUBSTITUTION_MAPPINGS);
133         if (eitherSubstitutionMappings.isLeft()) {
134             substitutionMappings = eitherSubstitutionMappings.left().value();
135         }
136         return substitutionMappings;
137     }
138
139     @SuppressWarnings("unchecked")
140     private Map<String, GroupDefinition> getGroups(String fileName, Map<String, Object> toscaJson) {
141
142         Map<String, Object> foundGroups = findFirstToscaMapElement(toscaJson, GROUPS)
143                 .left()
144                 .on(err -> logGroupsNotFound(fileName));
145
146         if (MapUtils.isNotEmpty(foundGroups)) {
147             Map<String, GroupDefinition> groups = foundGroups
148                     .entrySet()
149                     .stream()
150                     .map(this::createGroup)
151                     .collect(Collectors.toMap(GroupDefinition::getName, g -> g));
152             Map<String, Object> substitutionMappings = getSubstitutionMappings(toscaJson);
153             if (capabilitiesSubstitutionMappingsExist(substitutionMappings)) {
154                 groups.entrySet().forEach(entry -> updateCapabilitiesNames(entry.getValue(), getNamesToUpdate(entry.getKey(),
155                         (Map<String, List<String>>) substitutionMappings.get(CAPABILITIES.getElementName()))));
156             }
157             return groups;
158         }
159         return new HashMap<>();
160     }
161
162     private Map<String, Object> logGroupsNotFound(String fileName) {
163         log.debug("#logGroupsNotFound - Groups were not found in the yaml template {}.", fileName);
164         return new HashMap<>();
165     }
166
167     private void updateCapabilitiesNames(GroupDefinition group, Map<String, String> capabilityNames) {
168         if (MapUtils.isNotEmpty(group.getCapabilities())) {
169             group.getCapabilities().values()
170                     .stream()
171                     .flatMap(Collection::stream)
172                     .filter(cap -> capabilityNames.containsKey(cap.getName()))
173                     .forEach(cap -> cap.setName(capabilityNames.get(cap.getName())));
174         }
175     }
176
177     private Map<String, String> getNamesToUpdate(String name, Map<String, List<String>> pair) {
178         return pair.entrySet().stream()
179                 .filter(e -> e.getValue().get(SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX).equalsIgnoreCase(name))
180                 .collect(Collectors.toMap(e -> e.getValue().get(SUB_MAPPING_CAPABILITY_NAME_IDX), Map.Entry::getKey,  (n1 ,n2) -> n1));
181     }
182
183     private boolean capabilitiesSubstitutionMappingsExist(Map<String, Object> substitutionMappings) {
184         return substitutionMappings != null && substitutionMappings.containsKey(CAPABILITIES.getElementName());
185     }
186
187     private GroupDefinition createGroup(Map.Entry<String, Object> groupNameValue) {
188         GroupDefinition group = new GroupDefinition();
189         group.setName(groupNameValue.getKey());
190         try {
191             if (groupNameValue.getValue() != null && groupNameValue.getValue() instanceof Map) {
192                 Map<String, Object> groupTemplateJsonMap = (Map<String, Object>) groupNameValue.getValue();
193                 validateAndFillGroup(group, groupTemplateJsonMap);
194                 validateUpdateGroupProperties(group, groupTemplateJsonMap);
195                 validateUpdateGroupCapabilities(group, groupTemplateJsonMap);
196             } else {
197                 rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
198             }
199         } catch (ClassCastException e) {
200             log.debug("#createGroup - Failed to create the group {}. The exception occure", groupNameValue.getKey(), e);
201             rollbackWithException(ActionStatus.INVALID_YAML);
202         }
203         return group;
204     }
205
206     private Map<String, CapabilityDefinition> addCapabilities(Map<String, CapabilityDefinition> cap, Map<String, CapabilityDefinition> otherCap) {
207         cap.putAll(otherCap);
208         return cap;
209     }
210
211     private Map<String, CapabilityDefinition> addCapability(CapabilityDefinition cap) {
212         Map<String, CapabilityDefinition> map = Maps.newHashMap();
213         map.put(cap.getName(), cap);
214         return map;
215     }
216
217     private void setMembers(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
218         if (groupTemplateJsonMap.containsKey(MEMBERS.getElementName())) {
219             Object members = groupTemplateJsonMap.get(MEMBERS.getElementName());
220             if (members != null) {
221                 if (members instanceof List) {
222                     setMembersFromList(groupInfo, (List<?>) members);
223                 } else {
224                     log.debug("The 'members' member is not of type list under group {}", groupInfo.getName());
225                     rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
226                 }
227             }
228         }
229     }
230
231     private void setMembersFromList(GroupDefinition groupInfo, List<?> membersAsList) {
232         groupInfo.setMembers(membersAsList
233                 .stream()
234                 .collect(Collectors.toMap(Object::toString, member -> "")));
235     }
236
237     @SuppressWarnings("unchecked")
238     private void validateUpdateGroupProperties(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
239         if (groupTemplateJsonMap.containsKey(PROPERTIES.getElementName())) {
240             Object propertiesElement = groupTemplateJsonMap.get(PROPERTIES.getElementName());
241             if (propertiesElement instanceof Map){
242                 mergeGroupProperties(groupInfo, (Map<String, Object>) propertiesElement);
243             }
244         }
245     }
246
247     private void mergeGroupProperties(GroupDefinition groupInfo, Map<String, Object> parsedProperties) {
248         if(CollectionUtils.isNotEmpty(groupInfo.getProperties())){
249             validateGroupProperties(parsedProperties, groupInfo);
250             groupInfo.getProperties().forEach(p -> mergeGroupProperty(p, parsedProperties));
251         }
252     }
253
254     private void mergeGroupProperty(PropertyDataDefinition property, Map<String, Object> parsedProperties) {
255         if(parsedProperties.containsKey(property.getName())){
256             Object propValue = parsedProperties.get(property.getName());
257             if (valueNotContainsPattern(propertyValuePattern, propValue)) {
258                 setPropertyValueAndGetInputsValues(property, propValue);
259             }
260         }
261     }
262
263     private void setPropertyValueAndGetInputsValues(PropertyDataDefinition property, Object propValue) {
264         if(propValue != null){
265             UploadPropInfo uploadPropInfo = buildProperty(property.getName(), propValue);
266             property.setValue(convertPropertyValue(ToscaPropertyType.isValidType(property.getType()), uploadPropInfo.getValue()));
267             property.setGetInputValues(uploadPropInfo.getGet_input());
268         }
269     }
270
271     private String convertPropertyValue(ToscaPropertyType type, Object value) {
272         String convertedValue = null;
273         if (value != null) {
274             if (type == null || value instanceof Map || value instanceof List) {
275                 convertedValue = gson.toJson(value);
276             } else {
277                 convertedValue = value.toString();
278             }
279         }
280         return convertedValue;
281     }
282
283     private void setDescription(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
284         if (groupTemplateJsonMap.containsKey(DESCRIPTION.getElementName())) {
285             groupInfo.setDescription(
286                     (String) groupTemplateJsonMap.get(DESCRIPTION.getElementName()));
287         }
288     }
289
290     private void validateAndFillGroup(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
291         String type = (String) groupTemplateJsonMap.get(TYPE.getElementName());
292         if(StringUtils.isEmpty(type)){
293             log.debug("#validateAndFillGroup - The 'type' member is not found under group {}", groupInfo.getName());
294             rollbackWithException(ActionStatus.GROUP_MISSING_GROUP_TYPE, groupInfo.getName());
295         }
296         groupInfo.setType(type);
297         GroupTypeDefinition groupType =  groupTypeBusinessLogic.getLatestGroupTypeByType(type);
298         if (groupType == null) {
299             log.debug("#validateAndFillGroup - The group type {} not found", groupInfo.getName());
300             rollbackWithException(ActionStatus.GROUP_TYPE_IS_INVALID, type);
301         }
302         groupInfo.convertFromGroupProperties(groupType.getProperties());
303         groupInfo.convertCapabilityDefinitions(groupType.getCapabilities());
304         setDescription(groupInfo, groupTemplateJsonMap);
305         setMembers(groupInfo, groupTemplateJsonMap);
306     }
307
308     @SuppressWarnings("unchecked")
309     private void validateUpdateGroupCapabilities(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
310
311         if (groupTemplateJsonMap.containsKey(CAPABILITIES.getElementName())) {
312             Object capabilities = groupTemplateJsonMap.get(CAPABILITIES.getElementName());
313             if (capabilities instanceof List) {
314                 validateUpdateCapabilities(groupInfo, ((List<Object>) capabilities).stream()
315                         .map(o -> buildGroupCapability(groupInfo, o))
316                         .collect(Collectors.toMap(CapabilityDefinition::getType, this::addCapability, this::addCapabilities)));
317             } else if (capabilities instanceof Map) {
318                 validateUpdateCapabilities(groupInfo, ((Map<String, Object>) capabilities).entrySet()
319                         .stream()
320                         .map(e -> buildGroupCapability(groupInfo, e))
321                         .collect(Collectors.toMap(CapabilityDefinition::getType, this::addCapability, this::addCapabilities)));
322             } else {
323                 log.debug("#setCapabilities - Failed to import the capabilities of the group {}. ", groupInfo.getName());
324                 rollbackWithException(ActionStatus.INVALID_YAML);
325             }
326         }
327     }
328
329     private void validateUpdateCapabilities(GroupDefinition groupInfo, Map<String, Map<String, CapabilityDefinition>> capabilityInfo) {
330         validateGroupCapabilities(groupInfo, capabilityInfo);
331         groupInfo.updateCapabilitiesProperties(capabilityInfo);
332     }
333
334     private void validateGroupCapabilities(GroupDefinition group, Map<String, Map<String, CapabilityDefinition>> parsedCapabilities) {
335         if (MapUtils.isNotEmpty(parsedCapabilities)) {
336             if (MapUtils.isEmpty(group.getCapabilities())) {
337                 failOnMissingCapabilityTypes(group, Lists.newArrayList(parsedCapabilities.keySet()));
338             }
339             List<String> missingCapTypes = parsedCapabilities.keySet().stream().filter(ct -> !group.getCapabilities().containsKey(ct)).collect(toList());
340             if (CollectionUtils.isNotEmpty(missingCapTypes)) {
341                 failOnMissingCapabilityTypes(group, missingCapTypes);
342             }
343             group.getCapabilities().entrySet().forEach(e -> validateCapabilities(group, e.getValue(), parsedCapabilities.get(e.getKey())));
344         }
345     }
346
347     private void validateCapabilities(GroupDefinition group, List<CapabilityDefinition> capabilities, Map<String, CapabilityDefinition> parsedCapabilities) {
348         List<String> allowedCapNames = capabilities.stream().map(CapabilityDefinition::getName).distinct().collect(toList());
349         List<String> missingCapNames = parsedCapabilities.keySet().stream().filter(c -> !allowedCapNames.contains(c)).collect(toList());
350         if (CollectionUtils.isNotEmpty(missingCapNames)) {
351             failOnMissingCapabilityNames(group, missingCapNames);
352         }
353         validateCapabilitiesProperties(capabilities, parsedCapabilities);
354     }
355
356     private void validateCapabilitiesProperties(List<CapabilityDefinition> capabilities, Map<String, CapabilityDefinition> parsedCapabilities) {
357         capabilities.forEach(c -> validateCapabilityProperties(c, parsedCapabilities.get(c.getName())));
358     }
359
360     private void validateCapabilityProperties(CapabilityDefinition capability, CapabilityDefinition parsedCapability) {
361         if(parsedCapability != null && parsedCapability.getProperties() != null){
362             List<String> parsedPropertiesNames = parsedCapability.getProperties()
363                 .stream()
364                 .map(ComponentInstanceProperty::getName).collect(toList());
365             validateProperties(capability.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames, ActionStatus.PROPERTY_NOT_FOUND, capability.getName(), capability.getType());
366         }
367     }
368
369     private void  validateGroupProperties(Map<String, Object> parsedProperties, GroupDefinition groupInfo) {
370         List<String> parsedPropertiesNames = parsedProperties.entrySet()
371                         .stream()
372                         .map(Map.Entry::getKey).collect(toList());
373         validateProperties(groupInfo.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames, ActionStatus.GROUP_PROPERTY_NOT_FOUND, groupInfo.getName(), groupInfo.getType());
374     }
375
376     private void validateProperties(List<String> validProperties, List<String> parsedProperties, ActionStatus actionStatus, String name, String type) {
377         if (CollectionUtils.isNotEmpty(parsedProperties)) {
378             verifyMissingProperties(actionStatus, name, type, parsedProperties
379                     .stream()
380                     .filter(n -> !validProperties.contains(n))
381                     .collect(toList()));
382         }
383     }
384
385     private void verifyMissingProperties(ActionStatus actionStatus, String name, String type, List<String> missingProperties) {
386         if (CollectionUtils.isNotEmpty(missingProperties)) {
387             log.debug("#validateProperties - Failed to validate properties. The properties {} are missing on {} of the type {}. ", missingProperties.toString(), name, type);
388             rollbackWithException(actionStatus, missingProperties.toString(), missingProperties.toString(), name, type);
389         }
390     }
391
392     @SuppressWarnings("unchecked")
393     private CapabilityDefinition buildGroupCapability(GroupDefinition groupInfo, Object capObject) {
394         if (!(capObject instanceof Map)) {
395             log.debug("#convertToGroupCapability - Failed to import the capability {}. ", capObject);
396             rollbackWithException(ActionStatus.INVALID_YAML);
397         }
398         return buildGroupCapability(groupInfo, ((Map<String, Object>) capObject).entrySet().iterator().next());
399     }
400
401     @SuppressWarnings("unchecked")
402     private CapabilityDefinition buildGroupCapability(GroupDefinition groupInfo, Map.Entry<String, Object> capEntry) {
403         CapabilityDefinition capability = new CapabilityDefinition();
404         capability.setOwnerType(CapabilityDataDefinition.OwnerType.GROUP);
405         capability.setName(capEntry.getKey());
406         capability.setParentName(capEntry.getKey());
407         capability.setOwnerId(groupInfo.getName());
408         if (!(capEntry.getValue() instanceof Map)) {
409             log.debug("#convertMapEntryToCapabilityDefinition - Failed to import the capability {}. ", capEntry.getKey());
410             rollbackWithException(ActionStatus.INVALID_YAML);
411         }
412         Map<String, Object> capabilityValue = (Map<String, Object>) capEntry.getValue();
413         String type = (String) capabilityValue.get(TYPE.getElementName());
414         if (StringUtils.isEmpty(type)) {
415             log.debug("#convertMapEntryToCapabilityDefinition - Failed to import the capability {}. Missing capability type. ", capEntry.getKey());
416             rollbackWithException(ActionStatus.INVALID_YAML);
417         }
418         capability.setType(type);
419         if (!(capabilityValue.get(PROPERTIES.getElementName()) instanceof Map)) {
420             log.debug("#convertMapEntryToCapabilityDefinition - Failed to import the capability {}. ", capEntry.getKey());
421             rollbackWithException(ActionStatus.INVALID_YAML);
422         }
423         Map<String, Object> properties = (Map<String, Object>) capabilityValue.get(PROPERTIES.getElementName());
424         capability.setProperties(properties.entrySet().stream().map(this::convertToProperty).collect(toList()));
425         return capability;
426     }
427
428     private ComponentInstanceProperty convertToProperty(Map.Entry<String, Object> e) {
429         ComponentInstanceProperty property = new ComponentInstanceProperty();
430         property.setName(e.getKey());
431         property.setValue((String) e.getValue());
432         return property;
433     }
434
435     @SuppressWarnings("unchecked")
436     private UploadComponentInstanceInfo buildModuleComponentInstanceInfo(
437             Map.Entry<String, Object> nodeTemplateJsonEntry, Map<String, Object> substitutionMappings,
438             Map<String, String> createdNodesToscaResourceNames) {
439
440         UploadComponentInstanceInfo nodeTemplateInfo = new UploadComponentInstanceInfo();
441         nodeTemplateInfo.setName(nodeTemplateJsonEntry.getKey());
442         try {
443             if (nodeTemplateJsonEntry.getValue() instanceof String) {
444                 String nodeTemplateJsonString = (String) nodeTemplateJsonEntry.getValue();
445                 nodeTemplateInfo.setType(nodeTemplateJsonString);
446             } else if (nodeTemplateJsonEntry.getValue() instanceof Map) {
447                 Map<String, Object> nodeTemplateJsonMap = (Map<String, Object>) nodeTemplateJsonEntry.getValue();
448                 setToscaResourceType(createdNodesToscaResourceNames, nodeTemplateInfo, nodeTemplateJsonMap);
449                 setRequirements(nodeTemplateInfo, nodeTemplateJsonMap);
450                 setCapabilities(nodeTemplateInfo, nodeTemplateJsonMap);
451                 updateProperties(nodeTemplateInfo, nodeTemplateJsonMap);
452                 setSubstitutions(substitutionMappings, nodeTemplateInfo);
453             } else {
454                 rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
455             }
456         } catch (ClassCastException e) {
457             BeEcompErrorManager.getInstance().logBeSystemError("Import Resource - create capability");
458             log.debug("error when creating capability, message:{}", e.getMessage(), e);
459             rollbackWithException(ActionStatus.INVALID_YAML);
460         }
461         return nodeTemplateInfo;
462     }
463
464     @SuppressWarnings("unchecked")
465     private void setSubstitutions(Map<String, Object> substitutionMappings, UploadComponentInstanceInfo nodeTemplateInfo) {
466         if (substitutionMappings != null) {
467             if (substitutionMappings.containsKey(CAPABILITIES.getElementName())) {
468                 nodeTemplateInfo.setCapabilitiesNamesToUpdate(getNamesToUpdate(nodeTemplateInfo.getName(), (Map<String, List<String>>) substitutionMappings
469                         .get(CAPABILITIES.getElementName())));
470             }
471             if (substitutionMappings.containsKey(REQUIREMENTS.getElementName())) {
472                 nodeTemplateInfo.setRequirementsNamesToUpdate(getNamesToUpdate(
473                         nodeTemplateInfo.getName(), (Map<String, List<String>>) substitutionMappings
474                                 .get(REQUIREMENTS.getElementName())));
475             }
476         }
477     }
478
479     private void updateProperties(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
480         if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) {
481             Map<String, List<UploadPropInfo>> properties = buildPropModuleFromYaml(nodeTemplateJsonMap);
482             if (!properties.isEmpty()) {
483                 nodeTemplateInfo.setProperties(properties);
484             }
485         }
486     }
487
488     private void setCapabilities(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
489         if (nodeTemplateJsonMap.containsKey(CAPABILITIES.getElementName())) {
490             Map<String, List<UploadCapInfo>> eitherCapRes = createCapModuleFromYaml(nodeTemplateJsonMap);
491             if (!eitherCapRes.isEmpty()) {
492                 nodeTemplateInfo.setCapabilities(eitherCapRes);
493             }
494         }
495     }
496
497     private void setRequirements(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
498         if (nodeTemplateJsonMap.containsKey(REQUIREMENTS.getElementName())) {
499             Map<String, List<UploadReqInfo>> regResponse = createReqModuleFromYaml(nodeTemplateJsonMap);
500             if (!regResponse.isEmpty()) {
501                 nodeTemplateInfo.setRequirements(regResponse);
502             }
503         }
504     }
505
506     private void setToscaResourceType(Map<String, String> createdNodesToscaResourceNames,
507                                       UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
508         if (nodeTemplateJsonMap.containsKey(TYPE.getElementName())) {
509             String toscaResourceType = (String) nodeTemplateJsonMap.get(TYPE.getElementName());
510             if (createdNodesToscaResourceNames.containsKey(toscaResourceType)) {
511                 toscaResourceType = createdNodesToscaResourceNames.get(toscaResourceType);
512             }
513             nodeTemplateInfo.setType(toscaResourceType);
514         }
515     }
516
517     @SuppressWarnings("unchecked")
518     private Map<String, List<UploadReqInfo>> createReqModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) {
519         Map<String, List<UploadReqInfo>> moduleRequirements = new HashMap<>();
520         Either<List<Object>, ResultStatusEnum> requirementsListRes =
521                 findFirstToscaListElement(nodeTemplateJsonMap, REQUIREMENTS);
522
523         if (requirementsListRes.isLeft()) {
524             for (Object jsonReqObj : requirementsListRes.left().value()) {
525                 String reqName = ((Map<String, Object>) jsonReqObj).keySet().iterator().next();
526                 Object reqJson = ((Map<String, Object>) jsonReqObj).get(reqName);
527                 addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName);
528             }
529         } else {
530             Either<Map<String, Object>, ResultStatusEnum> requirementsMapRes =
531                     findFirstToscaMapElement(nodeTemplateJsonMap, REQUIREMENTS);
532             if (requirementsMapRes.isLeft()) {
533                 for (Map.Entry<String, Object> entry : requirementsMapRes.left().value().entrySet()) {
534                     String reqName = entry.getKey();
535                     Object reqJson = entry.getValue();
536                     addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName);
537                 }
538             }
539         }
540         return moduleRequirements;
541     }
542
543     private void addModuleNodeTemplateReq(Map<String, List<UploadReqInfo>> moduleRequirements, Object requirementJson, String requirementName) {
544
545         UploadReqInfo requirement = buildModuleNodeTemplateReg(requirementJson);
546         requirement.setName(requirementName);
547         if (moduleRequirements.containsKey(requirementName)) {
548             moduleRequirements.get(requirementName).add(requirement);
549         } else {
550             List<UploadReqInfo> list = new ArrayList<>();
551             list.add(requirement);
552             moduleRequirements.put(requirementName, list);
553         }
554     }
555
556     @SuppressWarnings("unchecked")
557     private Map<String, List<UploadCapInfo>> createCapModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) {
558         Map<String, List<UploadCapInfo>> moduleCap = new HashMap<>();
559         Either<List<Object>, ResultStatusEnum> capabilitiesListRes =
560                 findFirstToscaListElement(nodeTemplateJsonMap, CAPABILITIES);
561         if (capabilitiesListRes.isLeft()) {
562             for (Object jsonCapObj : capabilitiesListRes.left().value()) {
563                 String key = ((Map<String, Object>) jsonCapObj).keySet().iterator().next();
564                 Object capJson = ((Map<String, Object>) jsonCapObj).get(key);
565                 addModuleNodeTemplateCap(moduleCap, capJson, key);
566             }
567         } else {
568             Either<Map<String, Object>, ResultStatusEnum> capabilitiesMapRes =
569                     findFirstToscaMapElement(nodeTemplateJsonMap, CAPABILITIES);
570             if (capabilitiesMapRes.isLeft()) {
571                 for (Map.Entry<String, Object> entry : capabilitiesMapRes.left().value().entrySet()) {
572                     String capName = entry.getKey();
573                     Object capJson = entry.getValue();
574                     addModuleNodeTemplateCap(moduleCap, capJson, capName);
575                 }
576             }
577         }
578         return moduleCap;
579     }
580
581     private void addModuleNodeTemplateCap(Map<String, List<UploadCapInfo>> moduleCap, Object capJson, String key) {
582
583         UploadCapInfo capabilityDef = buildModuleNodeTemplateCap(capJson);
584         capabilityDef.setKey(key);
585         if (moduleCap.containsKey(key)) {
586             moduleCap.get(key).add(capabilityDef);
587         } else {
588             List<UploadCapInfo> list = new ArrayList<>();
589             list.add(capabilityDef);
590             moduleCap.put(key, list);
591         }
592     }
593
594     @SuppressWarnings("unchecked")
595     private UploadCapInfo buildModuleNodeTemplateCap(Object capObject) {
596         UploadCapInfo capTemplateInfo = new UploadCapInfo();
597
598         if (capObject instanceof String) {
599             String nodeTemplateJsonString = (String) capObject;
600             capTemplateInfo.setNode(nodeTemplateJsonString);
601         } else if (capObject instanceof Map) {
602             fillCapability(capTemplateInfo, (Map<String, Object>) capObject);
603         }
604         return capTemplateInfo;
605     }
606
607     private void fillCapability(UploadCapInfo capTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
608         if (nodeTemplateJsonMap.containsKey(NODE.getElementName())) {
609             capTemplateInfo.setNode((String) nodeTemplateJsonMap.get(NODE.getElementName()));
610         }
611         if (nodeTemplateJsonMap.containsKey(TYPE.getElementName())) {
612             capTemplateInfo.setType((String) nodeTemplateJsonMap.get(TYPE.getElementName()));
613         }
614         if (nodeTemplateJsonMap.containsKey(VALID_SOURCE_TYPES.getElementName())) {
615             Either<List<Object>, ResultStatusEnum> validSourceTypesRes =
616                     findFirstToscaListElement(nodeTemplateJsonMap, VALID_SOURCE_TYPES);
617             if (validSourceTypesRes.isLeft()) {
618                 capTemplateInfo.setValidSourceTypes(validSourceTypesRes.left().value().stream()
619                         .map(Object::toString).collect(toList()));
620             }
621         }
622         if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) {
623             Map<String, List<UploadPropInfo>> props = buildPropModuleFromYaml(nodeTemplateJsonMap);
624             if (!props.isEmpty()) {
625                 List<UploadPropInfo> properties = props.values().stream().flatMap(Collection::stream).collect(toList());
626                 capTemplateInfo.setProperties(properties);
627             }
628         }
629     }
630
631     @SuppressWarnings("unchecked")
632     private UploadReqInfo buildModuleNodeTemplateReg(Object regObject) {
633
634         UploadReqInfo regTemplateInfo = new UploadReqInfo();
635         if (regObject instanceof String) {
636             String nodeTemplateJsonString = (String) regObject;
637             regTemplateInfo.setNode(nodeTemplateJsonString);
638         } else if (regObject instanceof Map) {
639             Map<String, Object> nodeTemplateJsonMap = (Map<String, Object>) regObject;
640             if (nodeTemplateJsonMap.containsKey(NODE.getElementName())) {
641                 regTemplateInfo.setNode((String) nodeTemplateJsonMap.get(NODE.getElementName()));
642             }
643             if (nodeTemplateJsonMap.containsKey(CAPABILITY.getElementName())) {
644                 regTemplateInfo.setCapabilityName(
645                         (String) nodeTemplateJsonMap.get(CAPABILITY.getElementName()));
646             }
647         }
648         return regTemplateInfo;
649     }
650
651     private Map<String, List<UploadPropInfo>> buildPropModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) {
652
653         Map<String, List<UploadPropInfo>> moduleProp = new HashMap<>();
654         Either<Map<String, Object>, ResultStatusEnum> toscaProperties =
655                 findFirstToscaMapElement(nodeTemplateJsonMap, PROPERTIES);
656         if (toscaProperties.isLeft()) {
657             Map<String, Object> jsonProperties = toscaProperties.left().value();
658             for (Map.Entry<String, Object> jsonPropObj : jsonProperties.entrySet()) {
659                 if (valueNotContainsPattern(propertyValuePattern, jsonPropObj.getValue())) {
660                     addProperty(moduleProp, jsonPropObj);
661                 }
662             }
663         }
664         return moduleProp;
665     }
666
667     private void addProperty(Map<String, List<UploadPropInfo>> moduleProp, Map.Entry<String, Object> jsonPropObj) {
668         UploadPropInfo propertyDef = buildProperty(jsonPropObj.getKey(), jsonPropObj.getValue());
669         if (moduleProp.containsKey(propertyDef.getName())) {
670             moduleProp.get(propertyDef.getName()).add(propertyDef);
671         } else {
672             List<UploadPropInfo> list = new ArrayList<>();
673             list.add(propertyDef);
674             moduleProp.put(propertyDef.getName(), list);
675         }
676     }
677
678     @SuppressWarnings("unchecked")
679     private UploadPropInfo buildProperty(String propName, Object propValue) {
680
681         UploadPropInfo propertyDef = new UploadPropInfo();
682         propertyDef.setValue(propValue);
683         propertyDef.setName(propName);
684         if (propValue instanceof Map) {
685             if (((Map<String, Object>) propValue).containsKey(TYPE.getElementName())) {
686                 propertyDef.setType(((Map<String, Object>) propValue)
687                         .get(TYPE.getElementName()).toString());
688             }
689             if (containsGetInput(propValue)) {
690                 fillInputRecursively(propName, (Map<String, Object>) propValue, propertyDef);
691             }
692
693             if (((Map<String, Object>) propValue).containsKey(DESCRIPTION.getElementName())) {
694                 propertyDef.setDescription(((Map<String, Object>) propValue)
695                         .get(DESCRIPTION.getElementName()).toString());
696             }
697             if (((Map<String, Object>) propValue)
698                     .containsKey(DEFAULT_VALUE.getElementName())) {
699                 propertyDef.setValue(((Map<String, Object>) propValue)
700                         .get(DEFAULT_VALUE.getElementName()));
701             }
702             if (((Map<String, Object>) propValue).containsKey(IS_PASSWORD.getElementName())) {
703                 propertyDef.setPassword(Boolean.getBoolean(((Map<String, Object>) propValue)
704                         .get(IS_PASSWORD.getElementName()).toString()));
705             } else {
706                 propertyDef.setValue(propValue);
707             }
708         } else if (propValue instanceof List) {
709             List<Object> propValueList = (List<Object>) propValue;
710
711             fillInputsListRecursively(propertyDef, propValueList);
712             propertyDef.setValue(propValue);
713         }
714
715         return propertyDef;
716     }
717
718     @SuppressWarnings("unchecked")
719     private boolean containsGetInput(Object propValue) {
720         return ((Map<String, Object>) propValue).containsKey(GET_INPUT.getElementName())
721                 || ImportUtils.containsGetInput(propValue);
722     }
723
724     @SuppressWarnings("unchecked")
725     private void fillInputsListRecursively(UploadPropInfo propertyDef, List<Object> propValueList) {
726         for (Object objValue : propValueList) {
727
728             if (objValue instanceof Map) {
729                 Map<String, Object> objMap = (Map<String, Object>) objValue;
730                 if (objMap.containsKey(GET_INPUT.getElementName())) {
731                     fillInputRecursively(propertyDef.getName(), objMap, propertyDef);
732                 } else {
733                     Set<String> keys = objMap.keySet();
734                     findAndFillInputsListRecursively(propertyDef, objMap, keys);
735                 }
736             } else if (objValue instanceof List) {
737                 List<Object> propSubValueList = (List<Object>) objValue;
738                 fillInputsListRecursively(propertyDef, propSubValueList);
739             }
740         }
741     }
742
743     @SuppressWarnings("unchecked")
744     private void findAndFillInputsListRecursively(UploadPropInfo propertyDef, Map<String, Object> objMap,
745                                                   Set<String> keys) {
746         for (String key : keys) {
747             Object value = objMap.get(key);
748             if (value instanceof Map) {
749                 fillInputRecursively(key, (Map<String, Object>) value, propertyDef);
750             } else if (value instanceof List) {
751                 List<Object> propSubValueList = (List<Object>) value;
752                 fillInputsListRecursively(propertyDef, propSubValueList);
753             }
754         }
755     }
756
757     private void fillInputRecursively(String propName, Map<String, Object> propValue, UploadPropInfo propertyDef) {
758
759         if (propValue.containsKey(GET_INPUT.getElementName())) {
760             Object getInput = propValue.get(GET_INPUT.getElementName());
761             GetInputValueDataDefinition getInputInfo = new GetInputValueDataDefinition();
762             List<GetInputValueDataDefinition> getInputs = propertyDef.getGet_input();
763             if (getInputs == null) {
764                 getInputs = new ArrayList<>();
765             }
766             if (getInput instanceof String) {
767
768                 getInputInfo.setInputName((String) getInput);
769                 getInputInfo.setPropName(propName);
770
771             } else if (getInput instanceof List) {
772                 fillInput(propName, getInput, getInputInfo);
773             }
774             getInputs.add(getInputInfo);
775             propertyDef.setGet_input(getInputs);
776             propertyDef.setValue(propValue);
777         } else {
778             findAndFillInputRecursively(propValue, propertyDef);
779         }
780     }
781
782     @SuppressWarnings("unchecked")
783     private void findAndFillInputRecursively(Map<String, Object> propValue, UploadPropInfo propertyDef) {
784         for (String propName : propValue.keySet()) {
785             Object value = propValue.get(propName);
786             if (value instanceof Map) {
787                 fillInputRecursively(propName, (Map<String, Object>) value, propertyDef);
788
789             } else if (value instanceof List) {
790                 fillInputsRecursively(propertyDef, propName, (List<Object>) value);
791             }
792         }
793     }
794
795     private void fillInputsRecursively(UploadPropInfo propertyDef, String propName, List<Object> inputs) {
796         inputs.stream()
797                 .filter(o -> o instanceof Map)
798                 .forEach(o -> fillInputRecursively(propName, (Map<String, Object>)o, propertyDef));
799     }
800
801     @SuppressWarnings("unchecked")
802     private void fillInput(String propName, Object getInput, GetInputValueDataDefinition getInputInfo) {
803         List<Object> getInputList = (List<Object>) getInput;
804         getInputInfo.setPropName(propName);
805         getInputInfo.setInputName((String) getInputList.get(0));
806         if (getInputList.size() > 1) {
807             Object indexObj = getInputList.get(1);
808             if (indexObj instanceof Integer) {
809                 getInputInfo.setIndexValue((Integer) indexObj);
810             } else if (indexObj instanceof Float) {
811                 int index = ((Float) indexObj).intValue();
812                 getInputInfo.setIndexValue(index);
813             } else if (indexObj instanceof Map && ((Map<String, Object>) indexObj)
814                     .containsKey(GET_INPUT.getElementName())) {
815                 Object index = ((Map<String, Object>) indexObj)
816                         .get(GET_INPUT.getElementName());
817                 GetInputValueDataDefinition getInputInfoIndex = new GetInputValueDataDefinition();
818                 getInputInfoIndex.setInputName((String) index);
819                 getInputInfoIndex.setPropName(propName);
820                 getInputInfo.setGetInputIndex(getInputInfoIndex);
821             }
822             getInputInfo.setList(true);
823         }
824     }
825
826     private boolean valueNotContainsPattern(Pattern pattern, Object propValue) {
827         return propValue == null || !pattern.matcher(propValue.toString()).find();
828     }
829
830     private Map<String, Object> failIfNoNodeTemplates(String fileName) {
831         titanDao.rollback();
832         throw new ComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, fileName);
833     }
834
835     private Object failIfNotTopologyTemplate(String fileName) {
836         titanDao.rollback();
837         throw new ComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, fileName);
838     }
839
840     private void rollbackWithException(ActionStatus actionStatus, String... params) {
841         titanDao.rollback();
842         throw new ComponentException(actionStatus, params);
843     }
844
845     private void failOnMissingCapabilityTypes(GroupDefinition groupDefinition, List<String> missingCapTypes) {
846         log.debug("#failOnMissingCapabilityTypes - Failed to validate the capabilities of the group {}. The capability types {} are missing on the group type {}. ", groupDefinition.getName(), missingCapTypes.toString(), groupDefinition.getType());
847         if(CollectionUtils.isNotEmpty(missingCapTypes)) {
848             rollbackWithException(ActionStatus.MISSING_CAPABILITY_TYPE, missingCapTypes.toString());
849         }
850     }
851
852     private void failOnMissingCapabilityNames(GroupDefinition groupDefinition, List<String> missingCapNames) {
853         log.debug("#failOnMissingCapabilityNames - Failed to validate the capabilities of the group {}. The capabilities with the names {} are missing on the group type {}. ", groupDefinition.getName(), missingCapNames.toString(), groupDefinition.getType());
854         rollbackWithException(ActionStatus.MISSING_CAPABILITIES, missingCapNames.toString(), CapabilityDataDefinition.OwnerType.GROUP.getValue(), groupDefinition.getName());
855     }
856
857 }