d204281d6bd81e3635f88ac66c6ce51cdb06d97d
[sdc.git] /
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.translator.services.heattotosca;
18
19 import static org.openecomp.sdc.heat.services.HeatResourceUtil.extractNetworkRoleFromSubInterfaceId;
20 import static org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation.FunctionTranslator.getFunctionTranslateTo;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Objects;
31 import java.util.Optional;
32 import java.util.Set;
33 import java.util.stream.Collectors;
34
35 import org.apache.commons.collections4.CollectionUtils;
36 import org.apache.commons.collections4.MapUtils;
37 import org.apache.commons.io.FilenameUtils;
38 import org.onap.sdc.tosca.datatypes.model.AttributeDefinition;
39 import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition;
40 import org.onap.sdc.tosca.datatypes.model.Import;
41 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
42 import org.onap.sdc.tosca.datatypes.model.NodeType;
43 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
44 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
45 import org.onap.sdc.tosca.datatypes.model.PropertyType;
46 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
47 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
48 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
49 import org.onap.sdc.tosca.datatypes.model.Template;
50 import org.onap.sdc.tosca.datatypes.model.TopologyTemplate;
51 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
52 import org.onap.sdc.tosca.services.YamlUtil;
53 import org.openecomp.core.translator.api.HeatToToscaTranslator;
54 import org.openecomp.core.translator.datatypes.TranslatorOutput;
55 import org.openecomp.core.translator.factory.HeatToToscaTranslatorFactory;
56 import org.openecomp.core.utilities.file.FileContentHandler;
57 import org.openecomp.core.utilities.file.FileUtils;
58 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
59 import org.openecomp.core.validation.util.MessageContainerUtil;
60 import org.openecomp.sdc.common.errors.CoreException;
61 import org.openecomp.sdc.common.errors.SdcRuntimeException;
62 import org.openecomp.sdc.common.utils.SdcCommon;
63 import org.openecomp.sdc.datatypes.error.ErrorLevel;
64 import org.openecomp.sdc.datatypes.error.ErrorMessage;
65 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
66 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
67 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
68 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
69 import org.openecomp.sdc.heat.datatypes.model.Resource;
70 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
71 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
72 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
73 import org.openecomp.sdc.heat.services.HeatConstants;
74 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
75 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
76 import org.openecomp.sdc.logging.api.Logger;
77 import org.openecomp.sdc.logging.api.LoggerFactory;
78 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
79 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
80 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
81 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
82 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
83 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
84 import org.openecomp.sdc.tosca.services.DataModelUtil;
85 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
86 import org.openecomp.sdc.tosca.services.ToscaConstants;
87 import org.openecomp.sdc.tosca.services.ToscaUtil;
88 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
89 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedPropertyVal;
90 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
91 import org.openecomp.sdc.translator.datatypes.heattotosca.ReferenceType;
92 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
93 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
94 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
95 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
96 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
97 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailV2VirtualMachineInterfaceHelper;
98 import org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation.FunctionTranslator;
99 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
100 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
101
102 /**
103  * The type Heat to tosca util.
104  */
105 public class HeatToToscaUtil {
106
107     private static final Logger LOGGER = LoggerFactory.getLogger(HeatToToscaUtil.class);
108     private static final String FQ_NAME = "fq_name";
109     private static final String GET_PARAM = "get_param";
110     private static final String GET_ATTR = "get_attr";
111     private static final String GET_RESOURCE = "get_resource";
112     private static final String UNDERSCORE = "_";
113
114     /**
115      * Load and translate template data translator output.
116      *
117      * @param fileNameContentMap the file name content map
118      * @return the translator output
119      */
120     public static TranslatorOutput loadAndTranslateTemplateData(FileContentHandler fileNameContentMap) {
121         HeatToToscaTranslator heatToToscaTranslator = HeatToToscaTranslatorFactory.getInstance().createInterface();
122
123         try (InputStream fileContent = fileNameContentMap.getFileContentAsStream(SdcCommon.MANIFEST_NAME)) {
124             heatToToscaTranslator.addManifest(SdcCommon.MANIFEST_NAME, FileUtils.toByteArray(fileContent));
125         } catch (IOException e) {
126             throw new SdcRuntimeException("Failed to read manifest", e);
127         }
128
129         fileNameContentMap.getFileList().stream().filter(fileName -> !(fileName.equals(SdcCommon.MANIFEST_NAME)))
130                           .forEach(fileName -> heatToToscaTranslator.addFile(fileName,
131                                   fileNameContentMap.getFileContent(fileName)));
132
133         Map<String, List<ErrorMessage>> errors = heatToToscaTranslator.validate();
134         if (MapUtils.isNotEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, errors))) {
135             TranslatorOutput translatorOutput = new TranslatorOutput();
136             translatorOutput.setErrorMessages(errors);
137             return translatorOutput;
138         }
139
140         try (InputStream structureFile = getHeatStructureTreeFile(fileNameContentMap)) {
141             heatToToscaTranslator.addExternalArtifacts(SdcCommon.HEAT_META, structureFile);
142             return heatToToscaTranslator.translate();
143         } catch (IOException e) {
144             // rethrow as a RuntimeException to keep the signature backward compatible
145             throw new SdcRuntimeException("Failed to read Heat template tree", e);
146         }
147     }
148
149
150     private static InputStream getHeatStructureTreeFile(FileContentHandler fileNameContentMap) {
151         HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(fileNameContentMap);
152         heatTreeManager.createTree();
153         HeatStructureTree tree = heatTreeManager.getTree();
154         ValidationStructureList validationStructureList = new ValidationStructureList(tree);
155         return FileUtils.convertToInputStream(validationStructureList, FileUtils.FileExtension.JSON);
156     }
157
158     /**
159      * Build list of files to search optional.
160      *
161      * @param heatFileName  the heat file name
162      * @param filesDataList the files data list
163      * @param types         the types
164      * @return the optional
165      */
166     public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName, List<FileData> filesDataList,
167                                                                            FileData.Type... types) {
168         List<FileData> list = new ArrayList<>(filesDataList);
169         Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
170         if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
171             list.addAll(resourceFileData.get().getData());
172         }
173         return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
174     }
175
176     /**
177      * Gets filtered list of file data by types.
178      *
179      * @param filesToSearch the files to search
180      * @param types         the types
181      * @return the filtered list of file data by types
182      */
183     public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
184                                                                          FileData.Type... types) {
185         return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types)).collect(Collectors.toList());
186     }
187
188     /**
189      * Gets file data from the list according to the input heat file name.
190      *
191      * @param heatFileName the heat file name
192      * @param fileDataList the file data list
193      * @return the file data
194      */
195     public static Optional<FileData> getFileData(String heatFileName, Collection<FileData> fileDataList) {
196         for (FileData file : fileDataList) {
197             if (file.getFile().equals(heatFileName)) {
198                 return Optional.of(file);
199             }
200         }
201         return Optional.empty();
202     }
203
204     /**
205      * Gets file data which is supported by the translator, from the context according the input heat
206      * file name.
207      *
208      * @param heatFileName the heat file name
209      * @param context      the translation context
210      * @return the file data
211      */
212     public static FileData getFileData(String heatFileName, TranslationContext context) {
213         List<FileData> fileDataList = context.getManifest().getContent().getData();
214         for (FileData fileData : fileDataList) {
215             if (TranslationService.getTypesToProcessByTranslator().contains(fileData.getType()) && fileData.getFile()
216                     .equals(heatFileName)) {
217                 return fileData;
218             }
219         }
220         return null;
221     }
222
223     static FileDataCollection getFileCollectionsByHelmFilter(List<FileData> fileDataList, Set<FileData.Type> typeFilter) {
224         FileDataCollection fileDataCollection = new FileDataCollection();
225         Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
226         for (FileData fileData : filteredFiles.values()) {
227             String fileName = fileData.getFile();
228             if((fileData.getType().equals(FileData.Type.HELM)))
229             {
230                 fileDataCollection.addHelmFiles(fileData);
231             }
232         }
233         return fileDataCollection;
234     }
235
236     static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList, Set<FileData.Type> typeFilter,
237                                                                 TranslationContext translationContext) {
238         FileDataCollection fileDataCollection = new FileDataCollection();
239         Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
240         Set<String> referenced = new HashSet<>();
241         for (FileData fileData : filteredFiles.values()) {
242             String fileName = fileData.getFile();
243
244             if (FileData.isHeatFile(fileData.getType())) {
245                 if (fileData.getBase() != null && fileData.getBase()) {
246                     fileDataCollection.addBaseFiles(fileData);
247                 }
248                 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil().yamlToObject(
249                         translationContext.getFileContentAsStream(fileName), HeatOrchestrationTemplate.class);
250                 if (MapUtils.isNotEmpty(heatOrchestrationTemplate.getResources())) {
251                     referenced.addAll(applyFilterOnFileCollection(heatOrchestrationTemplate, translationContext,
252                             fileDataCollection, filteredFiles));
253                 }
254
255             } else {
256                 fileDataCollection.addArtifactFiles(fileData);
257                 filteredFiles.remove(fileData.getFile());
258             }
259         }
260
261         referenced.addAll(getAssociatedFiles(filteredFiles.values()));
262         referenced.forEach(filteredFiles::remove);
263
264         if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
265             for (FileData fileData : fileDataCollection.getBaseFile()) {
266                 filteredFiles.remove(fileData.getFile());
267             }
268         }
269         fileDataCollection.setAddOnFiles(filteredFiles.values());
270         return fileDataCollection;
271     }
272
273     private static Set<String> getAssociatedFiles(Collection<FileData> filteredFiles) {
274         Set<String> associatedFiles = new HashSet<>();
275         filteredFiles.stream().filter(file -> file.getParentFile() != null
276                             && FileData.Type.canBeAssociated(file.getType()))
277                                     .forEach(file -> associatedFiles.add(file.getFile()));
278         return associatedFiles;
279     }
280
281     private static Set<String> applyFilterOnFileCollection(HeatOrchestrationTemplate heatOrchestrationTemplate,
282                                                            TranslationContext translationContext,
283                                                            FileDataCollection fileDataCollection,
284                                                            Map<String, FileData> filteredFiles) {
285         Set<String> nestedFiles = new HashSet<>();
286         List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
287         for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
288             String resourceType = resource.getType();
289             if (filenames.contains(resourceType)) {
290                 handleNestedFile(translationContext, fileDataCollection, filteredFiles, resourceType);
291                 nestedFiles.add(resourceType);
292             } else if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
293                 Optional<String> nestedFile = handleResourceGrpNestedFile(resource, translationContext,
294                         fileDataCollection, filteredFiles, filenames);
295                 nestedFile.ifPresent(nestedFiles::add);
296             }
297         }
298         return nestedFiles;
299     }
300
301     private static Optional<String> handleResourceGrpNestedFile(Resource resource, TranslationContext
302             translationContext, FileDataCollection fileDataCollection,
303                     Map<String, FileData> filteredFiles, List<String> filenames) {
304         Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
305         Object innerTypeDef = ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
306         if (innerTypeDef instanceof String) {
307             String internalResourceType = (String) innerTypeDef;
308             if (filenames.contains(internalResourceType)) {
309                 handleNestedFile(translationContext, fileDataCollection, filteredFiles,
310                         internalResourceType);
311                 return Optional.of(internalResourceType);
312             }
313         }
314         return Optional.empty();
315     }
316
317     private static void handleNestedFile(TranslationContext translationContext, FileDataCollection fileDataCollection,
318                                                 Map<String, FileData> filteredFiles,
319                                                 String nestedFileName) {
320         fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
321         translationContext.getNestedHeatsFiles().add(nestedFileName);
322     }
323
324     private static Map<String, FileData>  filterFileDataListByType(List<FileData> fileDataList,
325             Set<FileData.Type> typesToGet) {
326         Map<String, FileData> filtered = new HashMap<>();
327         filterFileDataListByType(fileDataList, filtered, typesToGet, null);
328         return filtered;
329     }
330
331     private static void filterFileDataListByType(List<FileData> fileDataList, Map<String, FileData> filtered,
332             Set<FileData.Type> typesToGet, String parentFileName) {
333         fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
334                     .forEach(file -> {
335                         filtered.put(file.getFile(), file);
336                         file.setParentFile(parentFileName);
337                     });
338
339         Set<FileData.Type> canBeAssociatedTypes = typesToGet.stream()
340                 .filter(FileData.Type::canBeAssociated).collect(Collectors.toSet());
341
342         fileDataList.stream().filter(file -> Objects.nonNull(file.getData()))
343                 .forEach(file -> filterFileDataListByType(file.getData(), filtered,
344                         canBeAssociatedTypes, file.getFile()));
345     }
346
347     private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
348         return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
349     }
350
351     /**
352      * Extract attached resource id optional.
353      *
354      * @param translateTo  the translate to
355      * @param propertyName the property name
356      * @return the optional
357      */
358     public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo, String propertyName) {
359         Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
360         if (propertyValue == null) {
361             return Optional.empty();
362         }
363         return extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
364                 translateTo.getContext(), propertyValue);
365     }
366
367     /**
368      * Extract attached resource id optional.
369      *
370      * @param heatFileName              the heat file name
371      * @param heatOrchestrationTemplate the heat orchestration template
372      * @param context                   the context
373      * @param propertyValue             the property value
374      * @return the optional
375      */
376     public static Optional<AttachedResourceId> extractAttachedResourceId(String heatFileName,
377                                                                                 HeatOrchestrationTemplate heatOrchestrationTemplate,
378                                                                                 TranslationContext context,
379                                                                                 Object propertyValue) {
380
381         Object entity;
382         Object translatedId = null;
383
384         if (Objects.isNull(propertyValue)) {
385             return Optional.empty();
386         }
387
388         ReferenceType referenceType = ReferenceType.OTHER;
389         if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
390             Map<String, Object> propMap = (Map) propertyValue;
391             Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
392             entity = entry.getValue();
393             String key = entry.getKey();
394             referenceType = getReferenceTypeFromAttachedResouce(key);
395
396             if (FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
397                 FunctionTranslator functionTranslator = new FunctionTranslator(getFunctionTranslateTo(null, null,
398                         heatFileName, heatOrchestrationTemplate, context), null, entry.getValue(), null);
399                 translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
400                         .translateFunction(functionTranslator);
401                 if (translatedId instanceof String
402                         && !new FunctionTranslator().isResourceSupported((String) translatedId)) {
403                     translatedId = null;
404                 }
405             }
406         } else {
407             translatedId = propertyValue;
408             entity = propertyValue;
409         }
410
411         return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
412     }
413
414     private static ReferenceType getReferenceTypeFromAttachedResouce(String key) {
415         ReferenceType referenceType;
416         switch (key) {
417             case GET_RESOURCE:
418                 referenceType = ReferenceType.GET_RESOURCE;
419                 break;
420             case GET_PARAM:
421                 referenceType = ReferenceType.GET_PARAM;
422                 break;
423             case GET_ATTR:
424                 referenceType = ReferenceType.GET_ATTR;
425                 break;
426             default:
427                 referenceType = ReferenceType.OTHER;
428                 break;
429         }
430
431         return referenceType;
432     }
433
434     /**
435      * Gets contrail attached heat resource id.
436      *
437      * @param attachedResource the attached resource
438      * @return the contrail attached heat resource id
439      */
440     public static Optional<String> getContrailAttachedHeatResourceId(AttachedResourceId attachedResource) {
441         if (attachedResource == null) {
442             return Optional.empty();
443         }
444
445         if (attachedResource.isGetResource()) {
446             return Optional.of((String) attachedResource.getEntityId());
447         }
448
449         if (attachedResource.isGetAttr()) {
450             return getResourceId(attachedResource.getEntityId());
451         }
452         return Optional.empty();
453     }
454
455     /**
456      * Extract property optional.
457      *
458      * @param propertyValue the property value
459      * @return the optional
460      */
461     private static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
462         Object attachedPropertyVal;
463         if (Objects.isNull(propertyValue)) {
464             return Optional.empty();
465         }
466
467         ReferenceType referenceType = ReferenceType.OTHER;
468         if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
469             Map<String, Object> propMap = (Map) propertyValue;
470             Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
471             attachedPropertyVal = entry.getValue();
472             String key = entry.getKey();
473             switch (key) {
474                 case GET_RESOURCE:
475                     referenceType = ReferenceType.GET_RESOURCE;
476                     break;
477                 case GET_PARAM:
478                     referenceType = ReferenceType.GET_PARAM;
479                     break;
480                 case GET_ATTR:
481                     referenceType = ReferenceType.GET_ATTR;
482                     break;
483                 default:
484                     break;
485             }
486
487         } else {
488             attachedPropertyVal = propertyValue;
489         }
490         return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
491     }
492
493     /**
494      * Map boolean.
495      *
496      * @param nodeTemplate the node template
497      * @param propertyKey  the property key
498      */
499     public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
500         Object value = nodeTemplate.getProperties().get(propertyKey);
501         if (value != null && !(value instanceof Map)) {
502             nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
503         }
504     }
505
506     /**
507      * Map boolean list.
508      *
509      * @param nodeTemplate    the node template
510      * @param propertyListKey the property list key
511      */
512     public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
513         Object listValue = nodeTemplate.getProperties().get(propertyListKey);
514         if (listValue instanceof List) {
515             List booleanList = (List) listValue;
516             for (int i = 0; i < booleanList.size(); i++) {
517                 Object value = booleanList.get(i);
518                 if (value != null && !(value instanceof Map)) {
519                     booleanList.set(i, HeatBoolean.eval(value));
520                 }
521             }
522         }
523     }
524
525
526     /**
527      * Is yml file type boolean.
528      *
529      * @param filename the filename
530      * @return the boolean
531      */
532     public static boolean isYmlFileType(String filename) {
533         String extension = FilenameUtils.getExtension(filename);
534         return "yaml".equalsIgnoreCase(extension) || "yml".equalsIgnoreCase(extension);
535     }
536
537     /**
538      * Is nested resource boolean.
539      *
540      * @param resource the resource
541      * @return the boolean
542      */
543     public static boolean isNestedResource(Resource resource) {
544         String resourceType = resource.getType();
545
546         if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
547             Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
548             if (!(((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME) instanceof String)) {
549                 //currently only resource group which is poinitng to nested heat file is supported
550                 //dynamic type is currently not supported
551                 return false;
552             }
553             String internalResourceType =
554                     (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
555             if (isYamlFile(internalResourceType)) {
556                 return true;
557             }
558         } else if (isYamlFile(resourceType)) {
559             return true;
560         }
561         return false;
562     }
563
564     /**
565      * Checks if the current HEAT resource if of type sub interface.
566      *
567      * @param resource the resource
568      * @return true if the resource is of sub interface type and false otherwise
569      */
570     public static boolean isSubInterfaceResource(Resource resource, TranslationContext context) {
571         //Check if resource group is a nested resource
572         if (!isNestedResource(resource)) {
573             return false;
574         }
575         Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
576         return nestedHeatFileName.filter(fileName -> isNestedVlanResource(fileName, context)).isPresent();
577     }
578
579     private static boolean isNestedVlanResource(String nestedHeatFileName, TranslationContext translationContext) {
580         HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
581                 translationContext.getFileContentAsStream(nestedHeatFileName), HeatOrchestrationTemplate.class);
582         return Objects.nonNull(nestedHeatOrchestrationTemplate.getResources()) && nestedHeatOrchestrationTemplate
583                                                                                           .getResources().values()
584                                                                                           .stream().anyMatch(
585                         new ContrailV2VirtualMachineInterfaceHelper()::isVlanSubInterfaceResource);
586     }
587
588     public static Optional<String> getSubInterfaceParentPortNodeTemplateId(TranslateTo subInterfaceTo) {
589         String subInterfaceResourceType = getSubInterfaceResourceType(subInterfaceTo.getResource());
590         HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
591                 subInterfaceTo.getContext().getFileContentAsStream(subInterfaceResourceType), HeatOrchestrationTemplate.class);
592         if (Objects.isNull(nestedHeatOrchestrationTemplate.getResources())) {
593             return Optional.empty();
594         }
595         for (Map.Entry<String, Resource> resourceEntry : nestedHeatOrchestrationTemplate.getResources().entrySet()) {
596             Resource resource = resourceEntry.getValue();
597             if (isVmiRefsPropertyExists(resource)) {
598                 Object toscaPropertyValue = TranslatorHeatToToscaPropertyConverter
599                                                     .getToscaPropertyValue(subInterfaceTo.getServiceTemplate(),
600                                                             resourceEntry.getKey(),
601                                                             HeatConstants.VMI_REFS_PROPERTY_NAME,
602                                                             resource.getProperties()
603                                                                     .get(HeatConstants.VMI_REFS_PROPERTY_NAME),
604                                                             resource.getType(), subInterfaceResourceType,
605                                                             nestedHeatOrchestrationTemplate, null,
606                                                             subInterfaceTo.getContext());
607                 return getParentNodeTemplateIdFromPropertyValue(toscaPropertyValue, subInterfaceTo);
608             }
609         }
610         return Optional.empty();
611     }
612
613     private static boolean isVmiRefsPropertyExists(Resource resource) {
614         return HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource()
615                                                                                      .equals(resource.getType())
616                        && MapUtils.isNotEmpty(resource.getProperties()) && resource.getProperties().containsKey(
617                 HeatConstants.VMI_REFS_PROPERTY_NAME);
618     }
619     
620     public static boolean isValueSpecsPropertyExists(Resource resource) {
621         return  MapUtils.isNotEmpty(resource.getProperties()) && resource.getProperties().containsKey(
622                 HeatConstants.VALUE_SPECS_PROPERTY_NAME);
623     }
624     
625     public static Optional<Object> getResourceProperty(Resource resource, String propertyName){
626         Map<String, Object> properties = resource.getProperties();
627         if(MapUtils.isNotEmpty(properties) && properties.containsKey(propertyName)){
628             return Optional.ofNullable(resource.getProperties().get(propertyName));
629         }
630         return Optional.empty();  
631     }
632
633     public static String getSubInterfaceResourceType(Resource resource) {
634         if (!HeatToToscaUtil.isYamlFile(resource.getType())) {
635             return ((Map) resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
636                            .get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME).toString();
637         }
638         return resource.getType();
639     }
640
641     private static Optional<String> getParentNodeTemplateIdFromPropertyValue(Object toscaPropertyValue,
642                                                                                     TranslateTo subInterfaceTo) {
643         if (toscaPropertyValue instanceof List && ((List) toscaPropertyValue).get(0) instanceof Map) {
644             Resource subInterfaceResource = subInterfaceTo.getResource();
645             Map<String, String> toscaPropertyValueMap = (Map) ((List) toscaPropertyValue).get(0);
646             String parentPortPropertyInput = toscaPropertyValueMap.get(ToscaFunctions.GET_INPUT.getFunctionName());
647             Map<String, Object> resourceDefPropertiesMap;
648             if (!isYamlFile(subInterfaceResource.getType())) {
649                 resourceDefPropertiesMap =
650                         (Map) ((Map) subInterfaceResource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
651                                       .get(HeatConstants.RESOURCE_DEF_PROPERTIES);
652             } else {
653                 resourceDefPropertiesMap = subInterfaceResource.getProperties();
654             }
655             Object parentPortObj = resourceDefPropertiesMap.get(parentPortPropertyInput);
656             if (parentPortObj instanceof Map) {
657                 Map<String, String> parentPortPropertyValue = (Map) parentPortObj;
658                 if (parentPortPropertyValue.keySet().contains(ResourceReferenceFunctions.GET_RESOURCE.getFunction())) {
659                     return ResourceTranslationBase.getResourceTranslatedId(subInterfaceTo.getHeatFileName(),
660                             subInterfaceTo.getHeatOrchestrationTemplate(),
661                             parentPortPropertyValue.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction()),
662                             subInterfaceTo.getContext());
663                 }
664             }
665         }
666         return Optional.empty();
667     }
668
669     /**
670      * Checks if the nested resource represents a VFC or a complex VFC (Heat file should contain at
671      * least one or more compute nodes).
672      *
673      * @param resource the resource
674      * @param context  the context
675      * @return true if the resource represents a VFC and false otherwise.
676      */
677     public static boolean isNestedVfcResource(Resource resource, TranslationContext context) {
678         Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
679         HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
680                 context.getFileContentAsStream(nestedHeatFileName.get()), HeatOrchestrationTemplate.class);
681         Map<String, Resource> resources = nestedHeatOrchestrationTemplate.getResources();
682         return Objects.nonNull(resources) && resources.values().stream()
683                      .anyMatch(ConsolidationDataUtil::isComputeResource);
684     }
685
686     /**
687      * Get nested heat file name in case of nested resource.
688      *
689      * @param resource the resource
690      * @return the nested heat file name
691      */
692     private static Optional<String> getNestedHeatFileName(Resource resource) {
693         if (!isNestedResource(resource)) {
694             return Optional.empty();
695         }
696
697         String resourceType = resource.getType();
698
699         if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
700             Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
701             String internalResourceType =
702                     (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
703             return Optional.of(internalResourceType);
704         }
705         return Optional.of(resourceType);
706     }
707
708     /**
709      * Gets nested file.
710      *
711      * @param resource the resource
712      * @return the nested file
713      */
714     public static Optional<String> getNestedFile(Resource resource) {
715         if (!isNestedResource(resource)) {
716             return Optional.empty();
717         }
718         String resourceType = resource.getType();
719         if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
720             Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
721             String internalResourceType =
722                     (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
723             return Optional.of(internalResourceType);
724         } else {
725             return Optional.of(resourceType);
726         }
727     }
728
729     public static boolean isYamlFile(String fileName) {
730         return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
731     }
732
733     /**
734      * Gets resource.
735      *
736      * @param heatOrchestrationTemplate the heat orchestration template
737      * @param resourceId                the resource id
738      * @param heatFileName              the heat file name
739      * @return the resource
740      */
741     public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate, String resourceId,
742                                               String heatFileName) {
743         Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
744         if (resource == null) {
745             throw new CoreException(new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
746         }
747         return resource;
748     }
749
750
751     /**
752      * Get resource type.
753      *
754      * @param resourceId                the resource id
755      * @param heatOrchestrationTemplate heat orchestration template
756      * @param heatFileName              heat file name
757      * @return resource type
758      */
759     public static String getResourceType(String resourceId, HeatOrchestrationTemplate heatOrchestrationTemplate,
760                                                 String heatFileName) {
761         return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName).getType();
762     }
763
764     /**
765      * Is heat file nested boolean.
766      *
767      * @param translateTo  the translate to
768      * @param heatFileName the heat file name
769      * @return the boolean
770      */
771     public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
772         return isHeatFileNested(translateTo.getContext(), heatFileName);
773     }
774
775     public static boolean isHeatFileNested(TranslationContext context, String heatFileName) {
776         return context.getNestedHeatsFiles().contains(heatFileName);
777     }
778
779     /**
780      * Extract contrail get resource attached heat resource id optional.
781      *
782      * @param propertyValue the property value
783      * @return the optional
784      */
785     public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(Object propertyValue) {
786         if (propertyValue instanceof Map) {
787             if (((Map) propertyValue).containsKey(GET_ATTR)) {
788                 return getResourceId(((Map) propertyValue).get(GET_ATTR));
789             } else if (((Map) propertyValue).containsKey(GET_RESOURCE)) {
790                 return getHeatResourceIdFromResource((Map) propertyValue);
791             } else {
792                 Collection valCollection = ((Map) propertyValue).values();
793                 return evaluateHeatResourceId(valCollection);
794             }
795         } else if (propertyValue instanceof List) {
796             return evaluateHeatResourceId((List) propertyValue);
797         }
798         return Optional.empty();
799     }
800
801     private static Optional<String> getResourceId(Object data) {
802         if (data instanceof List && CollectionUtils.size(data) > 1 && FQ_NAME.equals(((List) data).get(1))
803                     && ((List) data).get(0) instanceof String) {
804             return Optional.of((String) ((List) data).get(0));
805         } else {
806             LOGGER.warn("invalid format of 'get_attr' function - " + data.toString());
807             return Optional.empty();
808         }
809     }
810
811     private static Optional<String> getHeatResourceIdFromResource(Map propertyValue) {
812         Object value = propertyValue.get(GET_RESOURCE);
813         if (value instanceof String) {
814             return Optional.of((String) value);
815         } else {
816             LOGGER.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
817             return Optional.empty();
818         }
819     }
820
821     private static Optional<String> evaluateHeatResourceId(Collection propertyValue) {
822         for (Object prop : propertyValue) {
823             Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
824             if (ret.isPresent()) {
825                 return ret;
826             }
827         }
828         return Optional.empty();
829     }
830
831     /**
832      * Gets tosca service model.
833      *
834      * @param context translation context
835      * @return the tosca service model
836      */
837     public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
838         Map<String, String> metadata = new HashMap<>();
839         metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
840         return getToscaServiceModel(context, metadata);
841     }
842
843     /**
844      * Gets tosca service model.
845      *
846      * @param context                 translation context
847      * @param entryDefinitionMetadata template name of the entry definition servie template
848      * @return the tosca service model
849      */
850     private static ToscaServiceModel getToscaServiceModel(TranslationContext context,
851                                                                  Map<String, String> entryDefinitionMetadata) {
852         Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(context.getGlobalServiceTemplates());
853         Collection<ServiceTemplate> tmpServiceTemplates = context.getTranslatedServiceTemplates().values();
854         for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
855             ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
856         }
857         return new ToscaServiceModel(null, serviceTemplates,
858                                             ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
859     }
860
861     /**
862      * Gets service template from context.
863      *
864      * @param serviceTemplateFileName the service template file name
865      * @param context                 the context
866      * @return the service template from context
867      */
868     public static Optional<ServiceTemplate> getServiceTemplateFromContext(String serviceTemplateFileName,
869                                                                                  TranslationContext context) {
870         for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
871             if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
872                 return Optional.of(serviceTemplate);
873             }
874         }
875         return Optional.empty();
876     }
877
878     /**
879      * Adding link requerment from port node template to network node template.
880      *
881      * @param portNodeTemplate    port node template
882      * @param networkTranslatedId network node template id
883      */
884     public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
885                                                                            String networkTranslatedId) {
886         RequirementAssignment requirement = new RequirementAssignment();
887         requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
888         requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
889         requirement.setNode(networkTranslatedId);
890         DataModelUtil.addRequirementAssignment(portNodeTemplate, ToscaConstants.LINK_REQUIREMENT_ID, requirement);
891         return requirement;
892     }
893
894     /**
895      * Adding binding requerment from sub interface node template to interface (port) node template.
896      *
897      * @param subInterfaceNodeTemplate sub interface template
898      * @param interfaceTranslatedId    interface node template id
899      */
900     public static void addBindingReqFromSubInterfaceToInterface(NodeTemplate subInterfaceNodeTemplate,
901                                                                        String interfaceTranslatedId) {
902         RequirementAssignment requirement = new RequirementAssignment();
903         requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
904         requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
905         requirement.setNode(interfaceTranslatedId);
906         DataModelUtil
907                 .addRequirementAssignment(subInterfaceNodeTemplate, ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
908     }
909
910     /**
911      * Get property Parameter Name Value.
912      *
913      * @param property property
914      * @return Parameter name in case the property include "get_param" function
915      */
916     public static Optional<String> getPropertyParameterNameValue(Object property) {
917         if (Objects.isNull(property)) {
918             return Optional.empty();
919         }
920         Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
921         if (extractedProperty.isPresent()) {
922             return getParameterName(extractedProperty.get());
923         }
924         return Optional.empty();
925     }
926
927     private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
928         if (!extractedProperty.isGetParam()) {
929             return Optional.empty();
930         }
931         Object getParamFuncValue = extractedProperty.getPropertyValue();
932         if (getParamFuncValue instanceof String) {
933             return Optional.of((String) getParamFuncValue);
934         } else {
935             return Optional.of((String) ((List) getParamFuncValue).get(0));
936         }
937     }
938
939     public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
940                                                      String heatPropertyName) {
941         return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
942     }
943
944     /**
945      * Gets tosca property name.
946      *
947      * @param translateTo      the translate to
948      * @param heatPropertyName the heat property name
949      * @return the tosca property name
950      */
951     public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
952         return translateTo.getContext()
953                           .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
954     }
955
956     /**
957      * Gets tosca attribute name.
958      *
959      * @param context          the context
960      * @param heatResourceType the heat resource type
961      * @param heatAttrName     the heat attr name
962      * @return the tosca attribute name
963      */
964     public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
965                                                       String heatAttrName) {
966         return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
967     }
968
969     /**
970      * Gets tosca attribute name.
971      *
972      * @param translateTo  the translate to
973      * @param heatAttrName the heat attr name
974      * @return the tosca attribute name
975      */
976     public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
977         return translateTo.getContext()
978                           .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
979     }
980
981     /**
982      * Create init substitution service template service template.
983      *
984      * @param templateName the template name
985      * @return the service template
986      */
987     public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
988         ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
989         Map<String, String> templateMetadata = new HashMap<>();
990         templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
991         nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
992         nestedSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
993         nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
994         List<Map<String, Import>> globalTypesImportList = GlobalTypesGenerator.getGlobalTypesImportList();
995         globalTypesImportList
996                 .addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
997         nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
998         return nestedSubstitutionServiceTemplate;
999     }
1000
1001     /**
1002      * Create init global substitution service template service template.
1003      *
1004      * @return the service template
1005      */
1006     private static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
1007         ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
1008         Map<String, String> templateMetadata = new HashMap<>();
1009         templateMetadata
1010                 .put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1011         globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
1012         globalSubstitutionServiceTemplate.setImports(GlobalTypesGenerator.getGlobalTypesImportList());
1013         globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
1014         return globalSubstitutionServiceTemplate;
1015     }
1016
1017     /**
1018      * Create substitution node type node type.
1019      *
1020      * @param substitutionServiceTemplate the substitution service template
1021      * @return the node type
1022      */
1023     public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
1024         NodeType substitutionNodeType = new NodeType();
1025         substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
1026         substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
1027         substitutionNodeType.setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
1028         substitutionNodeType.setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
1029         return substitutionNodeType;
1030     }
1031
1032     private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(ServiceTemplate substitutionServiceTemplate) {
1033         Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
1034         Map<String, ParameterDefinition> properties = substitutionServiceTemplate.getTopology_template().getInputs();
1035         if (properties == null) {
1036             return null;
1037         }
1038
1039         PropertyDefinition propertyDefinition;
1040         String toscaPropertyName;
1041         for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
1042             toscaPropertyName = entry.getKey();
1043             propertyDefinition = new PropertyDefinition();
1044             ParameterDefinition parameterDefinition =
1045                     substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
1046             propertyDefinition.setType(parameterDefinition.getType());
1047             propertyDefinition.setDescription(parameterDefinition.getDescription());
1048             propertyDefinition.setRequired(parameterDefinition.getRequired());
1049             propertyDefinition.set_default(parameterDefinition.get_default());
1050             propertyDefinition.setConstraints(parameterDefinition.getConstraints());
1051             propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1052             propertyDefinition.setStatus(parameterDefinition.getStatus());
1053             substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
1054         }
1055         return substitutionNodeTypeProperties;
1056     }
1057
1058     private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(ServiceTemplate substitutionServiceTemplate) {
1059         Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
1060         Map<String, ParameterDefinition> attributes = substitutionServiceTemplate.getTopology_template().getOutputs();
1061         if (attributes == null) {
1062             return null;
1063         }
1064         AttributeDefinition attributeDefinition;
1065         String toscaAttributeName;
1066
1067         for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
1068             attributeDefinition = new AttributeDefinition();
1069             toscaAttributeName = entry.getKey();
1070             ParameterDefinition parameterDefinition =
1071                     substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
1072             if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
1073                 attributeDefinition.setType(parameterDefinition.getType());
1074             } else {
1075                 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
1076             }
1077             attributeDefinition.setDescription(parameterDefinition.getDescription());
1078             attributeDefinition.set_default(parameterDefinition.get_default());
1079             attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1080             attributeDefinition.setStatus(parameterDefinition.getStatus());
1081             substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
1082         }
1083         return substitutionNodeTypeAttributes;
1084     }
1085
1086     /**
1087      * .
1088      * Create and add substitution mapping to the nested substitution service template, and update
1089      * the subtitution node type accordingly with the exposed requerments and capabilities
1090      *
1091      * @param context                           the translation context
1092      * @param substitutionNodeTypeKey           the substitution node type key
1093      * @param nestedSubstitutionServiceTemplate the nested substitution service template
1094      * @param substitutionNodeType              the substitution node type
1095      */
1096     public static void handleSubstitutionMapping(TranslationContext context, String substitutionNodeTypeKey,
1097                                                         ServiceTemplate nestedSubstitutionServiceTemplate,
1098                                                         NodeType substitutionNodeType) {
1099         Map<String, Map<String, List<String>>> substitutionMapping =
1100                 getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType, nestedSubstitutionServiceTemplate,
1101                         context);
1102         //add substitution mapping after capability and requirement expose calculation
1103         nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(DataModelUtil
1104                                                                                                   .createSubstitutionTemplateSubMapping(
1105                                                                                                           substitutionNodeTypeKey,
1106                                                                                                           substitutionNodeType,
1107                                                                                                           substitutionMapping));
1108     }
1109
1110     /**
1111      * Gets node type with flat hierarchy.
1112      *
1113      * @param nodeTypeId      the node type id
1114      * @param serviceTemplate the service template
1115      * @param context         the context
1116      * @return the node type with flat hierarchy
1117      */
1118     public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId, ServiceTemplate serviceTemplate,
1119                                                                TranslationContext context) {
1120         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1121         ToscaServiceModel toscaServiceModel =
1122                 HeatToToscaUtil.getToscaServiceModel(context, serviceTemplate.getMetadata());
1123         return (NodeType) toscaAnalyzerService.getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate,
1124                 toscaServiceModel).getFlatEntity();
1125     }
1126
1127
1128     /**
1129      * Create abstract substitution node template.
1130      *
1131      * @param translateTo             the translate to
1132      * @param templateName            the template name
1133      * @param substitutionNodeTypeKey the substitution node type key
1134      * @return the abstract substitute node template
1135      */
1136     public static NodeTemplate createAbstractSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
1137                                                                              String substitutionNodeTypeKey) {
1138         NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1139         List<String> directiveList = new ArrayList<>();
1140         directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1141         substitutionNodeTemplate.setDirectives(directiveList);
1142         substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1143         substitutionNodeTemplate.setProperties(
1144                 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate, templateName));
1145         return substitutionNodeTemplate;
1146     }
1147
1148
1149     /**
1150      * Checks if the source and target resource is a valid candidate for adding tosca dependency
1151      * relationship.
1152      *
1153      * @param sourceResource   the source resource
1154      * @param targetResource   the target resource
1155      * @param dependencyEntity the dependency entity
1156      * @return true if the candidate resources are a valid combination for the dependency relationship
1157      * and false otherwise
1158      */
1159     public static boolean isValidDependsOnCandidate(Resource sourceResource, Resource targetResource,
1160                                                            ConsolidationEntityType dependencyEntity,
1161                                                            TranslationContext context) {
1162         dependencyEntity.setEntityType(sourceResource, targetResource, context);
1163         ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
1164         ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
1165
1166         return ConsolidationTypesConnectivity.isDependsOnRelationshipValid(sourceEntityType, targetEntityType);
1167     }
1168
1169     private static Map<String, Object> managerSubstitutionNodeTemplateProperties(TranslateTo translateTo,
1170                                                                                         Template template,
1171                                                                                         String templateName) {
1172         Map<String, Object> substitutionProperties = new HashMap<>();
1173         Map<String, Object> heatProperties = translateTo.getResource().getProperties();
1174         if (Objects.nonNull(heatProperties)) {
1175             for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
1176                 Object property = TranslatorHeatToToscaPropertyConverter
1177                                           .getToscaPropertyValue(translateTo.getServiceTemplate(),
1178                                                   translateTo.getTranslatedId(), entry.getKey(), entry.getValue(), null,
1179                                                   translateTo.getHeatFileName(),
1180                                                   translateTo.getHeatOrchestrationTemplate(), template,
1181                                                   translateTo.getContext());
1182                 substitutionProperties.put(entry.getKey(), property);
1183             }
1184         }
1185         return addAbstractSubstitutionProperty(templateName, substitutionProperties);
1186     }
1187
1188     private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
1189                                                                               Map<String, Object> substitutionProperties) {
1190         Map<String, Object> innerProps = new HashMap<>();
1191         innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
1192                 ToscaUtil.getServiceTemplateFileName(templateName));
1193         substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
1194         return substitutionProperties;
1195     }
1196
1197     private static Map<String, Map<String, List<String>>> getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
1198                                                                                                                 ServiceTemplate substitutionServiceTemplate,
1199                                                                                                                 TranslationContext context) {
1200         Map<String, NodeTemplate> nodeTemplates =
1201                 substitutionServiceTemplate.getTopology_template().getNode_templates();
1202         String nodeTemplateId;
1203         NodeTemplate nodeTemplate;
1204         String nodeType;
1205         Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
1206         if (nodeTemplates == null) {
1207             return substitutionMapping;
1208         }
1209
1210         Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
1211         Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
1212         substitutionMapping.put("capability", capabilitySubstitutionMapping);
1213         substitutionMapping.put("requirement", requirementSubstitutionMapping);
1214         List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
1215         Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
1216         List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
1217         Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition = new HashMap<>();
1218         Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
1219         Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
1220         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1221
1222         for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
1223             nodeTemplateId = entry.getKey();
1224             nodeTemplate = entry.getValue();
1225             nodeType = nodeTemplate.getType();
1226
1227             // get requirements
1228             nodeTypeRequirementsDefinition = getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
1229                     requirementSubstitutionMapping, context);
1230             nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
1231             fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
1232             //set substitution node type requirements
1233             exposedRequirementsDefinition = toscaAnalyzerService
1234                                                     .calculateExposedRequirements(nodeTypeRequirementsDefinition,
1235                                                             nodeTemplateRequirementsAssignment);
1236             DataModelUtil.addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
1237                     nodeTemplateId);
1238
1239             //get capabilities
1240             addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping, nodeType,
1241                     nodeTemplateId, substitutionServiceTemplate, context);
1242         }
1243
1244         exposedCapabilitiesDefinition = toscaAnalyzerService
1245                                                 .calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
1246                                                         fullFilledRequirementsDefinition);
1247         DataModelUtil.setNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
1248         return substitutionMapping;
1249     }
1250
1251     private static void addNodeTypeCapabilitiesToSubMapping(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1252                                                                    Map<String, List<String>> capabilitySubstitutionMapping,
1253                                                                    String type, String templateName,
1254                                                                    ServiceTemplate serviceTemplate,
1255                                                                    TranslationContext context) {
1256         NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1257
1258         if (flatNodeType.getCapabilities() != null) {
1259             flatNodeType.getCapabilities().entrySet().stream().forEach(
1260                     capabilityNodeEntry -> addCapabilityToSubMapping(templateName, capabilityNodeEntry,
1261                             nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping));
1262         }
1263     }
1264
1265     private static void addCapabilityToSubMapping(String templateName,
1266                                                          Map.Entry<String, CapabilityDefinition> capabilityNodeEntry,
1267                                                          Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1268                                                          Map<String, List<String>> capabilitySubstitutionMapping) {
1269         String capabilityKey;
1270         List<String> capabilityMapping;
1271         capabilityKey = capabilityNodeEntry.getKey() + UNDERSCORE + templateName;
1272         nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
1273         capabilityMapping = new ArrayList<>();
1274         capabilityMapping.add(templateName);
1275         capabilityMapping.add(capabilityNodeEntry.getKey());
1276         capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
1277     }
1278
1279     private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(String type, String templateName,
1280                                                                                    ServiceTemplate serviceTemplate,
1281                                                                                    Map<String, List<String>> requirementSubstitutionMapping,
1282                                                                                    TranslationContext context) {
1283         List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
1284         NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1285         List<String> requirementMapping;
1286
1287         if (flatNodeType.getRequirements() == null) {
1288             return requirementList;
1289         }
1290
1291         for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
1292             for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap.entrySet()) {
1293                 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
1294                 RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil.yamlToObject(
1295                         toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
1296                         RequirementDefinition.class);
1297                 if (Objects.isNull(requirementNodeEntryValue.getOccurrences())) {
1298                     requirementNodeEntryValue.setOccurrences(new Object[] {1, 1});
1299                 }
1300                 Map<String, RequirementDefinition> requirementDef = new HashMap<>();
1301                 requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
1302                 DataModelUtil.addRequirementToList(requirementList, requirementDef);
1303                 requirementMapping = new ArrayList<>();
1304                 requirementMapping.add(templateName);
1305                 requirementMapping.add(requirementNodeEntry.getKey());
1306                 requirementSubstitutionMapping
1307                         .put(requirementNodeEntry.getKey() + UNDERSCORE + templateName, requirementMapping);
1308                 if (Objects.isNull(requirementNodeEntryValue.getNode())) {
1309                     requirementNodeEntryValue.setOccurrences(new Object[] {1, 1});
1310                 }
1311             }
1312         }
1313         return requirementList;
1314     }
1315
1316     /**
1317      * Fetch global substitution service template service template.
1318      *
1319      * @param serviceTemplate the service template
1320      * @param context         the context
1321      * @return the service template
1322      */
1323     public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(ServiceTemplate serviceTemplate,
1324                                                                                 TranslationContext context) {
1325         ServiceTemplate globalSubstitutionServiceTemplate =
1326                 context.getTranslatedServiceTemplates().get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1327         if (globalSubstitutionServiceTemplate == null) {
1328             globalSubstitutionServiceTemplate = HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
1329             context.getTranslatedServiceTemplates()
1330                    .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, globalSubstitutionServiceTemplate);
1331         }
1332         boolean isImportAddedToServiceTemplate = DataModelUtil
1333                                                          .isImportAddedToServiceTemplate(serviceTemplate.getImports(),
1334                                                                  Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1335         if (!isImportAddedToServiceTemplate) {
1336             serviceTemplate.getImports()
1337                            .addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1338         }
1339         return globalSubstitutionServiceTemplate;
1340     }
1341
1342     public static List<Map<String, Import>> createImportList(String templateName) {
1343         List<Map<String, Import>> imports = new ArrayList<>();
1344         Map<String, Import> importsMap = new HashMap<>();
1345         importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
1346         imports.add(importsMap);
1347         return imports;
1348     }
1349
1350     /**
1351      * Create service template import import.
1352      *
1353      * @param serviceTemplate the service template
1354      * @return the import
1355      */
1356     public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
1357         Import serviceTemplateImport = new Import();
1358         serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
1359         return serviceTemplateImport;
1360     }
1361
1362     /**
1363      * Create service template import import.
1364      *
1365      * @param metadataTemplateName the service template name
1366      * @return the import
1367      */
1368     private static Import createServiceTemplateImport(String metadataTemplateName) {
1369         Import serviceTemplateImport = new Import();
1370         serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
1371         return serviceTemplateImport;
1372     }
1373
1374     public static ToscaServiceModel createToscaServiceModel(ServiceTemplate entryDefinitionServiceTemplate,
1375                                                                    TranslationContext translationContext) {
1376         return new ToscaServiceModel(getCsarArtifactFiles(translationContext), getServiceTemplates(translationContext),
1377                                             ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
1378     }
1379
1380     private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
1381         FileContentHandler artifactFiles = new FileContentHandler();
1382         artifactFiles.addAll(translationContext.getFiles());
1383         artifactFiles.addAll(translationContext.getExternalArtifacts());
1384
1385         HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
1386         heatTreeManager.createTree();
1387         ValidationStructureList validationStructureList = new ValidationStructureList(heatTreeManager.getTree());
1388         byte[] validationStructureFile =
1389                 FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
1390         artifactFiles.addFile("HEAT.meta", validationStructureFile);
1391         return artifactFiles;
1392     }
1393
1394
1395     private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext translationContext) {
1396         List<ServiceTemplate> serviceTemplates = new ArrayList<>();
1397         serviceTemplates.addAll(GlobalTypesGenerator.getGlobalTypesServiceTemplate(OnboardingTypesEnum.ZIP).values());
1398         serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
1399         Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
1400
1401         for (ServiceTemplate template : serviceTemplates) {
1402             serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
1403         }
1404         return serviceTemplatesMap;
1405     }
1406
1407     public static String getNestedResourceTypePrefix(TranslateTo translateTo) {
1408         if (isSubInterfaceResource(translateTo.getResource(), translateTo.getContext()) && isSubInterfaceBoundToPort(
1409                 translateTo)) {
1410             return ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX;
1411         }
1412         return ToscaNodeType.NESTED_HEAT_RESOURCE_TYPE_PREFIX;
1413     }
1414
1415     private static boolean isSubInterfaceBoundToPort(TranslateTo translateTo) {
1416         return HeatToToscaUtil.getSubInterfaceParentPortNodeTemplateId(translateTo).isPresent();
1417     }
1418
1419     //Method evaluate the  network role from sub interface node template id, designed considering
1420     // only single sub interface present in nested file else it will return null
1421     public static Optional<String> getNetworkRoleFromSubInterfaceId(Resource resource,
1422                                                                            TranslationContext translationContext) {
1423         Optional<String> networkRole = Optional.empty();
1424         Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
1425
1426         if (!nestedHeatFileName.isPresent()) {
1427             return networkRole;
1428         }
1429
1430         HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
1431                 translationContext.getFileContentAsStream(nestedHeatFileName.get()), HeatOrchestrationTemplate.class);
1432
1433         if (MapUtils.isNotEmpty(nestedHeatOrchestrationTemplate.getResources())) {
1434             ContrailV2VirtualMachineInterfaceHelper contrailV2VirtualMachineInterfaceHelper =
1435                     new ContrailV2VirtualMachineInterfaceHelper();
1436             Optional<Map.Entry<String, Resource>> vlanSubInterfaceResource =
1437                     nestedHeatOrchestrationTemplate.getResources().entrySet().stream()
1438                                                    .filter(resourceEntry -> contrailV2VirtualMachineInterfaceHelper
1439                                                                                     .isVlanSubInterfaceResource(
1440                                                                                             resourceEntry.getValue()))
1441                                                    .findFirst();
1442             if (vlanSubInterfaceResource.isPresent()) {
1443                 Map.Entry<String, Resource> vlanSubInterfaceResourceEntry = vlanSubInterfaceResource.get();
1444                 networkRole = extractNetworkRoleFromSubInterfaceId(vlanSubInterfaceResourceEntry.getKey(),
1445                         vlanSubInterfaceResourceEntry.getValue().getType());
1446             }
1447         }
1448         return networkRole;
1449     }
1450
1451 }