7970dd26801a9d1d9e4108b2cdb125af2dde7442
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / csar / YamlTemplateParsingHandler.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  * Modifications copyright (c) 2019 Nokia
20  * ================================================================================
21  */
22
23 package org.openecomp.sdc.be.components.csar;
24
25 import static java.util.stream.Collectors.toList;
26 import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE;
27 import static org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
28 import static org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
29 import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaListElement;
30 import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaMapElement;
31 import static org.openecomp.sdc.be.components.impl.ImportUtils.findToscaElement;
32 import static org.openecomp.sdc.be.components.impl.ImportUtils.loadYamlAsStrictMap;
33 import static org.openecomp.sdc.be.model.tosca.ToscaType.STRING;
34 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.ARTIFACTS;
35 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.ATTRIBUTES;
36 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.CAPABILITIES;
37 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.CAPABILITY;
38 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE;
39 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DESCRIPTION;
40 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.FILE;
41 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.GET_INPUT;
42 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.GROUPS;
43 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.IMPLEMENTATION;
44 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INPUTS;
45 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INTERFACES;
46 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.IS_PASSWORD;
47 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.MEMBERS;
48 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NODE;
49 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES;
50 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NODE_TYPE;
51 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.OPERATIONS;
52 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.OUTPUTS;
53 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.POLICIES;
54 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.PROPERTIES;
55 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.RELATIONSHIP;
56 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.RELATIONSHIP_TEMPLATES;
57 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIREMENTS;
58 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_FILTERS;
59 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_MAPPINGS;
60 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TARGETS;
61 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE;
62 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE;
63 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.VALID_SOURCE_TYPES;
64
65 import com.att.aft.dme2.internal.gson.reflect.TypeToken;
66 import com.google.common.collect.Lists;
67 import com.google.common.collect.Maps;
68 import com.google.gson.Gson;
69 import fj.data.Either;
70 import java.lang.reflect.Type;
71 import java.util.ArrayList;
72 import java.util.Collection;
73 import java.util.Collections;
74 import java.util.EnumMap;
75 import java.util.HashMap;
76 import java.util.LinkedHashMap;
77 import java.util.List;
78 import java.util.Map;
79 import java.util.Map.Entry;
80 import java.util.Objects;
81 import java.util.Optional;
82 import java.util.Set;
83 import java.util.UUID;
84 import java.util.stream.Collectors;
85 import org.apache.commons.collections.CollectionUtils;
86 import org.apache.commons.collections.MapUtils;
87 import org.apache.commons.lang3.StringUtils;
88 import org.openecomp.sdc.be.components.impl.AnnotationBusinessLogic;
89 import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic;
90 import org.openecomp.sdc.be.components.impl.ImportUtils;
91 import org.openecomp.sdc.be.components.impl.NodeFilterUploadCreator;
92 import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic;
93 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
94 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
95 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
96 import org.openecomp.sdc.be.config.BeEcompErrorManager;
97 import org.openecomp.sdc.be.dao.api.ActionStatus;
98 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
99 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
100 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
101 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
102 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
103 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
104 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
105 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
106 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
107 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition;
108 import org.openecomp.sdc.be.datatypes.elements.SubPropertyToscaFunction;
109 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
110 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
111 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
112 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
113 import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
114 import org.openecomp.sdc.be.datatypes.enums.FilterValueType;
115 import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType;
116 import org.openecomp.sdc.be.model.CapabilityDefinition;
117 import org.openecomp.sdc.be.model.Component;
118 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
119 import org.openecomp.sdc.be.model.GroupDefinition;
120 import org.openecomp.sdc.be.model.GroupTypeDefinition;
121 import org.openecomp.sdc.be.model.InputDefinition;
122 import org.openecomp.sdc.be.model.NodeTypeInfo;
123 import org.openecomp.sdc.be.model.OutputDefinition;
124 import org.openecomp.sdc.be.model.ParsedToscaYamlInfo;
125 import org.openecomp.sdc.be.model.PolicyDefinition;
126 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
127 import org.openecomp.sdc.be.model.PropertyDefinition;
128 import org.openecomp.sdc.be.model.Resource;
129 import org.openecomp.sdc.be.model.UploadArtifactInfo;
130 import org.openecomp.sdc.be.model.UploadAttributeInfo;
131 import org.openecomp.sdc.be.model.UploadCapInfo;
132 import org.openecomp.sdc.be.model.UploadComponentInstanceInfo;
133 import org.openecomp.sdc.be.model.UploadInterfaceInfo;
134 import org.openecomp.sdc.be.model.UploadPropInfo;
135 import org.openecomp.sdc.be.model.UploadReqInfo;
136 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
137 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
138 import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil;
139 import org.openecomp.sdc.be.ui.model.OperationUi;
140 import org.openecomp.sdc.be.ui.model.PropertyAssignmentUi;
141 import org.openecomp.sdc.be.utils.PropertyFilterConstraintDataDefinitionHelper;
142 import org.openecomp.sdc.be.utils.TypeUtils;
143 import org.openecomp.sdc.common.log.wrappers.Logger;
144 import org.yaml.snakeyaml.parser.ParserException;
145
146 /**
147  * A handler class designed to parse the YAML file of the service template for a JAVA object
148  */
149 @org.springframework.stereotype.Component
150 public class YamlTemplateParsingHandler {
151
152     private static final int SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX = 0;
153     private static final int SUB_MAPPING_CAPABILITY_NAME_IDX = 1;
154     private static final Logger log = Logger.getLogger(YamlTemplateParsingHandler.class);
155     private final Gson gson = new Gson();
156     private final JanusGraphDao janusGraphDao;
157     private final GroupTypeBusinessLogic groupTypeBusinessLogic;
158     private final AnnotationBusinessLogic annotationBusinessLogic;
159     private final PolicyTypeBusinessLogic policyTypeBusinessLogic;
160     private final ServiceBusinessLogic serviceBusinessLogic;
161     private final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler;
162
163     public YamlTemplateParsingHandler(JanusGraphDao janusGraphDao,
164                                       GroupTypeBusinessLogic groupTypeBusinessLogic,
165                                       AnnotationBusinessLogic annotationBusinessLogic,
166                                       PolicyTypeBusinessLogic policyTypeBusinessLogic,
167                                       ServiceBusinessLogic serviceBusinessLogic,
168                                       final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler
169     ) {
170         this.janusGraphDao = janusGraphDao;
171         this.groupTypeBusinessLogic = groupTypeBusinessLogic;
172         this.annotationBusinessLogic = annotationBusinessLogic;
173         this.policyTypeBusinessLogic = policyTypeBusinessLogic;
174         this.serviceBusinessLogic = serviceBusinessLogic;
175         this.toscaFunctionYamlParsingHandler = toscaFunctionYamlParsingHandler;
176     }
177
178     public ParsedToscaYamlInfo parseResourceInfoFromYAML(String fileName, String resourceYml, Map<String, String> createdNodesToscaResourceNames,
179                                                          Map<String, NodeTypeInfo> nodeTypesInfo, String nodeName,
180                                                          Component component, String interfaceTemplateYaml) {
181         log.debug("#parseResourceInfoFromYAML - Going to parse yaml {} ", fileName);
182         Map<String, Object> mappedToscaTemplate = getMappedToscaTemplate(fileName, resourceYml, nodeTypesInfo, nodeName);
183         ParsedToscaYamlInfo parsedToscaYamlInfo = new ParsedToscaYamlInfo();
184         Map<String, Object> mappedTopologyTemplate = (Map<String, Object>) findToscaElement(mappedToscaTemplate, TOPOLOGY_TEMPLATE,
185             ToscaElementTypeEnum.ALL).left().on(err -> failIfNotTopologyTemplate(fileName));
186         final Map<String, Object> mappedTopologyTemplateInputs = mappedTopologyTemplate.entrySet().stream()
187             .filter(entry -> entry.getKey().equals(INPUTS.getElementName())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
188         final Map<String, Object> mappedTopologyTemplateOutputs = mappedTopologyTemplate.entrySet().stream()
189             .filter(entry -> entry.getKey().equals(OUTPUTS.getElementName())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
190         parsedToscaYamlInfo.setInputs(getInputs(mappedTopologyTemplateInputs));
191         parsedToscaYamlInfo.setOutputs(getOutputs(mappedTopologyTemplateOutputs));
192         parsedToscaYamlInfo.setInstances(getInstances(
193             mappedToscaTemplate,
194             createdNodesToscaResourceNames
195         ));
196         associateRelationshipTemplatesToInstances(parsedToscaYamlInfo.getInstances(), mappedTopologyTemplate);
197         parsedToscaYamlInfo.setGroups(getGroups(mappedToscaTemplate, component.getModel()));
198         parsedToscaYamlInfo.setPolicies(getPolicies(mappedToscaTemplate, component.getModel()));
199         Map<String, Object> substitutionMappings = getSubstitutionMappings(mappedToscaTemplate);
200         if (substitutionMappings != null) {
201             if (component.isService()) {
202                 if (interfaceTemplateYaml.isEmpty()) {
203                     component.setDerivedFromGenericType((String) substitutionMappings.get(NODE_TYPE.getElementName()));
204                     List<PropertyDefinition> properties = serviceBusinessLogic.fetchDerivedFromGenericType(component, null).getProperties();
205                     parsedToscaYamlInfo.setProperties(properties.stream().collect(Collectors.toMap(PropertyDefinition::getName, prop -> prop)));
206                 } else {
207                     parsedToscaYamlInfo.setProperties(getProperties(loadYamlAsStrictMap(interfaceTemplateYaml)));
208                 }
209                 parsedToscaYamlInfo.setSubstitutionFilterProperties(getSubstitutionFilterProperties(mappedToscaTemplate));
210             }
211             if (substitutionMappings.get("properties") != null) {
212                 parsedToscaYamlInfo.setSubstitutionMappingProperties((Map<String, List<String>>) substitutionMappings.get("properties"));
213             }
214             parsedToscaYamlInfo.setSubstitutionMappingNodeType((String) substitutionMappings.get(NODE_TYPE.getElementName()));
215         }
216         log.debug("#parseResourceInfoFromYAML - The yaml {} has been parsed ", fileName);
217         return parsedToscaYamlInfo;
218     }
219
220     private Map<String, Object> getMappedToscaTemplate(String fileName, String resourceYml, Map<String, NodeTypeInfo> nodeTypesInfo,
221                                                        String nodeName) {
222         Map<String, Object> mappedToscaTemplate;
223         if (isNodeExist(nodeTypesInfo, nodeName)) {
224             mappedToscaTemplate = nodeTypesInfo.get(nodeName).getMappedToscaTemplate();
225         } else {
226             mappedToscaTemplate = loadYaml(fileName, resourceYml);
227         }
228         return mappedToscaTemplate;
229     }
230
231     private Map<String, Object> loadYaml(String fileName, String resourceYml) {
232         Map<String, Object> mappedToscaTemplate = null;
233         try {
234             mappedToscaTemplate = loadYamlAsStrictMap(resourceYml);
235         } catch (ParserException e) {
236             log.debug("#getMappedToscaTemplate - Failed to load YAML file {}", fileName, e);
237             rollbackWithException(ActionStatus.TOSCA_PARSE_ERROR, fileName, e.getMessage());
238         }
239         return mappedToscaTemplate;
240     }
241
242     private boolean isNodeExist(Map<String, NodeTypeInfo> nodeTypesInfo, String nodeName) {
243         return nodeTypesInfo != null && nodeName != null && nodeTypesInfo.containsKey(nodeName);
244     }
245
246     private Map<String, InputDefinition> getInputs(Map<String, Object> toscaJson) {
247         Map<String, InputDefinition> inputs = ImportUtils.getInputs(toscaJson, annotationBusinessLogic.getAnnotationTypeOperations()).left()
248             .on(err -> new HashMap<>());
249         annotationBusinessLogic.validateAndMergeAnnotationsAndAssignToInput(inputs);
250         return inputs;
251     }
252
253     private Map<String, OutputDefinition> getOutputs(Map<String, Object> toscaJson) {
254         return ImportUtils.getOutputs(toscaJson).left().on(err -> new HashMap<>());
255     }
256
257     private Map<String, PropertyDefinition> getProperties(Map<String, Object> toscaJson) {
258         return ImportUtils.getProperties(toscaJson).left().on(err -> new HashMap<>());
259     }
260
261     private ListDataDefinition<SubstitutionFilterPropertyDataDefinition> getSubstitutionFilterProperties(final Map<String, Object> toscaJson) {
262         final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> propertyList = new ListDataDefinition<>();
263         final Map<String, Object> substitutionFilters = findFirstToscaMapElement(toscaJson, SUBSTITUTION_FILTERS).left().on(err -> new HashMap<>());
264         if (MapUtils.isEmpty(substitutionFilters)) {
265             return propertyList;
266         }
267         final List<Map<String, Object>> substitutionFilterProperties = (List<Map<String, Object>>) substitutionFilters.get("properties");
268         if (CollectionUtils.isEmpty(substitutionFilterProperties)) {
269             return propertyList;
270         }
271         for (final Map<String, Object> filterProps : substitutionFilterProperties) {
272             for (final Map.Entry<String, Object> propertyFilterEntry : filterProps.entrySet()) {
273                 final String propertyName = propertyFilterEntry.getKey();
274                 final Object value = propertyFilterEntry.getValue();
275                 if (value instanceof List) {
276                     final List<Map<String, Object>> propertyFilterEntryValue = (List<Map<String, Object>>) value;
277                     for (final Map<String, Object> filterValueMap : propertyFilterEntryValue) {
278                         final var substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition();
279                         substitutionFilterPropertyDataDefinition.setName(propertyName);
280                         substitutionFilterPropertyDataDefinition.setConstraints(createSubstitutionFilterConstraints(propertyName, filterValueMap));
281                         propertyList.add(substitutionFilterPropertyDataDefinition);
282                     }
283                 } else if (value instanceof Map) {
284                     final Map<String, Object> filterValueMap = (Map<String, Object>) value;
285                     final var substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition();
286                     substitutionFilterPropertyDataDefinition.setName(propertyName);
287                     substitutionFilterPropertyDataDefinition.setConstraints(createSubstitutionFilterConstraints(propertyName, filterValueMap));
288                     propertyList.add(substitutionFilterPropertyDataDefinition);
289                 }
290             }
291         }
292         return propertyList;
293     }
294
295     private List<PropertyFilterConstraintDataDefinition> createSubstitutionFilterConstraints(final String name, final Map<String, Object> value) {
296         final List<PropertyFilterConstraintDataDefinition> constraints = new ArrayList<>();
297         for (final Map.Entry<String, Object> valueEntry : value.entrySet()) {
298             final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition();
299             propertyFilterConstraint.setPropertyName(name);
300             propertyFilterConstraint.setOperator(ConstraintType.findByType(valueEntry.getKey()).orElse(null));
301             propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY);
302             final Optional<ToscaFunction> toscaFunction = PropertyFilterConstraintDataDefinitionHelper
303                 .createToscaFunctionFromLegacyConstraintValue(valueEntry.getValue());
304             if (toscaFunction.isPresent()) {
305                 final ToscaFunction toscaFunction1 = toscaFunction.get();
306                 propertyFilterConstraint.setValue(toscaFunction1);
307                 propertyFilterConstraint.setValueType(
308                     PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(toscaFunction1.getType()).orElse(null)
309                 );
310             } else {
311                 propertyFilterConstraint.setValue(valueEntry.getValue());
312                 propertyFilterConstraint.setValueType(FilterValueType.STATIC);
313             }
314             constraints.add(propertyFilterConstraint);
315         }
316
317         return constraints;
318     }
319
320     private Map<String, PolicyDefinition> getPolicies(Map<String, Object> toscaJson, String model) {
321         Map<String, Object> mappedTopologyTemplate = (Map<String, Object>) findToscaElement(toscaJson, TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL)
322             .left().on(err -> new HashMap<>());
323         Map<String, Object> foundPolicies = (Map<String, Object>) mappedTopologyTemplate.get(POLICIES.getElementName());
324         if (MapUtils.isNotEmpty(foundPolicies)) {
325             return foundPolicies.entrySet().stream().map(policyToCreate -> createPolicy(policyToCreate, model))
326                 .collect(Collectors.toMap(PolicyDefinition::getName, p -> p));
327         }
328         return Collections.emptyMap();
329     }
330
331     private PolicyDefinition createPolicy(Map.Entry<String, Object> policyNameValue, String model) {
332         PolicyDefinition emptyPolicyDef = new PolicyDefinition();
333         String policyName = policyNameValue.getKey();
334         emptyPolicyDef.setName(policyName);
335         try {
336             // There's no need to null test in conjunction with an instanceof test. null is not an instanceof anything, so a null check is redundant.
337             if (policyNameValue.getValue() instanceof Map) {
338                 Map<String, Object> policyTemplateJsonMap = (Map<String, Object>) policyNameValue.getValue();
339                 validateAndFillPolicy(emptyPolicyDef, policyTemplateJsonMap, model);
340             } else {
341                 rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
342             }
343         } catch (ClassCastException e) {
344             log.debug("#createPolicy - Failed to create the policy {}. The exception occurred", policyName, e);
345             rollbackWithException(ActionStatus.INVALID_YAML);
346         }
347         return emptyPolicyDef;
348     }
349
350     private void validateAndFillPolicy(PolicyDefinition emptyPolicyDefinition, Map<String, Object> policyTemplateJsonMap, String model) {
351         String policyTypeName = (String) policyTemplateJsonMap.get(TYPE.getElementName());
352         if (StringUtils.isEmpty(policyTypeName)) {
353             log.debug("#validateAndFillPolicy - The 'type' member is not found under policy {}", emptyPolicyDefinition.getName());
354             rollbackWithException(ActionStatus.POLICY_MISSING_POLICY_TYPE, emptyPolicyDefinition.getName());
355         }
356         emptyPolicyDefinition.setType(policyTypeName);
357         // set policy targets
358         emptyPolicyDefinition.setTargets(validateFillPolicyTargets(policyTemplateJsonMap));
359         PolicyTypeDefinition policyTypeDefinition = validateGetPolicyTypeDefinition(policyTypeName, model);
360         // set policy properties
361         emptyPolicyDefinition.setProperties(validateFillPolicyProperties(policyTypeDefinition, policyTemplateJsonMap));
362     }
363
364     private PolicyTypeDefinition validateGetPolicyTypeDefinition(String policyType, String modelName) {
365         PolicyTypeDefinition policyTypeDefinition = policyTypeBusinessLogic.getLatestPolicyTypeByType(policyType, modelName);
366         if (policyTypeDefinition == null) {
367             log.debug("#validateAndFillPolicy - The policy type {} not found", policyType);
368             rollbackWithException(ActionStatus.POLICY_TYPE_IS_INVALID, policyType);
369         }
370         return policyTypeDefinition;
371     }
372
373     private List<PropertyDataDefinition> validateFillPolicyProperties(final PolicyTypeDefinition policyTypeDefinition,
374                                                                       final Map<String, Object> policyTemplateJsonMap) {
375         if (policyTypeDefinition == null || CollectionUtils.isEmpty(policyTypeDefinition.getProperties())
376             || MapUtils.isEmpty(policyTemplateJsonMap)) {
377             return Collections.emptyList();
378         }
379         final Map<String, Object> propertiesJsonMap = (Map<String, Object>) policyTemplateJsonMap.get(PROPERTIES.getElementName());
380         if (MapUtils.isEmpty(propertiesJsonMap)) {
381             return Collections.emptyList();
382         }
383         return propertiesJsonMap.entrySet().stream()
384             .map(propertyJson -> {
385                 final PropertyDefinition originalProperty =
386                     policyTypeDefinition.getProperties().stream()
387                         .filter(propertyDefinition -> propertyDefinition.getName().equals(propertyJson.getKey()))
388                         .findFirst()
389                         .orElse(null);
390                 if (originalProperty == null) {
391                     return null;
392                 }
393                 final UploadPropInfo uploadPropInfo = buildProperty(propertyJson.getKey(), propertyJson.getValue());
394                 final PropertyDefinition propertyDefinition = new PropertyDefinition(originalProperty);
395                 propertyDefinition.setToscaFunction(uploadPropInfo.getToscaFunction());
396                 propertyDefinition.setSubPropertyToscaFunctions(uploadPropInfo.getSubPropertyToscaFunctions());
397                 propertyDefinition.setGetInputValues(uploadPropInfo.getGet_input());
398                 propertyDefinition.setDescription(uploadPropInfo.getDescription());
399                 String propertyValue = gson.toJson(uploadPropInfo.getValue());
400                 if (!propertyDefinition.isToscaFunction()) {
401                     propertyValue = PropertiesUtils.trimQuotes(propertyValue);
402                 }
403                 propertyDefinition.setValue(propertyValue);
404                 return propertyDefinition;
405             })
406             .filter(Objects::nonNull)
407             .collect(Collectors.toList());
408     }
409
410     private Map<PolicyTargetType, List<String>> validateFillPolicyTargets(Map<String, Object> policyTemplateJson) {
411         Map<PolicyTargetType, List<String>> targets = new EnumMap<>(PolicyTargetType.class);
412         if (policyTemplateJson.containsKey(TARGETS.getElementName()) && policyTemplateJson.get(TARGETS.getElementName()) instanceof List) {
413             List<String> targetsElement = (List<String>) policyTemplateJson.get(TARGETS.getElementName());
414             targets.put(PolicyTargetType.COMPONENT_INSTANCES, targetsElement);
415         }
416         return targets;
417     }
418
419     private Map<String, UploadComponentInstanceInfo> getInstances(
420         Map<String, Object> toscaJson,
421         Map<String, String> createdNodesToscaResourceNames
422     ) {
423         Map<String, Object> nodeTemplates = findFirstToscaMapElement(toscaJson, NODE_TEMPLATES)
424             .left().on(err -> new HashMap<>());
425         if (nodeTemplates.isEmpty()) {
426             return Collections.emptyMap();
427         }
428         return getInstances(
429             toscaJson,
430             createdNodesToscaResourceNames,
431             nodeTemplates
432         );
433     }
434
435     private Map<String, UploadComponentInstanceInfo> getInstances(
436         Map<String, Object> toscaJson,
437         Map<String, String> createdNodesToscaResourceNames,
438         Map<String, Object> nodeTemplates
439     ) {
440         Map<String, Object> substitutionMappings = getSubstitutionMappings(toscaJson);
441         return nodeTemplates.entrySet().stream()
442             .map(node -> buildModuleComponentInstanceInfo(
443                 node,
444                 substitutionMappings,
445                 createdNodesToscaResourceNames
446             ))
447             .collect(Collectors.toMap(UploadComponentInstanceInfo::getName, i -> i));
448     }
449
450     private Map<String, Object> getSubstitutionMappings(Map<String, Object> toscaJson) {
451         Either<Map<String, Object>, ResultStatusEnum> eitherSubstitutionMappings = findFirstToscaMapElement(toscaJson, SUBSTITUTION_MAPPINGS);
452         if (eitherSubstitutionMappings.isLeft()) {
453             return eitherSubstitutionMappings.left().value();
454         }
455         return null;
456     }
457
458     private void associateRelationshipTemplatesToInstances(final Map<String, UploadComponentInstanceInfo> instances,
459                                                            final Map<String, Object> toscaJson) {
460         if (MapUtils.isEmpty(instances)) {
461             return;
462         }
463         for (UploadComponentInstanceInfo instance : instances.values()) {
464             final Map<String, List<OperationUi>> operations = new HashMap<>();
465             final Map<String, List<UploadReqInfo>> requirements = instance.getRequirements();
466             if (MapUtils.isNotEmpty(requirements)) {
467                 requirements.values()
468                     .forEach(requirementInfoList -> requirementInfoList.stream()
469                         .filter(requirement -> StringUtils.isNotEmpty(requirement.getRelationshipTemplate()))
470                         .forEach(requirement -> operations.put(requirement.getRelationshipTemplate(),
471                             getOperationsFromRelationshipTemplate(toscaJson, requirement.getRelationshipTemplate()))));
472             }
473             instance.setOperations(operations);
474         }
475     }
476
477     private Map<String, Object> getRelationshipTemplates(final Map<String, Object> toscaJson, final String relationshipTemplate) {
478         final Either<Map<String, Object>, ResultStatusEnum> eitherRelationshipTemplates = findFirstToscaMapElement(toscaJson, RELATIONSHIP_TEMPLATES);
479         if (eitherRelationshipTemplates.isRight()) {
480             throw new ByActionStatusComponentException(ActionStatus.RELATIONSHIP_TEMPLATE_NOT_FOUND);
481         }
482         final Map<String, Object> relationshipTemplateMap = eitherRelationshipTemplates.left().value();
483         final Map<String, Map<String, Object>> relationship = (Map<String, Map<String, Object>>) relationshipTemplateMap.get(relationshipTemplate);
484         if (relationship == null) {
485             throw new ByActionStatusComponentException(ActionStatus.RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND);
486         }
487         return relationship.get(INTERFACES.getElementName());
488     }
489
490     private List<ToscaInterfaceDefinition> buildToscaInterfacesFromRelationship(final Map<String, Object> interfaces) {
491         return interfaces.entrySet().stream()
492             .map(entry -> {
493                 final var toscaInterfaceDefinition = new ToscaInterfaceDefinition();
494                 toscaInterfaceDefinition.setType(entry.getKey());
495                 final Map<String, Object> toscaInterfaceMap = (Map<String, Object>) entry.getValue();
496                 toscaInterfaceDefinition.setOperations((Map<String, Object>) toscaInterfaceMap.get(OPERATIONS.getElementName()));
497                 return toscaInterfaceDefinition;
498             })
499             .collect(toList());
500     }
501
502     private Optional<Object> getImplementation(final Map<String, Object> operationToscaMap) {
503         if (MapUtils.isEmpty(operationToscaMap) || !operationToscaMap.containsKey(IMPLEMENTATION.getElementName())) {
504             return Optional.empty();
505         }
506         return Optional.ofNullable(operationToscaMap.get(IMPLEMENTATION.getElementName()));
507     }
508
509     private List<PropertyAssignmentUi> getOperationsInputs(final Map<String, Object> operationToscaMap) {
510         if (MapUtils.isEmpty(operationToscaMap) || !operationToscaMap.containsKey(INPUTS.getElementName())) {
511             return Collections.emptyList();
512         }
513         final Map<String, Object> inputsMap = (Map<String, Object>) operationToscaMap.get(INPUTS.getElementName());
514         return inputsMap.entrySet().stream().map(this::buildInputAssignment).collect(toList());
515     }
516
517     private PropertyAssignmentUi buildInputAssignment(final Entry<String, Object> inputAssignmentMap) {
518         var propertyAssignmentUi = new PropertyAssignmentUi();
519         propertyAssignmentUi.setName(inputAssignmentMap.getKey());
520         propertyAssignmentUi.setValue(inputAssignmentMap.getValue().toString());
521         propertyAssignmentUi.setType(STRING.getType());
522         return propertyAssignmentUi;
523     }
524
525     private List<OperationUi> getOperationsFromRelationshipTemplate(final Map<String, Object> toscaJson, final String relationshipTemplate) {
526         final List<OperationUi> operationUiList = new ArrayList<>();
527         final List<ToscaInterfaceDefinition> interfaces =
528             buildToscaInterfacesFromRelationship(getRelationshipTemplates(toscaJson, relationshipTemplate));
529         interfaces.stream()
530             .filter(interfaceDefinition -> MapUtils.isNotEmpty(interfaceDefinition.getOperations()))
531             .forEach(interfaceDefinition ->
532                 interfaceDefinition.getOperations()
533                     .forEach((operationType, operationValue) ->
534                         operationUiList.add(buildOperation(interfaceDefinition.getType(), operationType, (Map<String, Object>) operationValue))
535                     ));
536         return operationUiList;
537     }
538
539     private OperationUi buildOperation(final String interfaceType, final String operationType, final Map<String, Object> operationToscaMap) {
540         var operationUi = new OperationUi();
541         operationUi.setInterfaceType(interfaceType);
542         operationUi.setOperationType(operationType);
543         getImplementation(operationToscaMap).ifPresent(operationUi::setImplementation);
544         final List<PropertyAssignmentUi> operationsInputs = getOperationsInputs(operationToscaMap);
545         if (CollectionUtils.isNotEmpty(operationsInputs)) {
546             operationUi.setInputs(operationsInputs);
547         }
548         return operationUi;
549     }
550
551     @SuppressWarnings("unchecked")
552     private Map<String, GroupDefinition> getGroups(Map<String, Object> toscaJson, String model) {
553         Map<String, Object> mappedTopologyTemplate = (Map<String, Object>) findToscaElement(toscaJson, TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL)
554             .left().on(err -> new HashMap<>());
555         Map<String, Object> foundGroups = (Map<String, Object>) mappedTopologyTemplate.get(GROUPS.getElementName());
556         if (MapUtils.isNotEmpty(foundGroups)) {
557             Map<String, GroupDefinition> groups = foundGroups.entrySet().stream().map(groupToCreate -> createGroup(groupToCreate, model))
558                 .collect(Collectors.toMap(GroupDefinition::getName, g -> g));
559             Map<String, Object> substitutionMappings = getSubstitutionMappings(toscaJson);
560             if (capabilitiesSubstitutionMappingsExist(substitutionMappings)) {
561                 groups.forEach((key, value) -> updateCapabilitiesNames(value,
562                     getNamesToUpdate(key, (Map<String, List<String>>) substitutionMappings.get(CAPABILITIES.getElementName()))));
563             }
564             return groups;
565         }
566         return new HashMap<>();
567     }
568
569     private void updateCapabilitiesNames(GroupDefinition group, Map<String, String> capabilityNames) {
570         if (MapUtils.isNotEmpty(group.getCapabilities())) {
571             group.getCapabilities().values().stream().flatMap(Collection::stream).filter(cap -> capabilityNames.containsKey(cap.getName()))
572                 .forEach(cap -> cap.setName(capabilityNames.get(cap.getName())));
573         }
574     }
575
576     private Map<String, String> getNamesToUpdate(String name, Map<String, List<String>> pair) {
577         return pair.entrySet().stream().filter(e -> e.getValue().get(SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX).equalsIgnoreCase(name))
578             .collect(Collectors.toMap(e -> e.getValue().get(SUB_MAPPING_CAPABILITY_NAME_IDX), Map.Entry::getKey, (n1, n2) -> n1));
579     }
580
581     private boolean capabilitiesSubstitutionMappingsExist(Map<String, Object> substitutionMappings) {
582         return substitutionMappings != null && substitutionMappings.containsKey(CAPABILITIES.getElementName());
583     }
584
585     private GroupDefinition createGroup(Map.Entry<String, Object> groupNameValue, String model) {
586         GroupDefinition group = new GroupDefinition();
587         group.setName(groupNameValue.getKey());
588         try {
589             if (groupNameValue.getValue() instanceof Map) {
590                 Map<String, Object> groupTemplateJsonMap = (Map<String, Object>) groupNameValue.getValue();
591                 validateAndFillGroup(group, groupTemplateJsonMap, model);
592                 validateUpdateGroupProperties(group, groupTemplateJsonMap);
593                 validateUpdateGroupCapabilities(group, groupTemplateJsonMap);
594             } else {
595                 rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
596             }
597         } catch (ClassCastException e) {
598             log.debug("#createGroup - Failed to create the group {}. The exception occurres", groupNameValue.getKey(), e);
599             rollbackWithException(ActionStatus.INVALID_YAML);
600         }
601         return group;
602     }
603
604     private Map<String, CapabilityDefinition> addCapabilities(Map<String, CapabilityDefinition> cap, Map<String, CapabilityDefinition> otherCap) {
605         cap.putAll(otherCap);
606         return cap;
607     }
608
609     private Map<String, CapabilityDefinition> addCapability(CapabilityDefinition cap) {
610         Map<String, CapabilityDefinition> map = Maps.newHashMap();
611         map.put(cap.getName(), cap);
612         return map;
613     }
614
615     private void setMembers(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
616         if (groupTemplateJsonMap.containsKey(MEMBERS.getElementName())) {
617             Object members = groupTemplateJsonMap.get(MEMBERS.getElementName());
618             if (members != null) {
619                 if (members instanceof List) {
620                     setMembersFromList(groupInfo, (List<?>) members);
621                 } else {
622                     log.debug("The 'members' member is not of type list under group {}", groupInfo.getName());
623                     rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
624                 }
625             }
626         }
627     }
628
629     private void setMembersFromList(GroupDefinition groupInfo, List<?> membersAsList) {
630         groupInfo.setMembers(membersAsList.stream().collect(Collectors.toMap(Object::toString, member -> "")));
631     }
632
633     @SuppressWarnings("unchecked")
634     private void validateUpdateGroupProperties(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
635         if (groupTemplateJsonMap.containsKey(PROPERTIES.getElementName())) {
636             Object propertiesElement = groupTemplateJsonMap.get(PROPERTIES.getElementName());
637             if (propertiesElement instanceof Map) {
638                 mergeGroupProperties(groupInfo, (Map<String, Object>) propertiesElement);
639             }
640         }
641     }
642
643     private void mergeGroupProperties(final GroupDefinition groupDefinition, final Map<String, Object> parsedProperties) {
644         if (CollectionUtils.isEmpty(groupDefinition.getProperties())) {
645             return;
646         }
647         validateGroupProperties(parsedProperties, groupDefinition);
648         groupDefinition.getProperties().stream()
649             .filter(property -> parsedProperties.containsKey(property.getName()))
650             .forEach(property -> mergeGroupProperty(property, parsedProperties.get(property.getName())));
651     }
652
653     private void mergeGroupProperty(final PropertyDataDefinition property, final Object propertyYaml) {
654         final UploadPropInfo uploadPropInfo = buildProperty(property.getName(), propertyYaml);
655         property.setToscaFunction(uploadPropInfo.getToscaFunction());
656         property.setSubPropertyToscaFunctions(uploadPropInfo.getSubPropertyToscaFunctions());
657         property.setValue(convertPropertyValue(ToscaPropertyType.isValidType(property.getType()), uploadPropInfo.getValue()));
658         property.setGetInputValues(uploadPropInfo.getGet_input());
659     }
660
661     private String convertPropertyValue(ToscaPropertyType type, Object value) {
662         String convertedValue = null;
663         if (value != null) {
664             if (type == null || value instanceof Map || value instanceof List) {
665                 convertedValue = gson.toJson(value);
666             } else {
667                 convertedValue = value.toString();
668             }
669         }
670         return convertedValue;
671     }
672
673     private void setDescription(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
674         if (groupTemplateJsonMap.containsKey(DESCRIPTION.getElementName())) {
675             groupInfo.setDescription((String) groupTemplateJsonMap.get(DESCRIPTION.getElementName()));
676         }
677     }
678
679     private void validateAndFillGroup(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap, String model) {
680         String type = (String) groupTemplateJsonMap.get(TYPE.getElementName());
681         if (StringUtils.isEmpty(type)) {
682             log.debug("#validateAndFillGroup - The 'type' member is not found under group {}", groupInfo.getName());
683             rollbackWithException(ActionStatus.GROUP_MISSING_GROUP_TYPE, groupInfo.getName());
684         }
685         groupInfo.setType(type);
686         GroupTypeDefinition groupType = groupTypeBusinessLogic.getLatestGroupTypeByType(type, model);
687         if (groupType == null) {
688             log.debug("#validateAndFillGroup - The group type {} not found", groupInfo.getName());
689             rollbackWithException(ActionStatus.GROUP_TYPE_IS_INVALID, type);
690         }
691         groupInfo.convertFromGroupProperties(groupType.getProperties());
692         groupInfo.convertCapabilityDefinitions(groupType.getCapabilities());
693         setDescription(groupInfo, groupTemplateJsonMap);
694         setMembers(groupInfo, groupTemplateJsonMap);
695     }
696
697     @SuppressWarnings("unchecked")
698     private void validateUpdateGroupCapabilities(GroupDefinition groupInfo, Map<String, Object> groupTemplateJsonMap) {
699         if (groupTemplateJsonMap.containsKey(CAPABILITIES.getElementName())) {
700             Object capabilities = groupTemplateJsonMap.get(CAPABILITIES.getElementName());
701             if (capabilities instanceof List) {
702                 validateUpdateCapabilities(groupInfo, ((List<Object>) capabilities).stream().map(o -> buildGroupCapability(groupInfo, o))
703                     .collect(Collectors.toMap(CapabilityDefinition::getType, this::addCapability, this::addCapabilities)));
704             } else if (capabilities instanceof Map) {
705                 validateUpdateCapabilities(groupInfo,
706                     ((Map<String, Object>) capabilities).entrySet().stream().map(e -> buildGroupCapability(groupInfo, e))
707                         .collect(Collectors.toMap(CapabilityDefinition::getType, this::addCapability, this::addCapabilities)));
708             } else {
709                 log.debug("#setCapabilities - Failed to import the capabilities of the group {}. ", groupInfo.getName());
710                 rollbackWithException(ActionStatus.INVALID_YAML);
711             }
712         }
713     }
714
715     private void validateUpdateCapabilities(GroupDefinition groupInfo, Map<String, Map<String, CapabilityDefinition>> capabilityInfo) {
716         validateGroupCapabilities(groupInfo, capabilityInfo);
717         groupInfo.updateCapabilitiesProperties(capabilityInfo);
718     }
719
720     private void validateGroupCapabilities(GroupDefinition group, Map<String, Map<String, CapabilityDefinition>> parsedCapabilities) {
721         if (MapUtils.isNotEmpty(parsedCapabilities)) {
722             if (MapUtils.isEmpty(group.getCapabilities())) {
723                 failOnMissingCapabilityTypes(group, Lists.newArrayList(parsedCapabilities.keySet()));
724             }
725             List<String> missingCapTypes = parsedCapabilities.keySet().stream().filter(ct -> !group.getCapabilities().containsKey(ct))
726                 .collect(toList());
727             if (CollectionUtils.isNotEmpty(missingCapTypes)) {
728                 failOnMissingCapabilityTypes(group, missingCapTypes);
729             }
730             group.getCapabilities().entrySet().forEach(e -> validateCapabilities(group, e.getValue(), parsedCapabilities.get(e.getKey())));
731         }
732     }
733
734     private void validateCapabilities(GroupDefinition group, List<CapabilityDefinition> capabilities,
735                                       Map<String, CapabilityDefinition> parsedCapabilities) {
736         List<String> allowedCapNames = capabilities.stream().map(CapabilityDefinition::getName).distinct().collect(toList());
737         List<String> missingCapNames = parsedCapabilities.keySet().stream().filter(c -> !allowedCapNames.contains(c)).collect(toList());
738         if (CollectionUtils.isNotEmpty(missingCapNames)) {
739             failOnMissingCapabilityNames(group, missingCapNames);
740         }
741         validateCapabilitiesProperties(capabilities, parsedCapabilities);
742     }
743
744     private void validateCapabilitiesProperties(List<CapabilityDefinition> capabilities, Map<String, CapabilityDefinition> parsedCapabilities) {
745         capabilities.forEach(c -> validateCapabilityProperties(c, parsedCapabilities.get(c.getName())));
746     }
747
748     private void validateCapabilityProperties(CapabilityDefinition capability, CapabilityDefinition parsedCapability) {
749         if (parsedCapability != null && parsedCapability.getProperties() != null) {
750             List<String> parsedPropertiesNames = parsedCapability.getProperties().stream().map(ComponentInstanceProperty::getName).collect(toList());
751             validateProperties(capability.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames,
752                 ActionStatus.PROPERTY_NOT_FOUND, capability.getName(), capability.getType());
753         }
754     }
755
756     private void validateGroupProperties(Map<String, Object> parsedProperties, GroupDefinition groupInfo) {
757         List<String> parsedPropertiesNames = new ArrayList<>(parsedProperties.keySet());
758         validateProperties(groupInfo.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames,
759             ActionStatus.GROUP_PROPERTY_NOT_FOUND, groupInfo.getName(), groupInfo.getType());
760     }
761
762     private void validateProperties(List<String> validProperties, List<String> parsedProperties, ActionStatus actionStatus, String name,
763                                     String type) {
764         if (CollectionUtils.isNotEmpty(parsedProperties)) {
765             verifyMissingProperties(actionStatus, name, type, parsedProperties.stream().filter(n -> !validProperties.contains(n)).collect(toList()));
766         }
767     }
768
769     private void verifyMissingProperties(ActionStatus actionStatus, String name, String type, List<String> missingProperties) {
770         if (CollectionUtils.isNotEmpty(missingProperties)) {
771             if (log.isDebugEnabled()) {
772                 log.debug("#validateProperties - Failed to validate properties. The properties {} are missing on {} of the type {}. ",
773                     missingProperties.toString(), name, type);
774             }
775             rollbackWithException(actionStatus, missingProperties.toString(), missingProperties.toString(), name, type);
776         }
777     }
778
779     @SuppressWarnings("unchecked")
780     private CapabilityDefinition buildGroupCapability(GroupDefinition groupInfo, Object capObject) {
781         if (!(capObject instanceof Map)) {
782             log.debug("#convertToGroupCapability - Failed to import the capability {}. ", capObject);
783             rollbackWithException(ActionStatus.INVALID_YAML);
784         }
785         return buildGroupCapability(groupInfo, ((Map<String, Object>) capObject).entrySet().iterator().next());
786     }
787
788     @SuppressWarnings("unchecked")
789     private CapabilityDefinition buildGroupCapability(GroupDefinition groupInfo, Map.Entry<String, Object> capEntry) {
790         CapabilityDefinition capability = new CapabilityDefinition();
791         capability.setOwnerType(CapabilityDataDefinition.OwnerType.GROUP);
792         capability.setName(capEntry.getKey());
793         capability.setParentName(capEntry.getKey());
794         capability.setOwnerId(groupInfo.getName());
795         if (!(capEntry.getValue() instanceof Map)) {
796             log.debug("#convertMapEntryToCapabilityDefinition - Failed to import the capability {}. ", capEntry.getKey());
797             rollbackWithException(ActionStatus.INVALID_YAML);
798         }
799         Map<String, Object> capabilityValue = (Map<String, Object>) capEntry.getValue();
800         String type = (String) capabilityValue.get(TYPE.getElementName());
801         if (StringUtils.isEmpty(type)) {
802             log.debug("#convertMapEntryToCapabilityDefinition - Failed to import the capability {}. Missing capability type. ", capEntry.getKey());
803             rollbackWithException(ActionStatus.INVALID_YAML);
804         }
805         capability.setType(type);
806         if (!(capabilityValue.get(PROPERTIES.getElementName()) instanceof Map)) {
807             log.debug("#convertMapEntryToCapabilityDefinition - Failed to import the capability {}. ", capEntry.getKey());
808             rollbackWithException(ActionStatus.INVALID_YAML);
809         }
810         Map<String, Object> properties = (Map<String, Object>) capabilityValue.get(PROPERTIES.getElementName());
811         capability.setProperties(properties.entrySet().stream().map(this::convertToProperty).collect(toList()));
812         return capability;
813     }
814
815     private ComponentInstanceProperty convertToProperty(Map.Entry<String, Object> e) {
816         ComponentInstanceProperty property = new ComponentInstanceProperty();
817         property.setName(e.getKey());
818         property.setValue((String) e.getValue());
819         return property;
820     }
821
822     @SuppressWarnings("unchecked")
823     private UploadComponentInstanceInfo buildModuleComponentInstanceInfo(
824         Map.Entry<String, Object> nodeTemplateJsonEntry,
825         Map<String, Object> substitutionMappings,
826         Map<String, String> createdNodesToscaResourceNames
827     ) {
828         UploadComponentInstanceInfo nodeTemplateInfo = new UploadComponentInstanceInfo();
829         nodeTemplateInfo.setName(nodeTemplateJsonEntry.getKey());
830         try {
831             if (nodeTemplateJsonEntry.getValue() instanceof String) {
832                 String nodeTemplateJsonString = (String) nodeTemplateJsonEntry.getValue();
833                 nodeTemplateInfo.setType(nodeTemplateJsonString);
834             } else if (nodeTemplateJsonEntry.getValue() instanceof Map) {
835                 Map<String, Object> nodeTemplateJsonMap = (Map<String, Object>) nodeTemplateJsonEntry.getValue();
836                 setToscaResourceType(createdNodesToscaResourceNames, nodeTemplateInfo, nodeTemplateJsonMap);
837                 setRequirements(nodeTemplateInfo, nodeTemplateJsonMap);
838                 setCapabilities(nodeTemplateInfo, nodeTemplateJsonMap);
839                 setArtifacts(nodeTemplateInfo, nodeTemplateJsonMap);
840                 updateProperties(nodeTemplateInfo, nodeTemplateJsonMap);
841                 updateAttributes(nodeTemplateInfo, nodeTemplateJsonMap);
842                 updateInterfaces(nodeTemplateInfo, nodeTemplateJsonMap);
843                 setDirectives(nodeTemplateInfo, nodeTemplateJsonMap);
844                 setNodeFilter(nodeTemplateInfo, nodeTemplateJsonMap);
845                 setSubstitutions(substitutionMappings, nodeTemplateInfo);
846                 setOccurrencesAndInstanceCount(nodeTemplateInfo, nodeTemplateJsonMap);
847             } else {
848                 rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
849             }
850         } catch (ClassCastException e) {
851             BeEcompErrorManager.getInstance().logBeSystemError("Import Resource - create capability");
852             log.debug("error when creating capability, message:{}", e.getMessage(), e);
853             rollbackWithException(ActionStatus.INVALID_YAML);
854         }
855         return nodeTemplateInfo;
856     }
857
858     @SuppressWarnings("unchecked")
859     private void setSubstitutions(Map<String, Object> substitutionMappings, UploadComponentInstanceInfo nodeTemplateInfo) {
860         if (substitutionMappings != null) {
861             if (substitutionMappings.containsKey(CAPABILITIES.getElementName())) {
862                 nodeTemplateInfo.setCapabilitiesNamesToUpdate(getNamesToUpdate(nodeTemplateInfo.getName(),
863                     (Map<String, List<String>>) substitutionMappings.get(CAPABILITIES.getElementName())));
864             }
865             if (substitutionMappings.containsKey(REQUIREMENTS.getElementName())) {
866                 nodeTemplateInfo.setRequirementsNamesToUpdate(getNamesToUpdate(nodeTemplateInfo.getName(),
867                     (Map<String, List<String>>) substitutionMappings.get(REQUIREMENTS.getElementName())));
868             }
869         }
870     }
871
872     private void updateProperties(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
873         if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) {
874             Map<String, List<UploadPropInfo>> properties =
875                 buildPropModuleFromYaml((Map<String, Object>) nodeTemplateJsonMap.get(PROPERTIES.getElementName()));
876             if (!properties.isEmpty()) {
877                 nodeTemplateInfo.setProperties(properties);
878             }
879         }
880     }
881
882     private void updateAttributes(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
883         if (nodeTemplateJsonMap.containsKey(ATTRIBUTES.getElementName())) {
884             Map<String, UploadAttributeInfo> attributes = buildAttributeModuleFromYaml(nodeTemplateJsonMap);
885             if (!attributes.isEmpty()) {
886                 nodeTemplateInfo.setAttributes(attributes);
887             }
888         }
889     }
890
891     private void updateInterfaces(
892         UploadComponentInstanceInfo nodeTemplateInfo,
893         Map<String, Object> nodeTemplateJsonMap
894     ) {
895         if (nodeTemplateJsonMap.containsKey(INTERFACES.getElementName())) {
896             Map<String, UploadInterfaceInfo> interfaces = buildInterfacesModuleFromYaml(
897                 nodeTemplateJsonMap
898             );
899             if (!interfaces.isEmpty()) {
900                 nodeTemplateInfo.setInterfaces(interfaces);
901             }
902         }
903     }
904
905     private void setCapabilities(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
906         if (nodeTemplateJsonMap.containsKey(CAPABILITIES.getElementName())) {
907             Map<String, List<UploadCapInfo>> eitherCapRes = createCapModuleFromYaml(nodeTemplateJsonMap);
908             if (!eitherCapRes.isEmpty()) {
909                 nodeTemplateInfo.setCapabilities(eitherCapRes);
910             }
911         }
912     }
913
914     private void setArtifacts(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
915         if (nodeTemplateJsonMap.containsKey(ARTIFACTS.getElementName())) {
916             Map<String, Map<String, UploadArtifactInfo>> eitherArtifactsRes = createArtifactsModuleFromYaml(nodeTemplateJsonMap);
917             if (!eitherArtifactsRes.isEmpty()) {
918                 nodeTemplateInfo.setArtifacts(eitherArtifactsRes);
919             }
920         }
921     }
922
923     private void setRequirements(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
924         if (nodeTemplateJsonMap.containsKey(REQUIREMENTS.getElementName())) {
925             Map<String, List<UploadReqInfo>> regResponse = createReqModuleFromYaml(nodeTemplateJsonMap, nodeTemplateInfo.getName());
926             if (!regResponse.isEmpty()) {
927                 nodeTemplateInfo.setRequirements(regResponse);
928             }
929         }
930     }
931
932     private void setToscaResourceType(Map<String, String> createdNodesToscaResourceNames, UploadComponentInstanceInfo nodeTemplateInfo,
933                                       Map<String, Object> nodeTemplateJsonMap) {
934         if (nodeTemplateJsonMap.containsKey(TYPE.getElementName())) {
935             String toscaResourceType = (String) nodeTemplateJsonMap.get(TYPE.getElementName());
936             if (createdNodesToscaResourceNames.containsKey(toscaResourceType)) {
937                 toscaResourceType = createdNodesToscaResourceNames.get(toscaResourceType);
938             }
939             nodeTemplateInfo.setType(toscaResourceType);
940         }
941     }
942
943     private void setDirectives(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
944         List<String> directives = (List<String>) nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.DIRECTIVES.getElementName());
945         nodeTemplateInfo.setDirectives(directives);
946     }
947
948     private void setNodeFilter(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
949         if (nodeTemplateJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.NODE_FILTER.getElementName())) {
950             nodeTemplateInfo.setUploadNodeFilterInfo(new NodeFilterUploadCreator()
951                 .createNodeFilterData(nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.NODE_FILTER.getElementName())));
952         }
953     }
954
955     @SuppressWarnings("unchecked")
956     private void setOccurrencesAndInstanceCount(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
957         if (nodeTemplateJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName())) {
958             List<Object> occurrences = (List<Object>) nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName());
959             nodeTemplateInfo.setMinOccurrences(occurrences.get(0).toString());
960             nodeTemplateInfo.setMaxOccurrences(occurrences.get(1).toString());
961         }
962         if (nodeTemplateJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.INSTANCE_COUNT.getElementName())) {
963             Object instanceCount = nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.INSTANCE_COUNT.getElementName());
964             if (instanceCount instanceof Map) {
965                 String instanceCountAsString = "{get_input:" + (String)((Map)instanceCount).get("get_input") + "}";
966                 nodeTemplateInfo.setInstanceCount(instanceCountAsString);
967             } else {
968                 nodeTemplateInfo.setInstanceCount(instanceCount.toString());
969             }
970         }
971     }
972
973     @SuppressWarnings("unchecked")
974     private Map<String, List<UploadReqInfo>> createReqModuleFromYaml(Map<String, Object> nodeTemplateJsonMap, String nodeName) {
975         Map<String, List<UploadReqInfo>> moduleRequirements = new HashMap<>();
976         Either<List<Object>, ResultStatusEnum> requirementsListRes = findFirstToscaListElement(nodeTemplateJsonMap, REQUIREMENTS);
977         if (requirementsListRes.isLeft()) {
978             for (Object jsonReqObj : requirementsListRes.left().value()) {
979                 String reqName = ((Map<String, Object>) jsonReqObj).keySet().iterator().next();
980                 Object reqJson = ((Map<String, Object>) jsonReqObj).get(reqName);
981                 addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName, nodeName);
982             }
983         } else {
984             Either<Map<String, Object>, ResultStatusEnum> requirementsMapRes = findFirstToscaMapElement(nodeTemplateJsonMap, REQUIREMENTS);
985             if (requirementsMapRes.isLeft()) {
986                 for (Map.Entry<String, Object> entry : requirementsMapRes.left().value().entrySet()) {
987                     String reqName = entry.getKey();
988                     Object reqJson = entry.getValue();
989                     addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName, nodeName);
990                 }
991             }
992         }
993         return moduleRequirements;
994     }
995
996     private void addModuleNodeTemplateReq(Map<String, List<UploadReqInfo>> moduleRequirements, Object requirementJson, String requirementName,
997                                           String nodeName) {
998         UploadReqInfo requirement = buildModuleNodeTemplateReg(requirementJson, nodeName);
999         requirement.setName(requirementName);
1000         if (moduleRequirements.containsKey(requirementName)) {
1001             moduleRequirements.get(requirementName).add(requirement);
1002         } else {
1003             List<UploadReqInfo> list = new ArrayList<>();
1004             list.add(requirement);
1005             moduleRequirements.put(requirementName, list);
1006         }
1007     }
1008
1009     @SuppressWarnings("unchecked")
1010     private Map<String, Map<String, UploadArtifactInfo>> createArtifactsModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) {
1011         Map<String, Map<String, UploadArtifactInfo>> moduleArtifacts = new HashMap<>();
1012         Either<List<Object>, ResultStatusEnum> artifactsListRes = findFirstToscaListElement(nodeTemplateJsonMap, ARTIFACTS);
1013         if (artifactsListRes.isLeft()) {
1014             for (Object jsonArtifactObj : artifactsListRes.left().value()) {
1015                 String key = ((Map<String, Object>) jsonArtifactObj).keySet().iterator().next();
1016                 Object artifactJson = ((Map<String, Object>) jsonArtifactObj).get(key);
1017                 addModuleNodeTemplateArtifacts(moduleArtifacts, artifactJson, key);
1018             }
1019         } else {
1020             Either<Map<String, Map<String, Object>>, ResultStatusEnum> artifactsMapRes = findFirstToscaMapElement(nodeTemplateJsonMap, ARTIFACTS);
1021             if (artifactsMapRes.isLeft()) {
1022                 for (Map.Entry<String, Map<String, Object>> entry : artifactsMapRes.left().value().entrySet()) {
1023                     String artifactName = entry.getKey();
1024                     Object artifactJson = entry.getValue();
1025                     addModuleNodeTemplateArtifacts(moduleArtifacts, artifactJson, artifactName);
1026                 }
1027             }
1028         }
1029         return moduleArtifacts;
1030     }
1031
1032     private void addModuleNodeTemplateArtifacts(Map<String, Map<String, UploadArtifactInfo>> moduleArtifacts, Object artifactJson,
1033                                                 String artifactName) {
1034         UploadArtifactInfo artifact = buildModuleNodeTemplateArtifact(artifactJson);
1035         artifact.setName(artifactName);
1036         if (moduleArtifacts.containsKey(ARTIFACTS.getElementName())) {
1037             moduleArtifacts.get(ARTIFACTS.getElementName()).put(artifactName, artifact);
1038         } else {
1039             Map<String, UploadArtifactInfo> map = new HashMap<>();
1040             map.put(artifactName, artifact);
1041             moduleArtifacts.put(ARTIFACTS.getElementName(), map);
1042         }
1043     }
1044
1045     @SuppressWarnings("unchecked")
1046     private UploadArtifactInfo buildModuleNodeTemplateArtifact(Object artifactObject) {
1047         UploadArtifactInfo artifactTemplateInfo = new UploadArtifactInfo();
1048         if (artifactObject instanceof Map) {
1049             fillArtifact(artifactTemplateInfo, (Map<String, Object>) artifactObject);
1050         }
1051         return artifactTemplateInfo;
1052     }
1053
1054     private void fillArtifact(UploadArtifactInfo artifactTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
1055         if (nodeTemplateJsonMap.containsKey(TYPE.getElementName())) {
1056             artifactTemplateInfo.setType((String) nodeTemplateJsonMap.get(TYPE.getElementName()));
1057         }
1058         if (nodeTemplateJsonMap.containsKey(FILE.getElementName())) {
1059             artifactTemplateInfo.setFile((String) nodeTemplateJsonMap.get(FILE.getElementName()));
1060         }
1061         if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) {
1062             Map<String, List<UploadPropInfo>> props =
1063                 buildPropModuleFromYaml((Map<String, Object>) nodeTemplateJsonMap.get(PROPERTIES.getElementName()));
1064             if (!props.isEmpty()) {
1065                 List<UploadPropInfo> properties = props.values().stream().flatMap(Collection::stream).collect(toList());
1066                 artifactTemplateInfo.setProperties(properties);
1067             }
1068         }
1069     }
1070
1071     @SuppressWarnings("unchecked")
1072     private Map<String, List<UploadCapInfo>> createCapModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) {
1073         Map<String, List<UploadCapInfo>> moduleCap = new HashMap<>();
1074         Map<String, Object> capabilities = (Map<String, Object>) nodeTemplateJsonMap.get(CAPABILITIES.getElementName());
1075         if (MapUtils.isNotEmpty(capabilities)) {
1076             for (Map.Entry<String, Object> entry : capabilities.entrySet()) {
1077                 String capName = entry.getKey();
1078                 Object capJson = entry.getValue();
1079                 addModuleNodeTemplateCap(moduleCap, capJson, capName);
1080             }
1081         }
1082         return moduleCap;
1083     }
1084
1085     private void addModuleNodeTemplateCap(Map<String, List<UploadCapInfo>> moduleCap, Object capJson, String key) {
1086         UploadCapInfo capabilityDef = buildModuleNodeTemplateCap(capJson);
1087         capabilityDef.setKey(key);
1088         if (moduleCap.containsKey(key)) {
1089             moduleCap.get(key).add(capabilityDef);
1090         } else {
1091             List<UploadCapInfo> list = new ArrayList<>();
1092             list.add(capabilityDef);
1093             moduleCap.put(key, list);
1094         }
1095     }
1096
1097     @SuppressWarnings("unchecked")
1098     private UploadCapInfo buildModuleNodeTemplateCap(Object capObject) {
1099         UploadCapInfo capTemplateInfo = new UploadCapInfo();
1100         if (capObject instanceof String) {
1101             String nodeTemplateJsonString = (String) capObject;
1102             capTemplateInfo.setNode(nodeTemplateJsonString);
1103         } else if (capObject instanceof Map) {
1104             fillCapability(capTemplateInfo, (Map<String, Object>) capObject);
1105         }
1106         return capTemplateInfo;
1107     }
1108
1109     private void fillCapability(UploadCapInfo capTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
1110         if (nodeTemplateJsonMap.containsKey(NODE.getElementName())) {
1111             capTemplateInfo.setNode((String) nodeTemplateJsonMap.get(NODE.getElementName()));
1112         }
1113         if (nodeTemplateJsonMap.containsKey(TYPE.getElementName())) {
1114             capTemplateInfo.setType((String) nodeTemplateJsonMap.get(TYPE.getElementName()));
1115         }
1116         if (nodeTemplateJsonMap.containsKey(VALID_SOURCE_TYPES.getElementName())) {
1117             Either<List<Object>, ResultStatusEnum> validSourceTypesRes = findFirstToscaListElement(nodeTemplateJsonMap, VALID_SOURCE_TYPES);
1118             if (validSourceTypesRes.isLeft()) {
1119                 capTemplateInfo.setValidSourceTypes(validSourceTypesRes.left().value().stream().map(Object::toString).collect(toList()));
1120             }
1121         }
1122         if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) {
1123             Map<String, List<UploadPropInfo>> props =
1124                 buildPropModuleFromYaml((Map<String, Object>) nodeTemplateJsonMap.get(PROPERTIES.getElementName()));
1125             if (!props.isEmpty()) {
1126                 List<UploadPropInfo> properties = props.values().stream().flatMap(Collection::stream).collect(toList());
1127                 capTemplateInfo.setProperties(properties);
1128             }
1129         }
1130     }
1131
1132     @SuppressWarnings("unchecked")
1133     private UploadReqInfo buildModuleNodeTemplateReg(Object regObject, String nodeName) {
1134         UploadReqInfo regTemplateInfo = new UploadReqInfo();
1135         if (regObject instanceof String) {
1136             String nodeTemplateJsonString = (String) regObject;
1137             regTemplateInfo.setNode(nodeTemplateJsonString);
1138         } else if (regObject instanceof Map) {
1139             Map<String, Object> nodeTemplateJsonMap = (Map<String, Object>) regObject;
1140             if (nodeTemplateJsonMap.containsKey(NODE.getElementName())) {
1141                 regTemplateInfo.setNode((String) nodeTemplateJsonMap.get(NODE.getElementName()));
1142             }
1143             if (nodeTemplateJsonMap.containsKey(CAPABILITY.getElementName())) {
1144                 regTemplateInfo.setCapabilityName((String) nodeTemplateJsonMap.get(CAPABILITY.getElementName()));
1145             }
1146             if (nodeTemplateJsonMap.containsKey(RELATIONSHIP.getElementName())) {
1147                 final String template = (String) nodeTemplateJsonMap.get(RELATIONSHIP.getElementName());
1148                 if (StringUtils.isNotEmpty(nodeName) && template.contains(nodeName)) {
1149                     regTemplateInfo.setRelationshipTemplate(template);
1150                 }
1151             }
1152         }
1153         return regTemplateInfo;
1154     }
1155
1156     private Map<String, UploadAttributeInfo> buildAttributeModuleFromYaml(
1157         Map<String, Object> nodeTemplateJsonMap) {
1158         Map<String, UploadAttributeInfo> moduleAttribute = new HashMap<>();
1159         Either<Map<String, Object>, ResultStatusEnum> toscaAttributes = findFirstToscaMapElement(nodeTemplateJsonMap, ATTRIBUTES);
1160         if (toscaAttributes.isLeft()) {
1161             Map<String, Object> jsonAttributes = toscaAttributes.left().value();
1162             for (Map.Entry<String, Object> jsonAttributeObj : jsonAttributes.entrySet()) {
1163                 UploadAttributeInfo attributeDef = buildAttribute(jsonAttributeObj.getKey(), jsonAttributeObj.getValue());
1164                 moduleAttribute.put(attributeDef.getName(), attributeDef);
1165             }
1166         }
1167         return moduleAttribute;
1168     }
1169
1170     private UploadAttributeInfo buildAttribute(String attributeName, Object attributeValue) {
1171         UploadAttributeInfo attributeDef = new UploadAttributeInfo();
1172         attributeDef.setValue(attributeValue);
1173         attributeDef.setName(attributeName);
1174         return attributeDef;
1175     }
1176
1177     private Map<String, List<UploadPropInfo>> buildPropModuleFromYaml(final Map<String, Object> propertyMap) {
1178         final Map<String, List<UploadPropInfo>> moduleProp = new HashMap<>();
1179         propertyMap.entrySet().forEach(propertyMapEntry -> addProperty(moduleProp, propertyMapEntry));
1180         return moduleProp;
1181     }
1182
1183     private Map<String, UploadInterfaceInfo> buildInterfacesModuleFromYaml(
1184         Map<String, Object> nodeTemplateJsonMap
1185     ) {
1186         Map<String, UploadInterfaceInfo> moduleInterfaces = new HashMap<>();
1187         Either<Map<String, Object>, ResultStatusEnum> toscaInterfaces = findFirstToscaMapElement(nodeTemplateJsonMap, INTERFACES);
1188         if (toscaInterfaces.isLeft()) {
1189             Map<String, Object> jsonInterfaces = toscaInterfaces.left().value();
1190             for (Map.Entry<String, Object> jsonInterfacesObj : jsonInterfaces.entrySet()) {
1191                 addInterfaces(moduleInterfaces, jsonInterfacesObj);
1192             }
1193         }
1194         return moduleInterfaces;
1195     }
1196
1197     private void addProperty(Map<String, List<UploadPropInfo>> moduleProp, Map.Entry<String, Object> jsonPropObj) {
1198         UploadPropInfo propertyDef = buildProperty(jsonPropObj.getKey(), jsonPropObj.getValue());
1199         if (moduleProp.containsKey(propertyDef.getName())) {
1200             moduleProp.get(propertyDef.getName()).add(propertyDef);
1201         } else {
1202             List<UploadPropInfo> list = new ArrayList<>();
1203             list.add(propertyDef);
1204             moduleProp.put(propertyDef.getName(), list);
1205         }
1206     }
1207
1208     private void addInterfaces(Map<String, UploadInterfaceInfo> moduleInterface, Map.Entry<String, Object> jsonPropObj) {
1209         UploadInterfaceInfo interfaceInfo = buildInterface(jsonPropObj.getKey(), jsonPropObj.getValue());
1210         moduleInterface.put(jsonPropObj.getKey(), interfaceInfo);
1211     }
1212
1213     @SuppressWarnings("unchecked")
1214     private UploadPropInfo buildProperty(String propName, Object propValueObj) {
1215         final var propertyDef = new UploadPropInfo();
1216         propertyDef.setValue(propValueObj);
1217         propertyDef.setName(propName);
1218         if (propValueObj instanceof Map) {
1219             final Map<String, Object> propValueMap = (Map<String, Object>) propValueObj;
1220             if (propValueMap.containsKey(TYPE.getElementName())) {
1221                 propertyDef.setType(propValueMap.get(TYPE.getElementName()).toString());
1222             }
1223             if (containsGetInput(propValueObj)) {
1224                 fillInputRecursively(propName, propValueMap, propertyDef);
1225             }
1226             if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(propValueObj)) {
1227                 toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(propValueMap).ifPresent(propertyDef::setToscaFunction);
1228             } else {
1229                 final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions =
1230                     buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>());
1231                 if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) {
1232                     Collection<SubPropertyToscaFunction> existingSubPropertyToscaFunctions = propertyDef.getSubPropertyToscaFunctions();
1233                     if (existingSubPropertyToscaFunctions == null) {
1234                         propertyDef.setSubPropertyToscaFunctions(subPropertyToscaFunctions);
1235                     } else {
1236                         propertyDef.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions);
1237                     }
1238                 }
1239             }
1240             if (propValueMap.containsKey(DESCRIPTION.getElementName())) {
1241                 propertyDef.setDescription((propValueMap).get(DESCRIPTION.getElementName()).toString());
1242             }
1243             if (propValueMap.containsKey(DEFAULT_VALUE.getElementName())) {
1244                 propertyDef.setValue(propValueMap.get(DEFAULT_VALUE.getElementName()));
1245             }
1246             if (propValueMap.containsKey(IS_PASSWORD.getElementName())) {
1247                 propertyDef.setPassword(Boolean.getBoolean(propValueMap.get(IS_PASSWORD.getElementName()).toString()));
1248             } else {
1249                 propertyDef.setValue(propValueObj);
1250             }
1251         } else if (propValueObj instanceof List) {
1252             fillInputsListRecursively(propertyDef, (List<Object>) propValueObj);
1253             propertyDef.setValue(propValueObj);
1254         }
1255         return propertyDef;
1256     }
1257
1258     private Collection<SubPropertyToscaFunction> buildSubPropertyToscaFunctions(final Map<String, Object> propValueMap, final List<String> path) {
1259         Collection<SubPropertyToscaFunction> subPropertyToscaFunctions = new ArrayList<>();
1260         propValueMap.entrySet().stream().filter(entry -> entry.getValue() instanceof Map).forEach(entry -> {
1261             List<String> subPropertyPath = new ArrayList<>(path);
1262             subPropertyPath.add(entry.getKey());
1263             if (ToscaFunctionType.findType(((Map<String, Object>) entry.getValue()).keySet().iterator().next()).isPresent()) {
1264                 Optional<ToscaFunction> toscaFunction =
1265                     toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue((Map) entry.getValue());
1266                 if (toscaFunction.isPresent()) {
1267                     SubPropertyToscaFunction subPropertyToscaFunction = new SubPropertyToscaFunction();
1268                     subPropertyToscaFunction.setToscaFunction(toscaFunction.get());
1269                     subPropertyToscaFunction.setSubPropertyPath(subPropertyPath);
1270                     subPropertyToscaFunctions.add(subPropertyToscaFunction);
1271                 }
1272             } else {
1273                 subPropertyToscaFunctions.addAll(buildSubPropertyToscaFunctions((Map<String, Object>) entry.getValue(), subPropertyPath));
1274             }
1275         });
1276         return subPropertyToscaFunctions;
1277     }
1278
1279     private UploadInterfaceInfo buildInterface(String interfaceName, Object interfaceValue) {
1280         UploadInterfaceInfo interfaceDef = new UploadInterfaceInfo();
1281         interfaceDef.setValue(interfaceValue);
1282         interfaceDef.setName(interfaceName);
1283         interfaceDef.setKey(interfaceName);
1284         Map<String, OperationDataDefinition> operations = new HashMap<>();
1285         if (interfaceValue instanceof Map) {
1286             Map<String, Object> operationsMap = (Map<String, Object>) interfaceValue;
1287             for (Map.Entry<String, Object> operationEntry : operationsMap.entrySet()) {
1288                 OperationDataDefinition operationDef = new OperationDataDefinition();
1289                 operationDef.setName(operationEntry.getKey());
1290                 Map<String, Object> operationValue = (Map<String, Object>) operationEntry.getValue();
1291                 if (operationValue.containsKey(DESCRIPTION.getElementName())) {
1292                     operationDef.setDescription(operationValue.get(DESCRIPTION.getElementName()).toString());
1293                 }
1294                 operationDef.setImplementation(handleOperationImplementation(operationValue).orElse(new ArtifactDataDefinition()));
1295                 if (operationValue.containsKey(INPUTS.getElementName())) {
1296                     final Map<String, Object> interfaceInputs = (Map<String, Object>) operationValue.get(INPUTS.getElementName());
1297                     operationDef.setInputs(handleInterfaceOperationInputs(interfaceInputs));
1298                 }
1299                 operations.put(operationEntry.getKey(), operationDef);
1300             }
1301             interfaceDef.setOperations(operations);
1302             if (operationsMap.containsKey(TYPE.getElementName())) {
1303                 interfaceDef.setType(((Map<String, Object>) interfaceValue).get(TYPE.getElementName()).toString());
1304             }
1305         }
1306         return interfaceDef;
1307     }
1308
1309     private ListDataDefinition<OperationInputDefinition> handleInterfaceOperationInputs(final Map<String, Object> interfaceInputs) {
1310         final ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>();
1311         for (final Entry<String, Object> interfaceInput : interfaceInputs.entrySet()) {
1312             final OperationInputDefinition operationInput = new OperationInputDefinition();
1313             operationInput.setUniqueId(UUID.randomUUID().toString());
1314             operationInput.setInputId(operationInput.getUniqueId());
1315             operationInput.setName(interfaceInput.getKey());
1316
1317             handleInputToscaDefinition(interfaceInput.getKey(), interfaceInput.getValue(), operationInput);
1318             inputs.add(operationInput);
1319         }
1320         return inputs;
1321     }
1322
1323     private void handleInputToscaDefinition(
1324         final String inputName,
1325         final Object value,
1326         final OperationInputDefinition operationInput
1327     ) {
1328         if (value instanceof Map) {
1329             final Map<String, Object> valueMap = (Map<String, Object>) value;
1330             log.debug("Creating interface operation input '{}'", inputName);
1331             Type type = new TypeToken<LinkedHashMap<String, Object>>() {
1332             }.getType();
1333             String stringValue = gson.toJson(value, type);
1334             if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(value)) {
1335                 toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue((Map<String, Object>) value)
1336                     .ifPresent(operationInput::setToscaFunction);
1337             } else {
1338                 final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions = buildSubPropertyToscaFunctions(valueMap, new ArrayList<>());
1339                 if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) {
1340                     Collection<SubPropertyToscaFunction> existingSubPropertyToscaFunctions = operationInput.getSubPropertyToscaFunctions();
1341                     if (existingSubPropertyToscaFunctions == null) {
1342                         operationInput.setSubPropertyToscaFunctions(subPropertyToscaFunctions);
1343                     } else {
1344                         operationInput.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions);
1345                     }
1346                 }
1347             }
1348             operationInput.setValue(stringValue);
1349         }
1350         if (value instanceof String) {
1351             final String stringValue = (String) value;
1352             operationInput.setDefaultValue(stringValue);
1353             operationInput.setToscaDefaultValue(stringValue);
1354             operationInput.setValue(stringValue);
1355         }
1356         operationInput.setType("string");
1357         if (operationInput.getValue() == null) {
1358             operationInput.setValue(String.valueOf(value));
1359         }
1360     }
1361
1362     private Optional<ArtifactDataDefinition> handleOperationImplementation(
1363         final Map<String, Object> operationDefinitionMap
1364     ) {
1365         if (!operationDefinitionMap.containsKey(IMPLEMENTATION.getElementName())) {
1366             return Optional.empty();
1367         }
1368         final ArtifactDataDefinition artifactDataDefinition = new ArtifactDataDefinition();
1369         if (operationDefinitionMap.get(IMPLEMENTATION.getElementName()) instanceof Map &&
1370             ((Map) operationDefinitionMap.get(IMPLEMENTATION.getElementName())).containsKey("primary")) {
1371
1372             final Object primary = ((Map) operationDefinitionMap.get(IMPLEMENTATION.getElementName())).get("primary");
1373             if (primary instanceof Map) {
1374                 Map<String, Object> implDetails = (Map) primary;
1375
1376                 if (implDetails.get("file") != null) {
1377                     final String file = implDetails.get("file").toString();
1378                     artifactDataDefinition.setArtifactName(generateArtifactName(file));
1379                 }
1380                 if (implDetails.get("type") != null) {
1381                     artifactDataDefinition.setArtifactType(implDetails.get("type").toString());
1382                 }
1383                 if (implDetails.get("artifact_version") != null) {
1384                     artifactDataDefinition.setArtifactVersion(implDetails.get("artifact_version").toString());
1385                 }
1386
1387                 if (implDetails.get("properties") instanceof Map) {
1388                     Map<String, Object> properties = (Map<String, Object>) implDetails.get("properties");
1389                     properties.forEach((k, v) -> {
1390                         ToscaPropertyType type = getTypeFromObject(v);
1391                         if (type != null) {
1392                             PropertyDataDefinition propertyDef = new PropertyDataDefinition();
1393                             propertyDef.setName(k);
1394                             propertyDef.setValue(v.toString());
1395                             artifactDataDefinition.addProperty(propertyDef);
1396                         }
1397                     });
1398                 }
1399             } else {
1400                 artifactDataDefinition.setArtifactName(generateArtifactName(primary.toString()));
1401             }
1402         }
1403
1404         if (operationDefinitionMap.get(IMPLEMENTATION.getElementName()) instanceof Map &&
1405             ((Map) operationDefinitionMap.get(IMPLEMENTATION.getElementName())).containsKey("timeout")) {
1406             final Object timeOut = ((Map) operationDefinitionMap.get(IMPLEMENTATION.getElementName())).get("timeout");
1407             artifactDataDefinition.setTimeout((Integer)timeOut);
1408         }
1409
1410         if (operationDefinitionMap.get(IMPLEMENTATION.getElementName()) instanceof String) {
1411             final String implementation = (String) operationDefinitionMap.get(IMPLEMENTATION.getElementName());
1412             artifactDataDefinition.setArtifactName(generateArtifactName(implementation));
1413         }
1414         return Optional.of(artifactDataDefinition);
1415     }
1416
1417     private String generateArtifactName(final String name) {
1418         if (OperationArtifactUtil.artifactNameIsALiteralValue(name)) {
1419             return name;
1420         } else {
1421             return QUOTE + name + QUOTE;
1422         }
1423     }
1424
1425     private ToscaPropertyType getTypeFromObject(final Object value) {
1426         if (value instanceof String) {
1427             return ToscaPropertyType.STRING;
1428         }
1429         if (value instanceof Integer) {
1430             return ToscaPropertyType.INTEGER;
1431         }
1432         if (value instanceof Boolean) {
1433             return ToscaPropertyType.BOOLEAN;
1434         }
1435         if (value instanceof Float || value instanceof Double) {
1436             return ToscaPropertyType.FLOAT;
1437         }
1438         return null;
1439     }
1440
1441     @SuppressWarnings("unchecked")
1442     private boolean containsGetInput(Object propValue) {
1443         return ((Map<String, Object>) propValue).containsKey(GET_INPUT.getElementName()) || ImportUtils.containsGetInput(propValue);
1444     }
1445
1446     @SuppressWarnings("unchecked")
1447     private void fillInputsListRecursively(UploadPropInfo propertyDef, List<Object> propValueList) {
1448         int index = 0;
1449         for (Object objValue : propValueList) {
1450             if (objValue instanceof Map) {
1451                 Map<String, Object> objMap = (Map<String, Object>) objValue;
1452                 Map<String, Object> propValueMap = new HashMap<>();
1453                 propValueMap.put(String.valueOf(index), objValue);
1454                 final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions =
1455                     buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>());
1456                 if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) {
1457                     Collection<SubPropertyToscaFunction> existingSubPropertyToscaFunctions = propertyDef.getSubPropertyToscaFunctions();
1458                     if (existingSubPropertyToscaFunctions == null) {
1459                         propertyDef.setSubPropertyToscaFunctions(subPropertyToscaFunctions);
1460                     } else {
1461                         propertyDef.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions);
1462                     }
1463                 }
1464                 if (objMap.containsKey(GET_INPUT.getElementName())) {
1465                     fillInputRecursively(propertyDef.getName(), objMap, propertyDef);
1466                 } else {
1467                     Set<String> keys = objMap.keySet();
1468                     findAndFillInputsListRecursively(propertyDef, objMap, keys);
1469                 }
1470             } else if (objValue instanceof List) {
1471                 List<Object> propSubValueList = (List<Object>) objValue;
1472                 fillInputsListRecursively(propertyDef, propSubValueList);
1473             }
1474             index++;
1475         }
1476     }
1477
1478     @SuppressWarnings("unchecked")
1479     private void findAndFillInputsListRecursively(UploadPropInfo propertyDef, Map<String, Object> objMap, Set<String> keys) {
1480         for (String key : keys) {
1481             Object value = objMap.get(key);
1482             if (value instanceof Map) {
1483                 fillInputRecursively(key, (Map<String, Object>) value, propertyDef);
1484             } else if (value instanceof List) {
1485                 List<Object> propSubValueList = (List<Object>) value;
1486                 fillInputsListRecursively(propertyDef, propSubValueList);
1487             }
1488         }
1489     }
1490
1491     private void fillInputRecursively(String propName, Map<String, Object> propValue, UploadPropInfo propertyDef) {
1492         if (propValue.containsKey(GET_INPUT.getElementName())) {
1493             Object getInput = propValue.get(GET_INPUT.getElementName());
1494             GetInputValueDataDefinition getInputInfo = new GetInputValueDataDefinition();
1495             List<GetInputValueDataDefinition> getInputs = propertyDef.getGet_input();
1496             if (getInputs == null) {
1497                 getInputs = new ArrayList<>();
1498             }
1499             if (getInput instanceof String) {
1500                 getInputInfo.setInputName((String) getInput);
1501                 getInputInfo.setPropName(propName);
1502             } else if (getInput instanceof List) {
1503                 fillInput(propName, getInput, getInputInfo);
1504             }
1505             getInputs.add(getInputInfo);
1506             propertyDef.setGet_input(getInputs);
1507             propertyDef.setValue(propValue);
1508         } else {
1509             findAndFillInputRecursively(propValue, propertyDef);
1510         }
1511     }
1512
1513     @SuppressWarnings("unchecked")
1514     private void findAndFillInputRecursively(Map<String, Object> propValue, UploadPropInfo propertyDef) {
1515         for (Map.Entry<String, Object> entry : propValue.entrySet()) {
1516             String propName = entry.getKey();
1517             Object value = entry.getValue();
1518             if (value instanceof Map) {
1519                 fillInputRecursively(propName, (Map<String, Object>) value, propertyDef);
1520             } else if (value instanceof List) {
1521                 fillInputsRecursively(propertyDef, propName, (List<Object>) value);
1522             }
1523         }
1524     }
1525
1526     private void fillInputsRecursively(UploadPropInfo propertyDef, String propName, List<Object> inputs) {
1527         inputs.stream().filter(Map.class::isInstance).forEach(o -> fillInputRecursively(propName, (Map<String, Object>) o, propertyDef));
1528     }
1529
1530     @SuppressWarnings("unchecked")
1531     private void fillInput(String propName, Object getInput, GetInputValueDataDefinition getInputInfo) {
1532         List<Object> getInputList = (List<Object>) getInput;
1533         getInputInfo.setPropName(propName);
1534         getInputInfo.setInputName((String) getInputList.get(0));
1535         if (getInputList.size() > 1) {
1536             Object indexObj = getInputList.get(1);
1537             if (indexObj instanceof Integer) {
1538                 getInputInfo.setIndexValue((Integer) indexObj);
1539             } else if (indexObj instanceof Float) {
1540                 int index = ((Float) indexObj).intValue();
1541                 getInputInfo.setIndexValue(index);
1542             } else if (indexObj instanceof Map && ((Map<String, Object>) indexObj).containsKey(GET_INPUT.getElementName())) {
1543                 Object index = ((Map<String, Object>) indexObj).get(GET_INPUT.getElementName());
1544                 GetInputValueDataDefinition getInputInfoIndex = new GetInputValueDataDefinition();
1545                 getInputInfoIndex.setInputName((String) index);
1546                 getInputInfoIndex.setPropName(propName);
1547                 getInputInfo.setGetInputIndex(getInputInfoIndex);
1548             }
1549             getInputInfo.setList(true);
1550         }
1551     }
1552
1553     private Object failIfNotTopologyTemplate(String fileName) {
1554         janusGraphDao.rollback();
1555         throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, fileName);
1556     }
1557
1558     private void rollbackWithException(ActionStatus actionStatus, String... params) {
1559         janusGraphDao.rollback();
1560         throw new ByActionStatusComponentException(actionStatus, params);
1561     }
1562
1563     private void failOnMissingCapabilityTypes(GroupDefinition groupDefinition, List<String> missingCapTypes) {
1564         if (log.isDebugEnabled()) {
1565             log.debug(
1566                 "#failOnMissingCapabilityTypes - Failed to validate the capabilities of the group {}. The capability types {} are missing on the group type {}. ",
1567                 groupDefinition.getName(), missingCapTypes.toString(), groupDefinition.getType());
1568         }
1569         if (CollectionUtils.isNotEmpty(missingCapTypes)) {
1570             rollbackWithException(ActionStatus.MISSING_CAPABILITY_TYPE, missingCapTypes.toString());
1571         }
1572     }
1573
1574     private void failOnMissingCapabilityNames(GroupDefinition groupDefinition, List<String> missingCapNames) {
1575         if (log.isDebugEnabled()) {
1576             log.debug(
1577                 "#failOnMissingCapabilityNames - Failed to validate the capabilities of the group {}. The capabilities with the names {} are missing on the group type {}. ",
1578                 groupDefinition.getName(), missingCapNames.toString(), groupDefinition.getType());
1579         }
1580         rollbackWithException(ActionStatus.MISSING_CAPABILITIES, missingCapNames.toString(), CapabilityDataDefinition.OwnerType.GROUP.getValue(),
1581             groupDefinition.getName());
1582     }
1583 }